Alternatives to @@IDENTITY in SQL Server 2000

來源:互聯網
上載者:User
Alternatives to @@IDENTITY in SQL Server 2000
@WWW_TRANSTAAFL_COM 2006-03-05
--------------------------------------------------------------------------------
本文詳細介紹了SQL Server 2000 中獲得剛剛插入的記錄的解決方案。
--------------------------------------------------------------------------------
Mark writes: "I was asked a question today by a developer having problems getting the right identity value from @@identity when a table has a trigger which has an additional insert - Post the insert statement the select @@identity returns the wrong value (which is behaviour I would expect).

Is there a trick to get round this, apart from not using triggers and/or not using identity columns - which is what I suggested ..."

Prior to SQL Server 2000, the answer was "no". However, SQL Server 2000 adds two cool new functions to help you get around this problem. Read on... SQL Server 2000 has three functions that return IDENTITY information. The result of each of these three functions is dependent on three factors:

  • The session scope (which connection produced the IDENTITY value?)
  • The table scope (which table produced the IDENTITY value?)
  • The statement scope (where is the statement that produced the IDENTITY value?)

(SQL Statements that are contained in the same batch, stored procedure, or trigger are considered to be in the same scope. So, if I call an INSERT that fires a trigger, I have two different scopes: scope 1 is inside the batch that called the INSERT, and scope 2 is inside the trigger.)

SELECT @@IDENTITY
This is everyone's favorite function, unchanged from earlier versions of SQL Server. It returns the last IDENTITY value produced on a connection, regardless of the table that produced the value, and regardless of the scope of the statement that produced the value.

SELECT IDENT_CURRENT('tablename')
This new function returns the last IDENTITY value produced in a table, regardless of the connection that created the value, and regardless of the scope of the statement that produced the value.

SELECT SCOPE_IDENTITY()
This new function returns the last IDENTITY value produced on a connection and by a statement in the same scope, regardless of the table that produced the value.

Okay, I think these are best explained with an example, and since Mark has provided a good one, we'll use it.
Let's create some tables:

CREATE TABLE YakName (ID int IDENTITY(1,1), YakName varchar(30))CREATE TABLE YakTracker (ID int IDENTITY(1000,1), TranType char(1), YakName varchar(30))GO
CREATE TRIGGER tI_Yak ON YakName FOR INSERTASBEGIN INSERT YakTracker (TranType, YakName) SELECT 'I',YakName FROM insertedENDGO

This is a basic scenario that duplicates the problem Mark described. Whenever I insert a record(s) into YakName, the trigger will insert a record(s) into YakTracker (we need audit information on the Yaks, apparently).

Now, Mark's developer is trying something like this:

INSERT YakName VALUES ('Graz')
SELECT @@IDENTITY

Although what we really want from this batch of statements is the last IDENTITY value for the YakName table, we get the value 1000--the last IDENTITY value

for the YakTracker table. Why is this? The second insert statement in the trigger also inserts into a table with an identity. Remember, @@IDENTITY works across all tables (YakName, YakTracker) and all scopes (batch scope, trigger scope), so it picked up the change we made to a different table (YakTracker) in a different scope (the trigger)!

Prior to SQL Server 2000, we would have been stuck. At this point, we'd have to eliminate the IDENTITY column on the YakTracker table to get these statements working the way we want them to.

But let's say we've shelled out the cash for the latest copy of SQL Server 2000. Let's look at how the new functions would behave:

INSERT YakName VALUES ('Billy Joe Bob')
SELECT SCOPE_IDENTITY() --returns the value 2

SELECT IDENT_CURRENT('YakName') --returns the value 2 (maybe)
SELECT IDENT_CURRENT('YakTracker') --returns the value 1001 (maybe)

SCOPE_IDENTITY() works for all tables in the scope for which it was called , which in this case is the original batch. So, we get the last value for the YakName table, which is what we wanted.

Note that I included some samples for IDENT_CURRENT as well. Unless someone else on another connection is also inserting values into the YakName table, you will get the results shown in the example. (Remember that the IDENT_CURRENT function disregards which connection produced the last IDENTITY value for the specified table.)

Admittedly, these are some pretty handy functions. Of course, I saw these and wanted more... Wouldn't it be nice to have a rowset function that returned all of the IDENTITY values created because of a multi-row insert? Oh well, I guess we have to wait through another couple of versions to see that feature.

-SQLGuru

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.