使用 scope_identity 多插入如何?

Posted

技术标签:

【中文标题】使用 scope_identity 多插入如何?【英文标题】:Multi insert with scope_identity how to? 【发布时间】:2019-04-08 13:22:39 【问题描述】:

我对 SSIS OLE DB 命令有疑问。

我要做的是插入“person”表并从插入中获取新创建的PersonID(表标识),因为我需要它来创建与 PersonContactInfo 表的关系,这应该是很简单。

我无法编写存储过程,并且大约有 10k 行,因此使用 OLE DB 命令应该没问题。

我已尝试编写此代码,它应该匹配:

DECLARE @PersonID int
---
--- create new person
---
INSERT INTO [dbo].[Personer_LF_TEST] (Fornavne, Efternavne, Oprindelse, OprettetDato, OprettetAf,OprindelseID)
VALUES (?, ?, 'Klimaquiz', ?, 499,7)

SET @PersonID = (SELECT SCOPE_IDENTITY())

---
--- update phonenumber
---
INSERT INTO [dbo].[Kontaktinfo_LF_TEST](PersonID, KontaktInfoTypeID, Notat, Tekst, Oprettet)
VALUES (@PersonID, 5, ?,?, Getdate() )

---
--- update Email
---
INSERT INTO [dbo].[Kontaktinfo_LF_TEST](PersonID, KontaktInfoTypeID, Notat, Tekst, Oprettet)
VALUES (@PersonID, 2,?, ?, Getdate() )

---
--- create persontypecode
---
INSERT INTO [dbo].[PersonArtskoder_LF_TEST](PersonID, ArtskoderID, Notat, Aktiv, CreatedBy, CreatedOn, ModifiedBy, ModifiedOn, StartDato, SlutDato)
VALUES (@PersonID,?, ?, 1, 209, getdate(), 209, getdate(), getdate(), NULL )

我也尝试过像这样成功运行第一部分:

-- Create new Person
INSERT INTO [dbo].[Personer_LF_TEST](Fornavne, Efternavne, Oprindelse, OprettetDato, OprettetAf, OprindelseID)
VALUES (?, ?,'Klimaquiz',?,499,7)

插入 10k 行

如果尝试这样做,它会失败

-- Create new person
INSERT INTO [dbo].[Personer_LF_TEST](Fornavne, Efternavne, Oprindelse, OprettetDato, OprettetAf, OprindelseID)
VALUES(?, ?, 'Klimaquiz', ?, 499, 7)
-- Insert Phone number
INSERT INTO [dbo].[Kontaktinfo_LF_TEST](PersonID, KontaktInfoTypeID, Tekst, Oprettet)
VALUES (1, 5, ?, Getdate())

错误是:

数据流任务 [OLE DB 命令 [178]] 出错:SSIS 错误代码 dts_E_OLEDBERROR。发生了 OLE DB 错误。

错误代码:0x80004005。 OLE DB 记录可用。来源: ” Microsoft SQL Server Native Client 11.0" Hresult:0x80004005 说明:“插入值列表与列列表不匹配”

但输入应与列列表匹配。

这是我希望 OLD DB 命令执行的“有点”代码

DECLARE @PersonID int
---
--- create new person
---
INSERT  INTO [dbo].[Personer_LF_TEST](Fornavne, Efternavne, Oprindelse, OprettetDato, OprettetAf,OprindelseID)
VALUES  ('Simster', 'Mann', 'Klimaquiz', '03-25-2019', 499,7)
SET @PersonID = (SELECT scope_identity())
---
--- update phonenumber
---
INSERT  INTO [dbo].[Kontaktinfo_LF_TEST](PersonID, KontaktInfoTypeID, Notat, Tekst, Oprettet)
VALUES  (@PersonID, 5, 'WEB','22004400', Getdate() )
---
--- update Email
---
INSERT  INTO [dbo].[Kontaktinfo_LF_TEST](PersonID, KontaktInfoTypeID, Notat, Tekst, Oprettet)
VALUES  (@PersonID, 2,'WEB', 'Simster@codewithme.dk', Getdate() )
---
--- create persontypecode
---
INSERT  INTO [dbo].[PersonArtskoder_LF_TEST](PersonID, ArtskoderID, Notat, Aktiv, CreatedBy, CreatedOn, ModifiedBy, ModifiedOn, StartDato, SlutDato)
VALUES  (@PersonID,'30395', 'WEB', 1, 209, getdate(), 209, getdate(), getdate(), NULL )

