l33*_*33t 2 sql sql-server sql-server-2014
运行SQL Server 2014
.如何从表中插入多行并将插入的数据与新ID组合?
让我们看一个精简的例子吧!
DECLARE @Old TABLE
(
[ID] [int] PRIMARY KEY,
[Data] [int] NOT NULL
)
DECLARE @New TABLE
(
[ID] [int] PRIMARY KEY,
[OtherID] [int] NULL
)
INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID], [@Old].[ID] /* <--- not supported :( */ INTO @New
SELECT [Data]
FROM @Old
Run Code Online (Sandbox Code Playgroud)
我需要将插入的ID与正在插入的数据相结合.我可以假设插入的行与所选行的顺序相同吗?([Data]
插入操作后我将无法加入.)
以下似乎是一个可能的解决方案,但我找不到它的工作原理.它保证有效吗?
DECLARE @Old TABLE
(
[RowID] [int] PRIMARY KEY IDENTITY, -- Guaranteed insert order?
[ID] [int] NOT NULL,
[Data] [int] NOT NULL
)
DECLARE @New TABLE
(
[RowID] [int] PRIMARY KEY IDENTITY, -- Guaranteed insert order?
[ID] [int] NOT NULL,
[OtherID] [int] NULL
)
INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID] INTO @New
SELECT [Data]
FROM @Old
ORDER BY [RowID]
Run Code Online (Sandbox Code Playgroud)
这里的技巧是使用单独的identity
列和ORDER BY
选定的行,然后加入 RowID
.
你可以(ab)使用MERGE
with OUTPUT
子句.
MERGE
可以INSERT
,UPDATE
和DELETE
行.在我们的例子中,我们只需要INSERT
.1 = 0始终为false,因此NOT MATCHED BY TARGET
始终执行该部件.一般来说,可能还有其他分支,请参阅docs.
WHEN MATCHED
通常用来UPDATE
;
WHEN NOT MATCHED BY SOURCE
通常习惯DELETE
,但我们在这里不需要它们.
这种复杂的形式MERGE
相当于简单INSERT
,但与简单不同,INSERT
它的OUTPUT
子句允许引用我们需要的列.它允许从源表和目标表中检索列,从而保存旧ID和新ID之间的映射.
MERGE INTO [dbo].[Test]
USING
(
SELECT [Data]
FROM @Old AS O
) AS Src
ON 1 = 0
WHEN NOT MATCHED BY TARGET THEN
INSERT ([Data])
VALUES (Src.[Data])
OUTPUT Src.ID AS OldID, inserted.ID AS NewID
INTO @New(ID, [OtherID])
;
Run Code Online (Sandbox Code Playgroud)
关于您的更新并依赖生成的IDENTITY
值的顺序.
在简单的情况下,当[dbo].[Test]
有IDENTITY
柱,然后INSERT
用ORDER BY
将保证所生成的IDENTITY
值将是按照指定的顺序.请参阅SQL Server中的订购保证中的第 4点.请注意,它不保证插入行的物理顺序,但它保证了IDENTITY
生成值的顺序.
INSERT INTO [dbo].[Test] ([Data])
SELECT [Data]
FROM @Old
ORDER BY [RowID]
Run Code Online (Sandbox Code Playgroud)
但是,当你使用该OUTPUT
条款时:
INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID] INTO @New
SELECT [Data]
FROM @Old
ORDER BY [RowID]
Run Code Online (Sandbox Code Playgroud)
OUTPUT
流中的行未排序.至少,严格来说,ORDER BY
在查询中适用于主要INSERT
操作,但没有任何内容表明该命令的顺序是什么OUTPUT
.所以,我不会试图依赖它.使用MERGE
或添加额外的列以显式存储ID之间的映射.
归档时间: |
|
查看次数: |
6582 次 |
最近记录: |