首页 > 解决方案 > 没有游标的 T-SQL 插入和更新外键

问题描述

我在 MS SQL 中有两个表:

CREATE TABLE Table1 (ID INT IDENTITY(1,1) NOT NULL, TEXTVal VARCHAR(100), Table2Id int)

insert into Table1 (TEXTVal) values('aaa'); 
insert into Table1 (TEXTVal) values('bbb'); insert into Table1 (TEXTVal) values('ccc');


CREATE TABLE Table2 (ID INT IDENTITY(1,1) NOT NULL, TEXTVal VARCHAR(100), Table2Id int)

Id 是标识列。我想将 TEXTVal 值从 Table1 复制到 Table2:

INSERT INTO Table2 (TEXTVal)
SELECT TEXTVal FROM Table1
where TEXTVal <> 'ccc'

并在 Table1 中的 Table2Id 列更新为 Table2 中的适当 Id 值。我可以用光标和 SCOPE_IDENTITY() 来做到这一点。

我只是想知道,有没有办法在 T-SQL 中不使用光标?

标签: sql-serverscope-identitydatabase-cursor

解决方案


正如 Jeroen 在评论中所说,您需要使用OUTPUT. 在以下示例中,如果您没有 AdventureWorks 数据库,则只需使用测试数据库。您应该能够复制/粘贴它并运行它以查看它的实际效果!

USE AdventureWorks;
GO
----Creating the table which will store permanent table
CREATE TABLE TestTable (ID INT, TEXTVal VARCHAR(100))
----Creating temp table to store ovalues of OUTPUT clause
DECLARE @TmpTable TABLE (ID_New INT, TEXTVal_New VARCHAR(100),ID_Old INT, TEXTVal_Old VARCHAR(100))
----Insert values in real table
INSERT TestTable (ID, TEXTVal)
VALUES (1,'FirstVal')
INSERT TestTable (ID, TEXTVal)
VALUES (2,'SecondVal')
----Update the table and insert values in temp table using Output clause
UPDATE TestTable
SET TEXTVal = 'NewValue'
OUTPUT Inserted.ID, Inserted.TEXTVal, Deleted.ID, Deleted.TEXTVal INTO @TmpTable
WHERE ID IN (1,2)
----Check the values in the temp table and real table
----The values in both the tables will be same
SELECT * FROM @TmpTable
SELECT * FROM TestTable
----Clean up time
DROP TABLE TestTable
GO

结果集:

TmpTable:
ID_New TextVal_New ID_Old TextVal_Old
——————— ——————— ——————— ———————
1 NewValue 1 FirstVal
2 NewValue 2 SecondVal

Original Table:
ID TextVal
——————— ———————
1 NewValue
2 NewValue

如您所见,可以捕获新值以及您正在更新的值。在这个例子中,我只是将它们填充到一个表变量中,但你可以对它们做任何你想做的事情。:)


推荐阅读