【问题标题】:MS SQL Server Last Inserted IDMS SQL Server 上次插入的 ID
【发布时间】:2013-05-08 04:50:41
【问题描述】:

在我的数据库中,所有表都使用一个公用表来表示 Sequence(ID_Table)。

TABLE_ID 有两个字段(Common_ID、Table_Name)。

如果我在表中插入任何记录,我必须首先在 Table_ID(Auto-increment, Table_name) 中插入一条记录,然后在我的其他表中使用该自动增量值。

例如,我想在 Table_Products 中插入字段 ID(Common_ID)、Product_Name、Product_ID(Auto Increment)

我想做这样的事情:

INSERT INTO TABLE_ID (Table_NAME), Values (Table_Products)

获取插入的 ID 并在 Table_Products 中使用:

INSERT INTO Table_Products (ID, Product_Name, Product_ID(Auto Increment) 
VALUES (ID from TABLE_ID, SomeProduct, Increment)

【问题讨论】:

  • "在我的数据库中,所有表都使用一个公用表来表示 Sequence(ID_Table)。" - 为什么?
  • @user2345661 - 您的 TABLE_ID 包含 id ,我必须在下一次插入 table_products 时使用它吗?
  • 嗯,这是一个火鸟数据库,由其他人创建,我转换为 SQL 服务器。
  • 您是否使用 storeprocedure 在两个表中插入?
  • 不,我正在尝试使用简单的插入。一旦我能够做到这一点,我就会学习存储过程。我是用 C# 做的。

标签: sql sql-server


【解决方案1】:

试试这个 -

DECLARE @ID BIGINT

INSERT INTO dbo.TABLE_ID (Table_NAME) 
SELECT 'Table_Products'

SELECT @ID = SCOPE_IDENTITY()

INSERT INTO dbo.Table_Products (ID, Product_Name)
SELECT @ID, 'SomeProduct'

【讨论】:

  • 我想有人在这里玩。也有人对我投了反对票。 :(
【解决方案2】:

您可以使用带有output 子句的insert 语句来生成新的Common_ID。使用insert ... select,您可以在插入操作中指定该 ID:

declare @Common_ID as table(ID int)

insert  Table_ID
        (Table_Name)
output  inserted.Common_ID into @Common_ID
values  ('Table_Products')

insert  Table_Products
        (ID, Product_Name)
select  ID
,       'Some Product'
from    @Common_ID 

【讨论】:

    【解决方案3】:

    在你的插入语句之后使用 SCOPE_IDENTITY() 来获取最后插入的 id。

    DECLARE @Product_Id int
    
    INSERT INTO TABLE_ID (Table_NAME) VALUES (Table_Products);
    SELECT @Product_Id=SCOPE_IDENTITY();
    
    Insert INTO Table_Products (ID, Product_Name)
    VALUES (ID from TABLE_ID, 'SomeProduct')
    

    【讨论】:

    • 多个语法错误 (Table_NAME), Values)、未声明的变量 (@Product_Id) 以及在插入值列表中指定标识列 (Product_ID)
    • @Andomar:他不会在生产服务器上部署这段代码。我只是给他一个答案,而不是要部署的脚本。
    • @Sivakumar 你为什么争论而不是纠正这些愚蠢的错误?
    • @lgor:我找不到批准按钮来批准您建议的编辑。所以我只是复制和粘贴。别误会我。
    【解决方案4】:

    亲爱的朋友,您必须选择插入的最后一条记录的 id 然后在另一个表中传递它,所以下面的代码会很好地帮助你

    Insert INTO TABLE_ID (Table_NAME), Values (Table_Products)
    DECLARE @ID int;
    set @ID = SCOPE_IDENTITY(); 
    
    Insert INTO Table_Products (ID, Product_Name) 
    Values (@ID, SomeProduct)
    

    此代码将解决您的问题,我为您的最后一个记录 ID 定义 @ID,然后将其插入到您的其他表中

    【讨论】:

      【解决方案5】:

      MySql 使用select LAST_INSERT_ID();

      【讨论】:

      • 问题是针对 SQL Server 的
      【解决方案6】:

      到目前为止,所有其他答案都为 SCOPE_IDENTITY() 声明了中间变量,但它可能更简单:

      INSERT INTO dbo.TABLE_ID (Table_NAME) VALUES 'Table_Products';
      
      INSERT INTO dbo.Table_Products (ID, Product_Name) VALUES (SCOPE_IDENTITY(),'SomeProduct');
      

      【讨论】:

        【解决方案7】:

        您还可以使用 IDENT_CURRENT() 更具体地表特定

        Insert INTO TABLE_ID (Table_NAME), Values (Table_Products)
        
        select @NewID=IDENT_CURRENT('TABLE_ID')
        
        Insert INTO Table_Products (ID, Product_Name, Product_ID
        Values (@NewID, SomeProduct, Increment)
        

        【讨论】:

        • 使用 IDENT_CURRENT 检索您插入的身份会引入竞争条件。
        • 大多数答案都使用 SCOPE_IDENTITY() 所以我只是给了他替代解决方案,所以我使用了 IDENT_CURRENT 。 SCOPE_IDENTITY() 是否实际上具有相同的场景,尽管在更通用的上下文中并且不是特定于表的?那么输出呢?那是非常特定于表的,它也不会产生竞争条件吗?如果在你得到 @Common_ID 之后有人插入了一毫秒怎么办?那么,它不会是最后一个 ID?
        • scope_identity() 返回会话生成的最后一个 ID。 output 捕获插入语句插入的行。两者都不受其他同时会话的影响。但是ident_current() 会受到竞争条件的影响,而identity()(没有scope_)可以被触发器覆盖。
        • 根据微软的OUTPUT子句,即使有错误还是会给出ID,是不是有风险?您可能没有竞争条件,但您可能会遇到“孤儿”记录。 msdn.microsoft.com/en-us/library/ms177564.aspx
        • 上面使用的output 子句不使用客户端通信。在任何情况下,ident_current 也会在插入过程中发生错误时返回一个值:它将返回先前插入的行的 id。
        猜你喜欢
        • 2019-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多