小编典典

SQL Server:是否可以同时插入两个表?

sql

我的数据库包含三个表叫Object_TableData_TableLink_Table。链接表仅包含两列,即对象记录的标识和数据记录的标识。

我想从DATA_TABLE链接到一个给定对象标识的位置复制数据,Data_TableLink_Table在不同的给定对象标识中插入相应的记录。

可以 通过选择一个表变量,并为每次迭代进行两次插入来循环执行此操作。

这是最好的方法吗?

编辑 :我想避免循环的原因有两个,第一个是我很懒,并且循环/临时表需要更多的代码,更多的代码意味着有更多的地方出错,第二个原因是对性能的关注。

我可以在一个插入中复制所有数据,但是如何获得链接表以链接到新数据记录,其中每个记录都有一个新的ID?


阅读 270

收藏
2021-05-05

共2个答案

小编典典

下面使用表变量设置我遇到的情况。

DECLARE @Object_Table TABLE
(
    Id INT NOT NULL PRIMARY KEY
)

DECLARE @Link_Table TABLE
(
    ObjectId INT NOT NULL,
    DataId INT NOT NULL
)

DECLARE @Data_Table TABLE
(
    Id INT NOT NULL Identity(1,1),
    Data VARCHAR(50) NOT NULL
)

-- create two objects '1' and '2'
INSERT INTO @Object_Table (Id) VALUES (1)
INSERT INTO @Object_Table (Id) VALUES (2)

-- create some data
INSERT INTO @Data_Table (Data) VALUES ('Data One')
INSERT INTO @Data_Table (Data) VALUES ('Data Two')

-- link all data to first object
INSERT INTO @Link_Table (ObjectId, DataId)
SELECT Objects.Id, Data.Id
FROM @Object_Table AS Objects, @Data_Table AS Data
WHERE Objects.Id = 1

感谢另一个指向OUTPUT子句的答案,我可以演示一个解决方案:

-- now I want to copy the data from from object 1 to object 2 without looping
INSERT INTO @Data_Table (Data)
OUTPUT 2, INSERTED.Id INTO @Link_Table (ObjectId, DataId)
SELECT Data.Data
FROM @Data_Table AS Data INNER JOIN @Link_Table AS Link ON Data.Id = Link.DataId
                INNER JOIN @Object_Table AS Objects ON Link.ObjectId = Objects.Id 
WHERE Objects.Id = 1

但是事实证明,由于以下错误,在现实生活中并非如此简单

OUTPUT INTO子句不能位于(主键,外键)关系的任一侧

我仍然可以OUTPUT INTO使用临时表,然后以正常插入结束。因此,我可以避免循环,但无法避免临时表。

2021-05-05
小编典典

In one statement: No.

In one transaction: Yes

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

好消息是,上述代码也保证是原子的,并且可以在单个函数调用中使用一个sql字符串从客户端应用程序将其发送到服务器,就好像它是一条语句一样。您还可以将触发器应用于一个表以获得单个插入的效果。但是,最终仍然是两个语句,您可能不想为每个插入都运行触发器。

2021-05-08