当前位置: 首页 > 面试题库 >

将OUTPUT insert.id与所选行中的值合并

司马同
2023-03-14
问题内容

运行中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

我需要将插入的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]

这里的技巧是使用一个单独的identity列并ORDER BY用于选定的行,然后 在上加入 RowID


问题答案:

您可以(MERGEwith
)使用withOUTPUT子句。

MERGE可以INSERTUPDATEDELETE行。就我们而言,我们只需要INSERT。1 = 0始终为假,因此NOT MATCHED BY TARGET始终执行该部分。通常,可能还有其他分支,请参阅文档。 WHEN MATCHED通常用于UPDATE; WHEN NOT MATCHED BY SOURCE通常用于DELETE,但是我们在这里不需要它们。

这种复杂的形式MERGE等效于simple
INSERT,但与simple不同,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])
;

关于您的更新,并依赖于生成IDENTITY值的顺序。

在简单的情况下,当[dbo].[Test]hasIDENTITY列时,INSERTwithORDER BY 可以
保证生成的IDENTITY值将按指定的顺序排列。

INSERT INTO [dbo].[Test] ([Data])
SELECT [Data]
FROM @Old
ORDER BY [RowID]

但是,当您使用该OUTPUT子句时:

INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID] INTO @New
SELECT [Data]
FROM @Old
ORDER BY [RowID]

OUTPUT流中的行未排序。至少严格来说,ORDER BY查询中的查询适用于主INSERT操作,但是没有什么可以说明的顺序OUTPUT。因此,我不会尝试依靠它。使用MERGE或添加额外的列来显式存储ID之间的映射。



 类似资料:
  • 问题内容: 我想将地图转换为: 至 结果列表是所有列表值的合并。 问题答案: 你可以有 这将检索映射的值,然后将每个列表平面映射到由其元素形成的Stream中,并将结果收集到列表中。 另一种选择是,不对每个列表进行平面映射,从而可能会提高性能,而无需对每个列表进行平面映射,则可以通过调用每个累加的结果来直接收集(由返回)。

  • 问题内容: 我需要将单行的所有而不是空值放入一个字符串中,例如 表: 导致: 重要说明-我不知道字段名称/类型,因此它应该遍历所有字段,并且所有非null值都将添加到列表中。 看起来它可以使用xquery做到这一点,但找不到正确的语法。有什么提示吗? 谢谢! 问题答案: select T2.N.value(‘local-name(.)’, ‘nvarchar(128)’)+’: ‘+ T2.N.v

  • 我有一个熊猫数据框,如下所示 我想找到每个日期介绍的,如果item_id介绍超过1个日期,那么我想找到每个日期的比例'(qty_bought/qty_purchased)。 我想要的输出如下 标志的条件是当比率大于以前的日期时,应将其设置为1或0 如果我在5个不同的日期引入了项目,那么这将动态生成5个日期和比率列。比率将具体到该日期。我只想列出那些引入了多次的。 这是我对python的尝试 这给了

  • 我试图通过数据的selectedRow从jTable到jTextField和jComboBox。 对于jTextField的每一行,我选择它会自动填充jTextFields,但对于jComboBox部分,当我选择一行时,它会正确填充,但当我选择另一行时,它会保留第一个选定的数据,我想传递任何选定行的数据:

  • 问题内容: 大家好,我将我的下拉列表与Jquery-Select2绑定在一起。它的工作正常,但现在我需要使用Jquery-Select2绑定多值selectBox。 我的DropDwon 通过此链接 http://ivaynberg.github.com/select2/ 我正在使用Mutiple Value Select Box,我可以将dropdwon与 它的工作正常,但现在我需要在编辑模式的

  • 我要做的是合并几行数据以显示为单行。基于行的最高值。因此只保留具有最高值的记录 由此得出: 对此: 欢迎提出任何建议。 多谢了。