【问题标题】:Get data from Last Inserted Row从最后插入的行获取数据
【发布时间】:2012-01-21 08:16:03
【问题描述】:

我试图弄清楚如何从我刚刚使用的 INSERT 语句中获取名字和姓氏。它创建了行,我想在下一个插入语句中使用名字和姓氏,我该怎么做?

Declare @idnt int

INSERT INTO dbo.Contacts (ContactFirstName,ContactLastName,ContactCompany) VALUES ('Richard','Burns',NULL);

SELECT @idnt = SCOPE_IDENTITY()

INSERT INTO dbo.Activity (ContactID, ActivityDate, ActivityName, ActivityNote, ActivityOwner)
VALUES (@idnt, '12/13/2011 10:55AM', 'Contact ' + @fname + " " + @lname + ", was automatically added by the system', 'Contact was automatically added by this system', 'System')

【问题讨论】:

    标签: sql sql-server select insert


    【解决方案1】:

    使用SCOPE_IDENTITY() 捕获的标识,查询回表并将ContactFirstNameContactLastName 获取到您声明的变量中:分别为@fname@lname

    ...
    SELECT @idnt = SCOPE_IDENTITY()
    
    SELECT
        @fname = ContactFirstName
      , @lname = ContactLastName
    FROM dbo.Contacts 
    WHERE YOUR_IDENTITY_COLUMN_HERE = @idnt
    
    INSERT INTO dbo.Activity ...
    

    YOUR_IDENTITY_COLUMN_HERE 替换为您假设从中获取SCOPE_IDENTITY() 并进行测试的标识列的名称。

    【讨论】:

    • 我不喜欢SCOPE_IDENTITY 的唯一原因是它可能不准确——它容易受到您插入记录的竞争条件的影响,而另一个用户在您的@987654331 之前插入一条记录@ 运行,因此您得到错误的 ID。当您看到它在生产中发生时,可能非常很难将其识别为错误。
    • @Eric:我不认为会是这样 - 毕竟,它被称为 scope 身份......它会给出最后插入的身份 在您的范围内 - 因此,如果其他连接上的其他用户插入新行 - 这不会影响返回的您的 ID...请参阅MSDN docs on SCOPE_IDENTITYIDENT_CURRENT(tablename) 不受范围限制 - 但始终只返回插入到指定表中的最后一个 ID
    • @marc_s:评论已编辑!出于可读性的原因,我仍然更喜欢output,但你是对的,我将scope_identity 的行为与@@IDENTITY 的行为混淆了。
    • @Eric:同意 - OUTPUT 是一个很好的功能,如果未充分利用。
    【解决方案2】:

    我认为您正在寻找带有 select 语句的插入。试试这个:

        INSERT INTO dbo.Activity (ContactID, ActivityDate, ActivityName, ActivityNote, ActivityOwner)
        SELECT @idnt, '12/13/2011 10:55AM', 'Contact ' + ContactFirstName + ' ' + ContactLastName + ', was automatically added by the system', 'Contact was automatically added by this system', 'System'
        FROM Contacts
        WHERE ContactId = @idnt
    

    【讨论】:

      【解决方案3】:

      使用output

      INSERT INTO dbo.Activity (
          ContactID, 
          ActivityDate, 
          ActivityName, 
          ActivityNote, 
          ActivityOwner
      )
      SELECT 
          ContactID, 
          GETDATE(), 
          'Contact ' + ContactFirstName + ' ' + ContactLastName, 
          'Contact was added by the system.', 
          'System'
      FROM (
          INSERT INTO dbo.Contacts (ContactFirstName,ContactLastName,ContactCompany) 
          OUTPUT inserted.ContactID, inserted.ContactFirstName, inserted.ContactLastName
          VALUES ('Richard','Burns',NULL)
      ) x
      

      更多关于outputsee here的魔力。

      您还可以在表上使用触发器使其自动执行,而不必每次都手动插入。它也使用inserted/deleted 表。

      你可以这样做:

      CREATE TRIGGER Contact_LogActivity ON dbo.Contacts FOR INSERT AS
      INSERT INTO dbo.Activity (
          ContactID, 
          ActivityDate, 
          ActivityName, 
          ActivityNote, 
          ActivityOwner
      )
      SELECT
          ContactID,
          GETDATE(), 
          'Contact ' + ContactFirstName + ' ' + ContactLastName, 
          'Contact was added by the system.', 
          'System'
      FROM
          Inserted
      

      现在,只要将任何行插入到联系人中,它就会将其记录到活动中。有关触发器的更多信息,请参阅here

      【讨论】:

      • +1 我正要提 OUTPUT...我迟到了 10 分钟!
      猜你喜欢
      • 1970-01-01
      • 2015-08-10
      • 1970-01-01
      • 2010-12-07
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      相关资源
      最近更新 更多