2011-08-29 104 views
0

的代碼是這樣的在存儲過程

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

    GetLastInsertID @tablename='TABLE' 

GetLastInsertID使用@@ IDENTITY SCOPE_IDENTITY或()+插入,一起爲這個存儲過程:

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

使用[SCOPE_IDENTITY()](http://msdn.microsoft.com/en-us/library/ms190315.aspx)是優選的,而不是'@@ IDENTITY'。 –

+0

@Joe:請參閱[Joel的答案](http://stackoverflow.com/questions/7236141/using-identity-insert-together-in-stored-procedures/7236192#7236192),SCOPE_IDENTITY不起作用,因爲存儲 - 程序是一個不同的範圍。 –

+0

請參閱[Identity Crisis](http://msdn.microsoft.com/zh-cn/library/aa224821(SQL.80).aspx)爲什麼@@ IDentity不好。它的一篇舊文章,但標題很容易記住 –

回答

5

這是一個壞主意,這個分離成因爲存儲過程會創建一個新的範圍/上下文。這讓你打開篡改錯誤的身份證號碼。如果會話中的一個用戶將多行記錄在一起,您可能會得到錯誤的結果。

相反,您幾乎總是希望使用scope_identity()函數,並且您想在與創建新記錄的語句相同的上下文中調用它。

+0

不確定你的意思「如果會話中的一個用戶插入多行,你可能會得到錯誤的結果。」 AFAIK唯一的問題是觸發器(以及具有並行性的錯誤,適用於'@@ IDENTITY'和'SCOPE_IDENTITY') –

+0

@Martin - 請參閱此[msdn page](http://msdn.microsoft.com/zh-cn/ /library/ms190315.aspx) - SCOPE_IDENTITY和@@ IDENTITY返回當前會話中任何表中生成的最後一個標識值。但是,SCOPE_IDENTITY返回僅在當前範圍內插入的值; @@ IDENTITY不限於特定的範圍。因此,即使範圍不同,@@身份在任何時候在同一個會話中都有多個插入時都會遇到問題。觸發器就是最常見的例子。 –

+1

@馬丁 - 當然。存儲過程(即:這個問題);) –

2

首先,你永遠不想使用@@身份,因爲如果有人添加觸發器,它可能會中斷。

你想要使用的是OUTPUT子句或scope_identity。請參閱聯機叢書以瞭解如何使用OUTPUT的示例。

-1

這是我的示例代碼,這樣做。 (但存儲的過程中不添加任何價值)

--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 
+0

SP看起來就像那樣,但是當SP正在被保存/更改時它仍然給出錯誤: Msg 2714,數據庫中已經有一個名爲'spTest'的對象。 –

+0

將'return'混入是一個非常糟糕的主意,存儲過程不應該使用'return'(可以將它用於SQL 2005之前的錯誤代碼,但是現在可以使用RAISERROR並拋出)。使用一個OUTPUT參數。 –

+1

如果您已經有一個名爲spTest的sp,您可以將「create proc」更改爲「alter proc」。 – JBrooks

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() 
+0

你的第二個例子在上面的例子中產生錯誤。 –