在存储过程中一起使用@@ IDENTITY或SCOPE_IDENTITY()+ Insert

时间:2011-08-29 21:22:45

标签: sql-server tsql

代码就像这样

   INSERT INTO TABLE (VAL1,VAL2,VAL3) VALUES (X,Y,Z)

   GetLastInsertID @tablename='TABLE'

GetLastInsertID是此存储过程:

   SELECT @@IDENTITY AS LastID FROM TABLE

如何让存储过程按照上面的Select @@ IDENTITY语句中的要求返回'LastID'?

我收到以下错误:

   Incorrect syntax near 'GetLastInsertId'.

...但这在单独执行时效果很好:

   GetLastInsertID @tablename='TABLE'

好的,谢谢我将它更新为Scope_Identity()。但是你说不要把它放在一个不同的SP中,把它放在与Insert相同的SP中?

同样,当我将插入与此组合时,我仍然会收到错误:

   SELECT SCOPE_IDENTITY() AS LastID FROM TABLE

以下是新的错误消息:

   There is already an object named 'TABLE' in the database.

4 个答案:

答案 0 :(得分:5)

将它分成存储过程根本不是一个坏主意,因为存储过程会创建一个新的范围/上下文。这让你开始抓住错误的身份证号码。如果会话中的一个用户一起插入多行,则可能会得到错误的结果。

相反,您几乎总是需要scope_identity()函数,并且您希望在与创建新记录的语句相同的上下文中调用它。

答案 1 :(得分:2)

首先,您不想使用@@ identity,因为如果有人添加了触发器,它可能会中断。

您要使用的是OUTPUT子句或scope_identity。有关如何使用OUTPUT的示例,请参阅联机丛书。

答案 2 :(得分:0)

您的错误是您未能包含EXECUTE命令,请尝试此操作:

INSERT INTO TABLE (VAL1,VAL2,VAL3) VALUES (X,Y,Z)

EXEC GetLastInsertID @tablename='TABLE'

当您尝试运行没有其他命令的过程时,会假定EXEC,但是当您包含INSERT时,它会使EXEC成为必需。

现在,你真的需要确定你想要做的是一个好的设计。

试试这个:

DECLARE @LastId int
INSERT INTO TABLE (VAL1,VAL2,VAL3) VALUES (X,Y,Z)
SELECT @LastID=SCOPE_IDENTITY()

答案 3 :(得分:-1)

这是我执行此操作的示例代码。 (但存储的proc不会添加任何值。)

--First create a test table.
    create table test
    (id int identity,
    name varchar(30))
    go

--A stored proc that returns the scope_identity()  
    create proc dbo.spTest
    as

    insert into test(name)
    values ('test')

    return scope_identity()

    go


-- Sample call
    declare @newId int

    exec @newId = spTest

    print @newId