如何获取标识值列 - SQL

Posted

技术标签:

【中文标题】如何获取标识值列 - SQL【英文标题】:How to get Identity value Column - SQL 【发布时间】:2009-01-17 12:12:34 【问题描述】:

我有一个将记录从一个表插入到另一个表的过程。目标表有一个名为 LeadId 的标识列

Create Procedure prcInsertPrd As Begin Begin Transaction Declare @Identity int Insert into Temp_ProductsArchive (column1,column2,column3) select (column1,column2,column3) from Temp_Products if(@@Error=0) Begin Commit End else Begin Rollback End End

然后我编写了一个插入触发器,它将从插入的表中获取 LeadId,并将其插入到另一个具有其他值的表中-

Alter TRIGGER trgInsertTopProducts ON Temp_ProductsArchive AFTER INSERT AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; declare @LeadId as int Select @LeadId=LeadId from inserted print @LeadId Insert into Temp_ProductsTop(column4,LeadID,Column5,column6) Select column4,@LeadID 'LeadID',column 5,column6 from Temp_Products END GO

问题是我得到的是第一个生成的 LeadiD,而不是所有的 LeadId。 Temp_ProductsTop 表中的 LeadiD 列仅针对记录数重复此值

【问题讨论】:

你想完成什么? 【参考方案1】:

您的触发器存在重大问题。当你编写一个触发器时,你必须假设它可能被多行调用。即inserted 表可能包含不止一行,这意味着您必须加入到插入的表中。

我不确定您要在代码中实现什么,但您需要重写如下内容:

   Alter TRIGGER trgInsertTopProducts  
    ON  Temp_ProductsArchive 
    AFTER INSERT AS
    BEGIN    
      SET NOCOUNT ON;    
      insert into Temp_ProductsTop 
        (ProductID,LeadID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) 
      Select ProductID, inserted.LeadID, ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued 
      from 
        Temp_Products
        inner join inserted on inserted.Leadid = ?
    END

GO

在哪里?代表您加入的 table.column。是否要为每个 LeadId 添加 temp_products?

【讨论】:

这是正确的方法,您可能可以消除与 Temp_Products 的连接,因为插入的伪表将具有所有值,除非它是一个而不是触发器 不,我不想为 LeadId 添加 Temp_Products @Badmate:也许你可以解释一下?【参考方案2】:

"inserted" 是一个伪表,其中包含插入的每个项目的行。触发器总共只触发一次,而不是每个插入的条目一次!

您可能需要使用游标来遍历插入的记录,一次处理一条。也许:

Alter TRIGGER trgInsertTopProducts
  ON Temp_ProductsArchive
  AFTER INSERT
AS
BEGIN
  -- SET NOCOUNT ON added to prevent extra result sets from
  -- interfering with SELECT statements.
  SET NOCOUNT ON;
  declare @LeadId as int
  declare c CURSOR READ_ONLY for
    select LeadId from inserted

  open c
  fetch next from c into @LeadId
  while @@FETCH_STATUS = 0
  BEGIN
    Insert into Temp_ProductsTop(ProductID,LeadID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) Select ProductID,@LeadID 'LeadID',ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued from Temp_Products
    fetch next from c into @LeadId
  END
  close c
  deallocate c
END

(请注意,我只是在这里输入的,还没有经过语法检查或测试)

【讨论】:

建议人们在基于集合的解决方案通常且适当时使用游标,这不是 IMO 的好建议。 你可以通过 insert into.... select * from inserted 来完成这个设置,这会快很多倍,触发器应该尽可能快

以上是关于如何获取标识值列 - SQL的主要内容,如果未能解决你的问题,请参考以下文章

插入记录后如何从 SQL 服务器获取标识值

SQL Server 主表主键自增量,如何获取主键呢?

如何在 Excel 中生成的 SQL 插入语句中获取行数?

如何在值列中搜索特定值并在 Big Query SQL 中替换为该特定值?

Pivot Rows to Columns 考虑到列名和值列 SQL

如何获取Android唯一标识