使用T-SQL中的索引从变量中获取名称

时间:2016-09-27 09:19:14

标签: sql-server tsql sql-server-2008-r2

使用以下两个查询

查询1:

DECLARE @ContentColumnNamesSRC NVARCHAR(4000) = NULL,

SELECT 
    @ContentColumnNamesSRC = COALESCE(@ContentColumnNamesSRC + ', ', '') + '[' + name + ']'
FROM    
    tempdb.sys.columns 
WHERE 
    1 = 1
    AND object_id = OBJECT_ID('tempdb..#tempTable')
    AND column_id < 9 -- First 8 columns are ID data, which is what I am after

查询2:

DECLARE @ContentColumnNamesDST NVARCHAR(4000) = NULL,

SELECT 
    @ContentColumnNamesDST = COALESCE(@ContentColumnNamesDST + ', ', '') + '[' + name + ']'
FROM    
    tempdb.sys.columns 
WHERE 
    1 = 1
    AND object_id = OBJECT_ID('Import.dbo.ContentTable')
    AND column_id < 9 -- First 8 columns are ID data, which is what I am after

我可以将每个表中的前8列变为变量。

我想要做的是找到一种从变量中获取值的方法,这样我就可以匹配列名。

它们在每个表中应该是相同的,我需要它能够创建动态合并语句,以便每个变量的列名称

@ContentColumnNamesSRC 

@ContentColumnNamesDST

排队,所以我可以在合并声明中使用它。

这一点是能够在循环中使用它,而我所要做的就是改变它所查看的表,并且合并语句仍然有效。

理想情况下,id最终会得到以下内容:

SELECT @StageSQLCore = N'USE Staging;

BEGIN TRANSACTION
MERGE '+@StageTableCore+' AS DST
USING '+@ImportTableCore+'  AS SRC
ON (SRC.[Key] = DST.[Key])
WHEN NOT MATCHED THEN
INSERT ('+@StageTableCoreColumns+')
VALUES (
    '+@ImportTableCoreColumns+',GETDATE())
WHEN MATCHED 
THEN UPDATE 
SET 
    DST.'+@ContentColumnNamesDST[i]' = SRC.'+@ContentColumnNamesSRC[i] +'
    ,DST.'+@ContentColumnNamesDST[i]' = SRC.'+@ContentColumnNamesSRC[i] +'
    ,DST.'+@ContentColumnNamesDST[i]' = SRC.'+@ContentColumnNamesSRC[i] +'
    ,DST.'+@ContentColumnNamesDST[i]' = SRC.'+@ContentColumnNamesSRC[i] +'
    ,DST.[ETLDate] = GETDATE()
 ;

 COMMIT'

EXEC (@StageSQLCore)

1 个答案:

答案 0 :(得分:1)

如果序号匹配

,则可以生成这样的合并SQL
DECLARE @MergeSQL NVARCHAR(4000) = NULL

SELECT --*--,
    @MergeSQL = COALESCE(@MergeSQL + ', DST.=', '') + QUOTENAME(bc.column_name) + ' = SRC.' + QUOTENAME(bc.COLUMN_NAME) + char(13)
FROM    
    test.INFORMATION_SCHEMA.COLUMNS tc
    inner join testb.INFORMATION_SCHEMA.COLUMNS bc
    on tc.TABLE_NAME = bc.TABLE_NAME
    and tc.ORDINAL_POSITION = bc.ORDINAL_POSITION
    and tc.TABLE_NAME = 'History'
WHERE 
     tc.ORDINAL_POSITION < 5 -- First 8 columns are ID data, which is what I am after
     and bc.ORDINAL_POSITION < 5

    select @MergeSQL