从存储过程完成的第一个插入中提取 id 以在第二个存储过程上使用的麻烦

Posted

技术标签:

【中文标题】从存储过程完成的第一个插入中提取 id 以在第二个存储过程上使用的麻烦【英文标题】:Troubles pulling id from first insert done by stored procedure to do use on second stored procedure 【发布时间】:2009-12-10 16:24:02 【问题描述】:

我无法从第一个插入中提取 id 以用于第二个插入。这是我的 SQL(我正在使用存储过程):

DECLARE @JoinDate date
DECLARE @ID int
SET @JoinDate = getdate()

EXEC Members_Add $(UserID), '$(UserName)', 
       @JoinDate, '$(firstname)', '$(lastname)', NULL, 
      '$(Country)', NULL,  '$(stateorprovince)', '$(city)', 
      '$(ziporpostalcode)', '$(addressline1)', '$(addressline2)', 
      '$(MailCountry)', NULL, '$(mailstateprovince)', '$(MailCity)', 
      '$(mailzipcode)', '$(mailaddress)', NULL, NULL, NULL, 
      '$(mobilephone)', NULL, '$(Fax)', '$(Email)', NULL, NULL

SELECT @ID = SCOPE_IDENTITY()

EXEC Merchants_Add @ID, NULL, '$(BusinessName)', '$(CorporateName)', 
      '$(contactperson)', '$(OfficePhone)', '$(website)', 
      '$(DirectoryListing)', 'False'

我需要获取第一个存储过程添加的记录的 ID,我读到您应该使用 SELECT @@IDENTITY 而不是 SELECT Max(ID) 但它似乎不起作用...

编辑:我刚刚将 SELECT @@IDENTITY AS NEW_ID 更新为 SELECT SCOPE_IDENTITY AS NEW_ID,现在我收到了无法将 nvarchar 转换为 int 的错误...有什么想法吗?

编辑 #2: 再次更新代码...现在我无法将值 NULL 插入到“成员 ID”列中,这是 @ID 所在的 @ 987654326@程序。

【问题讨论】:

【参考方案1】:

您应该使用 SCOPE_IDENTITY()。

看看SCOPE_IDENTITY (Transact-SQL)

@@IDENTITY 和 SCOPE_IDENTITY 将 返回最后一个标识值 在当前的任何表中生成 会议。但是,SCOPE_IDENTITY 仅在 当前范围; @@IDENTITY 不是 仅限于特定范围。

尝试使用类似的东西

DECLARE @ID INT
EXEC Members_Add $(UserID), '$(UserName)', 
       @JoinDate, '$(firstname)', '$(lastname)', NULL, 
      '$(Country)', NULL,  '$(stateorprovince)', '$(city)', 
      '$(ziporpostalcode)', '$(addressline1)', '$(addressline2)', 
      '$(MailCountry)', NULL, '$(mailstateprovince)', '$(MailCity)', 
      '$(mailzipcode)', '$(mailaddress)', NULL, NULL, NULL, 
      '$(mobilephone)', NULL, '$(Fax)', '$(Email)', NULL, NULL

SELECT @ID = SCOPE_IDENTITY()

EXEC Merchants_Add @ID, NULL, '$(BusinessName)', '$(CorporateName)', 
      '$(contactperson)', '$(OfficePhone)', '$(website)', 
      '$(DirectoryListing)', 'False'

注意@ID的使用

来自@@IDENTITY

【讨论】:

来自文档:返回插入到同一范围内的标识列中的最后一个标识值。范围是一个模块:存储过程、触发器、函数或批处理。因此,如果两条语句在同一个存储过程、函数或批处理中,则它们属于同一范围。 阅读规范...忽略我的问题:D 和 +1 我尝试将 SELECT SELECT @@IDENTITY AS NEW_ID 更改为 SELECT SCOPE_IDENTITY() AS NEW_ID ,现在我得到一个无法将 nvarchar 转换为错误...我更新了问题,你能接受吗再看看? 您应该使用 DECLARE @ID INT... 然后在插入 SELECT @ID = SCOPE_IDENTITY() 之后。检查这是否有效。您需要将值分配给参数。 刚刚做到了...现在它说不能在 MemberID 字段中插入 null (这就是您的代码中的@ID)我猜 SCOPE_IDENTITY() 出于某种原因返回 NULL... 【参考方案2】:

试试:

DECLARE @JoinDate date
DECLARE @newId int
SET @JoinDate = getdate()

EXEC Members_Add $(UserID), '$(UserName)', @JoinDate, '$(firstname)', '$(lastname)', NULL, '$(Country)', NULL, '$(stateorprovince)', '$(city)', '$(ziporpostalcode)', '$(addressline1)', '$(addressline2)', '$(MailCountry)', NULL, '$(mailstateprovince)', '$(MailCity)', '$(mailzipcode)', '$(mailaddress)', NULL, NULL, NULL, '$(mobilephone)', NULL, '$(Fax)', '$(Email)', NULL, NULL

SELECT @newId = SCOPE_IDENTITY()

EXEC Merchants_Add @newId, NULL, '$(BusinessName)', '$(CorporateName)', '$(contactperson)', '$(OfficePhone)', '$(website)', '$(DirectoryListing)', 'False'

编辑:使用首选的 SCOPE_IDENTITY() 而不是 @@IDENTITY 更改了源以反映所需的语法。

【讨论】:

【参考方案3】:

您需要声明并使用一个 T-Sql 变量来保存标识值。而且您通常应该使用 Scope_Identity() 而不是 @@Identity...

  DECLARE @JoinDate dateSET @JoinDate = getdate()
  Declare @NewId Integer 
  EXEC Members_Add $(UserID), '$(UserName)',  @JoinDate, '$(firstname)', 
       '$(lastname)', NULL, '$(Country)', NULL,  '$(stateorprovince)',      
       '$(city)',  '$(ziporpostalcode)', '$(addressline1)',        
       '$(addressline2)','$(MailCountry)', NULL, '$(mailstateprovince)', '
       $(MailCity)','$(mailzipcode)', '$(mailaddress)', NULL, NULL, NULL,
       '$(mobilephone)', NULL, '$(Fax)', '$(Email)', NULL, NULL

  -- Here get identity Value
  Set @NewId = Scope_Identity()

  EXEC Merchants_Add @NewId, NULL, '$(BusinessName)', '$(CorporateName)',
       '$(contactperson)', '$(OfficePhone)', '$(website)',
       '$(DirectoryListing)', 'False'

【讨论】:

以上是关于从存储过程完成的第一个插入中提取 id 以在第二个存储过程上使用的麻烦的主要内容,如果未能解决你的问题,请参考以下文章

从第二个关系中拉出文物

Django 在第二个数据库上调用存储过程

如何使用 PyQt5 QThread 从 CLASS(ShowVideo) 中获取值以在第二个 CLASS(ImageViewer) 中使用(根据我的程序)

根据第二个文件中相应的ID列表从文件中提取第一个条目?

与powershell的第二个浏览器选项卡进行交互

在同一个脚本python中使用来自一个请求的第二个url请求的数据