【问题讨论】:

如果我在 SSMS 中使用虚拟数据执行此查询,我执行它没有问题 【参考方案1】:

如果我在 SSMS 中使用虚拟数据执行此查询,我执行它没有问题,

DECLARE @PersonID int
---
--- create new person
---
INSERT  INTO [dbo].[Personer_LF_TEST](Fornavne, Efternavne, Oprindelse, OprettetDato, OprettetAf,OprindelseID)
VALUES  ('TEST', 'Simmy', 'Klimaquiz', GETDATE(), 499,7)
SET @PersonID = (SELECT scope_identity())
---
--- update phonenumber
---
INSERT  INTO [dbo].[Kontaktinfo_LF_TEST](PersonID, KontaktInfoTypeID, Notat, Tekst, Oprettet)
VALUES  (@PersonID, 5, 'WEB',33445566, Getdate() )
---
--- update Email
---
INSERT  INTO [dbo].[Kontaktinfo_LF_TEST](PersonID, KontaktInfoTypeID, Notat, Tekst, Oprettet)
VALUES  (@PersonID, 2,'WEB', 'simster@codewithme.dk', Getdate() )
---
--- create persontypecode
---
INSERT  INTO [dbo].[PersonArtskoder_LF_TEST](PersonID, ArtskoderID, Notat, Aktiv, CreatedBy, CreatedOn, ModifiedBy, ModifiedOn, StartDato, SlutDato)
VALUES  (@PersonID,'30895', 'WEB', 1, 209, getdate(), 209, getdate(), getdate(), NULL ) 

我成功插入了 4 行,但我无法让它在 OLE DB 命令对象中工作。我的想法是在流中添加一列,然后在数据流之后添加一个执行 sql 命令,然后执行 SQL 命令将基于列中的输入插入、更新或删除/不执行任何操作。但这似乎是一种乏味的方式。

【讨论】:

这是问题的附录吗? 您已将此作为答案发布。这是否意味着您的问题已解决? 您可以使用新信息修改您的原始帖子(最好标记为编辑或更新)。我建议您这样做,然后删除此答案。【参考方案2】:

我认为最好的方法可能是将其分解。

使用此链接 http://radacad.com/output-parameter-of-stored-procedure-in-ole-db-command-ssis 添加编辑以处理此问题是 SSIS:

    将您的数据读入数据流。

1.1(编辑)添加派生列并将 ID 设置为 null(dt_int)

    使用 OLE DB 命令插入新行并将范围标识返回到列中。

2.1(编辑)将您的列映射到返回 scope_identity() 的存储过程的输出参数

    使用多播并为派生列设置 3 个新路径 使用派生列输入硬编码值 使用 OLEDB Destination 一次性插入所有记录。

这允许您批量插入 3 个后续查询。

后期编辑:

就像我说的,我对 C# 脚本组件很快,这是一个如何做到这一点的示例......

how to get the last record number after inserting record to database in access

【讨论】:

谢谢 KeithL,你有关于如何让 OLE DB 将 ID 返回到列中的链接吗?我看过这个***.com/questions/8914818/… ......但是他们把它放在这里在 SSIS 变量中,但这对我不起作用... :-S 我不得不承认。我会很快跳到 c#,但这看起来是如何使用 SSIS 的一个很好的例子。 radacad.com/… 但是如果不能创建存储过程呢?那么您的解决方案将不起作用? :-( 添加了如何在 C# 脚本组件中执行步骤 2 的链接

以上是关于使用 scope_identity 多插入如何?的主要内容,如果未能解决你的问题,请参考以下文章

如果使用多个插入语句,有啥方法可以使用 SCOPE_IDENTITY 吗?

在插入时插入 SCOPE_IDENTITY

插入值时的 SCOPE_IDENTITY

SCOPE_IDENTITY,多个插入,如果当前插入没有插入,则携带前一个插入的值

为啥 SCOPE_IDENTITY() 不返回我插入的 ID?

SCOPE_IDENTITY 在这种情况下是不是有效?