我最初提出这个问题的方式对大多数人来说都没有帮助,所以我对其进行了重大修改。
我有一个遗留数据库,我无法控制(也从来没有)其架构。db 模式的设计与提供程序无关,供非托管 C++ 使用,因此没有 FK 约束等。我出现并需要从 .NET 使用它,并且还需要呈现与最初预期不同的数据.
这是相关表的架构(我已经用粗体/星号标记了这个问题的键的数量):
CREATE TABLE [dbo].[Formats](
[GroupName] [varchar](255) NOT NULL,
**[BatchID] [bigint] NOT NULL,**
[SeriesNumber] [bigint] NOT NULL,
**[SequenceID] [bigint] NOT NULL,**
[SeqNum] [int] NOT NULL,
[FormatName] [varchar](50) NOT NULL
CREATE TABLE [dbo].[Fields](
[GroupName] [varchar](255) NOT NULL,
**[BatchID] [bigint] NOT NULL,**
**[SequenceID] [bigint] NOT NULL,**
[SeqNum] [int] NOT NULL,
**[FieldName] [varchar](50) NOT NULL,**
[FieldDisplayName] [varchar](50) NOT NULL,
[FieldValue] [ntext] NULL
Formats:Fields 之间存在 1:Many 的关系。
我需要查询格式行列表。挑战有几个: + 有一个复合外键。+ 我需要将格式过滤为包含相关字段的子集。+ 相关字段必须与任意数量的过滤条件匹配,然后才能内联到格式。
所以要通过这个:存储过程接收下表值参数:
_FieldDisplayName_ Field_Value
Field 1 001
Field 2 002
然后它需要按这些值过滤字段表。
由于我需要使用所有标准,而不仅仅是其中一个,当我不知道我有多少值或 FieldDisplayName 是什么时,我不知道如何使用它来检索有用的加入值将是。
@Joe Phillips 足够聪明,可以看穿混乱并建议我需要旋转桌子。就是这样:
编辑: 以下正在对数据进行透视,但我不确定它是否理想。在提供答案之前仍在等待其他想法。
我没有使用 TVP,而是使用临时表和动态 SQL(是的,我看到了注入漏洞):
IF OBJECT_ID('[tempdb].[dbo].[#FilterFields]') is not null
Drop Table dbo.#FilterFields
CREATE Table #FilterFields (FieldDisplayName varchar(50), FieldValue nvarchar(max))
/* Just some example data */
INSERT INTO #FilterFields (FieldDisplayName, FieldValue) VALUES ('PTNUM', '011')
INSERT INTO #FilterFields (FieldDisplayName, FieldValue) VALUES('SITENUM', '001')
Declare @column_names varchar(max)
Declare @dynamic_pivot_query as varchar(max)
SELECT @column_names = Stuff((SELECT DISTINCT ',[' + FieldDisplayName + ']'
FROM #FilterFields FOR xml path('')),1,1,'')
PRINT(@column_names)
SET @dynamic_pivot_query =
'select * ' +
'from tempdb.dbo.#FilterFields ' +
'Pivot
(
MIN(
FieldValue
)
FOR FieldDisplayName IN (' + @column_names + ')
) as P'
PRINT(@dynamic_pivot_query)
EXEC(@dynamic_pivot_query)