比较 Table_1 和 Table_2 并根据 Table_1 中更改的数据更新 Table_2 的存储过程
Stored procedure that compares Table_1 and Table_2 and updates Table_2 according to data changed in Table_1
假设我有两个表 Table_1 和 Table_2。
两者都有相同的列。
@Table_1
| Id | Col1 | Col2 | Col3 |
| 1 | a | b | c |
| 2 | d | e | f |
和
@Table_2
| Id | Col1 | Col2 | Col3 |
| 1 | a | 0 | 0 |
| 3 | z | z | y |
我如何编写将从 Table_1
中获取行的存储过程,将该行的每一列与 Table_2
中的行进行比较,并相应地更新 Table_2
列。如果 Table_1
中的行在 Table_2
中找不到,则只需插入即可。
现在。我意识到 INSERT
很容易写,它可能看起来像
insert into @Table_2(col1, col2, col3)
select col1, col2, col3 from @Table_1 where id = @id
执行存储过程后 Table_2
的最终结果必须如下所示
@Table_2
| Id | Col1 | Col2 | Col3 |
| 1 | a | b | c |
| 2 | d | e | f |
| 3 | z | z | y |
如何将 Table_1
的每一行和每一列与 Table_2
中的数据进行比较?
@Martyn Meeks 的回答是两个独立的陈述!
根据用户@SQL_M提供的https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/,使用MERGE
语句并不完美,但有效
@Jayasurya Satheesh 的脚本也可以,但使用 MERGE
语句
使用单个语句插入和更新可以使用 SQL Merge Join
实现
像下面这个例子:
MERGE Table1 T1
USING Table2 T2
ON T1.Id = T2.Id
WHEN MATCHED
UPDATE SET
T1.Col1 = T2.Col1,
T1.Col2 = T2.Col2,
T1.Col3 = T2.Col3
WHEN NOT MATCHED BY TARGET
INSERT(COL1,COL2,COL3)
VALUES(T2.COL1,T2.COL2,T2.COL3)
在这里,如果根据 Id 找到匹配项,我将更新 Table1 上的记录,如果没有匹配项,则插入记录
创建 MERGE 语句。
CREATE PROCEDURE [dbo].[IMPORT_Data]
AS
SET NOCOUNT ON;
MERGE Table1 AS TRGT
USING Table2 AS SRCE
ON SRCE.Id = TRGT.Id
WHEN MATCHED THEN UPDATE
SET TRGT.Col1 = SRCE.Col1,
TRGT.Col2 = SRCE.Col2,
TRGT.Col3 = SRCE.Col3,
TRGT.Col4 = SRCE.Col4
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
Col1,
Col2,
Col3,
Col4
)
VALUES
(
SRCE.Col1,
SRCE.Col2,
SRCE.Col3,
SRCE.Col4
)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
如果您担心上述 MERGE 语句的潜在问题,您可以在两个单独的语句中进行
UPDATE T2
SET T2.Col1 = T1.Col1,
T2.Col2 = T1.Col2,
T2.Col3 = T1.Col3
FROM @Table_2 T2
INNER JOIN @Table_1 T1
ON T2.Id = T1.Id
INSERT INTO @Table_2 (Id,Col1,Col2,Col3)
SELECT T1.Id,T1.Col1,T1.Col2,T1.Col3
FROM @Table_1 T1
WHERE NOT EXISTS (SELECT 1 FROM @Table_2 T2 WHERE T2.Id = T1.Id)
编辑:按照 Jayasurya 的建议切换了更新和插入语句。
否则,新插入的行会在插入的同时进行更新,这是不必要的
假设我有两个表 Table_1 和 Table_2。
两者都有相同的列。
@Table_1
| Id | Col1 | Col2 | Col3 |
| 1 | a | b | c |
| 2 | d | e | f |
和
@Table_2
| Id | Col1 | Col2 | Col3 |
| 1 | a | 0 | 0 |
| 3 | z | z | y |
我如何编写将从 Table_1
中获取行的存储过程,将该行的每一列与 Table_2
中的行进行比较,并相应地更新 Table_2
列。如果 Table_1
中的行在 Table_2
中找不到,则只需插入即可。
现在。我意识到 INSERT
很容易写,它可能看起来像
insert into @Table_2(col1, col2, col3)
select col1, col2, col3 from @Table_1 where id = @id
执行存储过程后 Table_2
的最终结果必须如下所示
@Table_2
| Id | Col1 | Col2 | Col3 |
| 1 | a | b | c |
| 2 | d | e | f |
| 3 | z | z | y |
如何将 Table_1
的每一行和每一列与 Table_2
中的数据进行比较?
@Martyn Meeks 的回答是两个独立的陈述!
根据用户@SQL_M提供的https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/,使用MERGE
语句并不完美,但有效
@Jayasurya Satheesh 的脚本也可以,但使用 MERGE
语句
使用单个语句插入和更新可以使用 SQL Merge Join
像下面这个例子:
MERGE Table1 T1
USING Table2 T2
ON T1.Id = T2.Id
WHEN MATCHED
UPDATE SET
T1.Col1 = T2.Col1,
T1.Col2 = T2.Col2,
T1.Col3 = T2.Col3
WHEN NOT MATCHED BY TARGET
INSERT(COL1,COL2,COL3)
VALUES(T2.COL1,T2.COL2,T2.COL3)
在这里,如果根据 Id 找到匹配项,我将更新 Table1 上的记录,如果没有匹配项,则插入记录
创建 MERGE 语句。
CREATE PROCEDURE [dbo].[IMPORT_Data]
AS
SET NOCOUNT ON;
MERGE Table1 AS TRGT
USING Table2 AS SRCE
ON SRCE.Id = TRGT.Id
WHEN MATCHED THEN UPDATE
SET TRGT.Col1 = SRCE.Col1,
TRGT.Col2 = SRCE.Col2,
TRGT.Col3 = SRCE.Col3,
TRGT.Col4 = SRCE.Col4
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
Col1,
Col2,
Col3,
Col4
)
VALUES
(
SRCE.Col1,
SRCE.Col2,
SRCE.Col3,
SRCE.Col4
)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
如果您担心上述 MERGE 语句的潜在问题,您可以在两个单独的语句中进行
UPDATE T2
SET T2.Col1 = T1.Col1,
T2.Col2 = T1.Col2,
T2.Col3 = T1.Col3
FROM @Table_2 T2
INNER JOIN @Table_1 T1
ON T2.Id = T1.Id
INSERT INTO @Table_2 (Id,Col1,Col2,Col3)
SELECT T1.Id,T1.Col1,T1.Col2,T1.Col3
FROM @Table_1 T1
WHERE NOT EXISTS (SELECT 1 FROM @Table_2 T2 WHERE T2.Id = T1.Id)
编辑:按照 Jayasurya 的建议切换了更新和插入语句。 否则,新插入的行会在插入的同时进行更新,这是不必要的