2010-07-09 6 views
1

У меня есть две таблицы A и B с динамическими столбцами, где я понятия не имею, какие столбцы являются ключевыми внутри них, за исключением другой таблицы C.В SQL Server, как я могу сравнивать строки с именами столбцов из другой таблицы

В таблице 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, и от этого я знаю А имеет те же самые основные столбцы.

Но я хочу знать, есть ли лучший способ решить эту проблему.

ответ

1

Являются ли ключевые столбцы в «C» первичным ключом? Если это так, вы можете получить их от INFORMATION_SCHEMA.TABLE_CONSTRAINTS и INFORMATION_SCHEMA.KEY_COLUMN_USAGE, как описано here, а не использовать другую таблицу.

Для этого я должен использовать динамический 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 
+0

Спасибо. Кажется, это лучший способ сделать это. –