在SQL Server中,如何使用另一个表中的列名比较行

时间:2010-07-09 10:11:05

标签: sql sql-server dynamic-sql dynamic-columns

我有两个表A和B,带有动态列,我不知道哪些列是其中的键,除了另一个名为C的表。

C表指定哪个列是表A和B中的键列。可以有一个或多个键列。

我的问题是,如何生成这样的查询,我从A中选择所有行,其中键列等于B中的相同键列?

我的一个想法是创建一个我用sp_executesql执行的文本查询,但我需要一些关于如何生成查询的好主意。

首先,我会从表C中选择表A和B中的所有键列到我声明的表@keyColumns。

然后我将使用while循环遍历@keyColumns中的所有键列并生成查询并使用sp_executesql执行它。

例如:

UPDATE A 
SET ... 
FROM B INNER JOIN A 
ON A.keycol1 = B.keycol1 AND A.keycol2 = B.keycol2 AND ...

为了说清楚,C表只指定表B的键列,从中我知道A具有相同的键列。

但我想知道是否有更好的方法来解决这个问题。

1 个答案:

答案 0 :(得分:1)

“C”中的键列是主键吗?如果是这样,您可以按照here所述的INFORMATION_SCHEMA.TABLE_CONSTRAINTSINFORMATION_SCHEMA.KEY_COLUMN_USAGE检索这些内容,而不是使用其他表格。

我认为你必须使用动态SQL。没有像FROM B JOIN A ON PRIMARY KEYS这样的语法。您可以通过WHILE将查询连接起来,而不是SELECT循环,如下所示。

DECLARE @DynSql nvarchar(max)
DECLARE @TableA sysname
DECLARE @TableB sysname

SET @TableA = 'A'
SET @TableB = 'B';

WITH C AS
(
SELECT 'B' AS [Table], 'keycol2' As col UNION ALL
SELECT 'B' AS [Table], 'keycol1' As col UNION ALL
SELECT 'X' AS [Table], 'keycol1' As col
)

SELECT @DynSql = ISNULL(@DynSql + ' AND ','')+ @TableA + '.'+QUOTENAME(col) + '= ' + @TableB + '.'+QUOTENAME(col)
FROM C WHERE [Table] = @TableB

IF @@ROWCOUNT=0
RAISERROR('No Entry found for table %s',16,1,@TableB)

SET @DynSql = 
'UPDATE ' + @TableA + ' 
SET ... 
FROM ' + @TableB + '  INNER JOIN ' + @TableA + ' ON  
' + @DynSql

PRINT @DynSql