Sunday, May 8, 2016

SQL Server Brain Basher of the Week #042 - Identity property

Let's talk about an important property we always use; Identity property. This property has been used for generating Ids automatically, and most of the cases, this has been used as the surrogate key. Usage is very simple, all you have to do is, set it with CREATE TABLE statement, assigning the seed (starting value) and increment value. SQL Server will automatically generate a value for this when an insert is performed.

Since the value is not based on an application, we have no clue on the value generated. If we need the newly generated identity value for performing the next step of the process we have written, we used to call either @@identity or Scope_Identity function. Here is this week question based on it;

What is the different between @@identity and Scope_Identity function? Which one should be used for getting the last generated value within the scope?

Let's try to understand the purpose of these two. @@identity is a function that returns the last generated identity value regardless of the scope but for the current session. But Scope_Identity function returns the last generated value within the scope for the current session. That is the different between these two functions. For most cases, Scope_Identity is the best unless you have an unique requirement for getting the value via @@identity.

See this example, it shows how these two functions works.

  1. -- Creating Customer table  
  2. -- Id is an identity, starting number is 1  
  3. CREATE TABLE dbo.Customer  
  4. (  
  5.  Id int identity(1,1) Primary key  
  6.  , Name varchar(100) not null  
  7. );  
  8.   
  9. -- Creating Customer Log table  
  10. -- Id is and identity, starting number is 100  
  11. CREATE TABLE dbo.CustomerLog  
  12. (  
  13.  Id int identity(100,1) Primary key  
  14.  , Info varchar(100) not null  
  15. );  
  16. GO  
  17.   
  18. -- This stored procedure accepts a name  
  19. -- and insert a record  
  20. CREATE PROC dbo.InsertCustomer @Name varchar(100)  
  21. AS   
  22. BEGIN  
  23.   
  24.  INSERT INTO dbo.Customer  
  25.  (NameVALUES (@Name);  
  26.   
  27.  -- Getting CustomerId value via @@identity  
  28.  SELECT @@IDENTITY AS CustomerIdFromIdentityFunction;  
  29.  -- Getting Customer ID via Scope_identity  
  30.  SELECT SCOPE_IDENTITY() AS CustomerIdFromScopeIdentityFunction;  
  31. END  
  32. GO  
  33.   
  34.   
  35. -- This trigger will insert a record to  
  36. -- CustomerLog table  
  37. CREATE TRIGGER dbo.InsertTriggerForCustomer  
  38. ON dbo.Customer  
  39. FOR INSERT  
  40. AS  
  41. BEGIN  
  42.   
  43.  INSERT INTO dbo.CustomerLog  
  44.   (Info) VALUES ('Record is inserted');  
  45. END  
  46.   
  47. -- Executing the first procedure  
  48. EXEC dbo.InsertCustomer 'Dinesh';  


As you see, @@identity returns 100 and Scope_Identity returns 1. The reason for showing 100 for @@identity is, the insert happened inside the trigger. Trigger inserted a record and its Id is 100. Since @@identity for the current session, not for the current scope, it returned the last generated identity regardless of the scope.

No comments: