我有两个表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具有相同的键列。
但我想知道是否有更好的方法来解决这个问题。
答案 0 :(得分:1)
“C”中的键列是主键吗?如果是这样,您可以按照here所述的INFORMATION_SCHEMA.TABLE_CONSTRAINTS
和INFORMATION_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