使用本地变量值作为查询条件SQL Server

时间:2014-11-20 19:49:15

标签: sql sql-server

背景:我想通过循环遍历所有可能的列来比较所有表中的每个列的两个Person记录。然后我想运行一个公共表表达式,它在循环时使用每一列,如果第二个Person列为NULL,我希望它根据特定条件为所有重复记录更新第一个Person列的值。 / p>

这将基本上遍历所有重复项并在删除之前更新它们以匹配。

我正在运行一个循环遍历表列的存储过程。我想在查询中使用这些列。这就是我所拥有的:

declare table_columns cursor local dynamic for
     select BaseTable,
            DBColumn
     from viewTableInfo


declare @BaseTable nvarchar (100)
declare @DBColumn nvarchar (100)
open table_columns

while (1 = 1)
      begin
           fetch next from table_columns into @BaseTable, @DBColumn
                 if (@@FETCH_STATUS <> 0 ) break

                 ;with CTE as
                 (
                  select firstName,
                         lastName,
                         @DBColumn AS Column,
                         rn = ROW_NUMBER()OVER(PARTITION BY firstName, lastName ORDER BY pID)
                  from Person p
                  inner join Company c ON c.pID = p.pID -- joined because variable may be column from Company table.
                  where p.pID in (1, 2)
                  )
                  select destinationProperty = case
                                               when c1.Column = c2.Column then c2.Column
                                               when c2.Column IS NULL THEN c1.Column
                                               ELSE c2.Column END
                  from cte c1
                  inner join cte c2 on c1.firstName = c2.firstName and c1.lastName = c2.LastName and c2.rn = c1.rn + 1

当我运行它时,我在结果集中得到零记录,因为公用表表达式选择变量@DBColumn的值,对于每个循环,它是实际的列名。

我需要的是能够在查询中使用实际的列名,并为结果集中的每个pID获取该列的值。

这可能吗?

1 个答案:

答案 0 :(得分:1)

不确定在此处使用游标和动态列名的确切要求,但您可以使用动态SQL获得所需的功能。

更改循环不使用1 = 1,而是检查光标状态。

declare table_columns cursor local dynamic for
     select BaseTable,
            DBColumn
     from viewTableInfo


declare @BaseTable nvarchar (100)
declare @DBColumn nvarchar (100)

declare @query nvarchar(max)

open table_columns
fetch next from table_columns into @BaseTable, @DBColumn

WHILE @@FETCH_STATUS = 0
begin

    set @query =';with CTE as
                 (
                  select firstName,
                         lastName,
                         ' + @DBColumn + ' AS Column,
                         rn = ROW_NUMBER()OVER(PARTITION BY firstName, lastName ORDER BY pID)
                  from Person p
                  inner join Company c ON c.pID = p.pID -- joined because variable may be column from Company table.
                  where p.pID in (1, 2)
                  )
                  select destinationProperty = case
                                               when c1.Column = c2.Column then c2.Column
                                               when c2.Column IS NULL THEN c1.Column
                                               ELSE c2.Column END
                  from cte c1
                  inner join cte c2 on c1.firstName = c2.firstName and c1.lastName = c2.LastName and c2.rn = c1.rn + 1'

    exec sp_executesql @query
fetch next from table_columns into @BaseTable, @DBColumn
end