SQL Update两个相同的表

时间:2014-04-23 21:55:09

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

我有两个相同的表需要每天更新。两个表都具有完全相同的结构。他们有100多列。那么,在SQL中是否有一种方法可以基于TableB更新TableA中的所有列,而无需为每个列编写(Set columnname ='')更新语句?两个表都有相同的列名,所以我认为可能有更聪明的方法来实现它。

4 个答案:

答案 0 :(得分:3)

有点hacky但是可以做到 我创建了两个相同的表,每两个记录。 (表1和表2)


TABLE_1

Table_1

<强> TABLE_2

Table_2

SQL:

DECLARE @LeftTable VARCHAR(MAX) = 'Table_1';
DECLARE @RightTable VARCHAR(MAX) = 'Table_2';
DECLARE @UpdateStatement VARCHAR(MAX);
SELECT @UpdateStatement = COALESCE(@UpdateStatement + ', ', '') + 
                          't2.' + COLUMN_NAME + ' = t1.' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = @LeftTable AND COLUMN_NAME <> 'ID'

SET @UpdateStatement = 'UPDATE t2 SET ' + @UpdateStatement + ' ' +
                       'FROM ' + @RightTable + ' t2 JOIN ' + @LeftTable + ' ' +
                       't1 ON t2.ID = t1.ID';
EXEC(@UpdateStatement)
-- The actual executed query is:
-- UPDATE t2 SET t2.Description = t1.Description,
--               t2.Extra = t1.Extra
-- FROM Table_2 t2 JOIN Table_1 t1 ON t2.ID = t1.ID


结果: TABLE_1

Table_1

<强> TABLE_2

Table_2

修改

有点复杂,但这不包括主键列:

DECLARE @LeftTable VARCHAR(MAX) = 'Table_1';
DECLARE @RightTable VARCHAR(MAX) = 'Table_2';
DECLARE @UpdateStatement VARCHAR(MAX);
WITH ColumnNames AS
(
    SELECT c.name AS COLUMN_NAME from
    sys.tables t
    JOIN sys.columns c on t.object_id = c.object_id
    LEFT JOIN
    (
        SELECT ic.object_id
              ,ic.column_id
              ,idx.name AS index_name
        FROM sys.indexes idx
        JOIN sys.index_columns ic on idx.index_id = ic.index_id
        AND idx.object_id = ic.object_id AND idx.is_primary_key = 1
    ) idx ON t.object_id = idx.object_id AND c.column_id = idx.column_id
    WHERE t.name = @LeftTable
    AND idx.index_name IS NULL
)
SELECT @UpdateStatement = COALESCE(@UpdateStatement + ', ', '') + 
                          't2.' + COLUMN_NAME + ' = t1.' + COLUMN_NAME + CHAR(10)
FROM ColumnNames
SET @UpdateStatement = 'UPDATE t2 SET ' + @UpdateStatement + CHAR(10) +
                       'FROM ' + @RightTable + ' t2 JOIN ' + @LeftTable + CHAR(10) +
                       't1 ON t2.ID = t1.ID';
EXEC(@UpdateStatement)

答案 1 :(得分:1)

可用的方法是UPDATE语句和MERGE语句。它们都需要在SET子句中更新specyfing列名。

如果需要,可以编写一个动态SQL来读取表的模式并生成包含所有列名的查询。这样您就不必手动编写所有列名。

答案 2 :(得分:1)

写一次更新查询...

然后从该查询中创建一个存储过程。然后,只需在需要根据表b更新表a时执行存储过程。

答案 3 :(得分:0)

谢谢大家的意见。这是我决定做的最不专业的方式。 1找到第二个表上列出的键,然后删除目标表上的那些行,并将它们从第二个表重新插入到目标表中。这样我就不必担心每列的更新语句。这是非常不专业,但它做的工作!