zoukankan      html  css  js  c++  java
  • IDENT_CURRENT ,@@identity,SCOPE_IDENTITY() 之间对比

    获取表的标识值,有3种比较常见的用法 IDENT_CURRENT ,@@identity,SCOPE_IDENTITY(),有啥不一样呢?
    3个关键字在联机手册中的解释
     
    • IDENT_CURRENT 返回为某个会话和用域中的指定表生成的最新标识值。
    • @@IDENTITY 返回为跨所有作用域的当前会话中的某个表生成的最新标识值。
    • SCOPE_IDENTITY() 返回为当前会话和当前作用域中的某个表生成的最新标识值。
     
    也就是说,同一作用域下,插入了数据,不考虑并发的情况下,@@IDENTITY ,SCOPE_IDENTITY(),IDENT_CURRENT 的值是没有差别的。
    IDENT_CURRENT 是看表对象。所以没有受作用域限制。
    SCOPE_IDENTITY()  受作用域限制。同一个会话里面不同作用域也会有差异
    @@IDENTITY  受会话限制。不同会话里面值不一样
     
     
    好,开波做测试。
    测试不同点,建立测试表
     
     
    CREATE TABLE TestTB1
    (ID INT IDENTITY(1,1) PRIMARY KEY,
     DATA VARCHAR(50))
    

    当会话没有插入数据的时候, @@IDENTITY  和  SCOPE_IDENTITY() 都是null,而  IDENT_CURRENT是1 这个是需要区别

    SELECT @@identity AS '@@identity' ,
            SCOPE_IDENTITY() AS 'SCOPE_IDENTITY()' ,
            IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'
    

     

    测试@@IDENTITY 和   IDENT_CURRENT('TestTB1') 的值变化是否与会话有关
    会话1:
    1 INSERT INTO TestTB1 (Data) SELECT 'A'
    2 SELECT '会话1',@@IDENTITY AS '@@IDENTITY',IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'

     

    会话2:
    INSERT INTO TestTB1 (Data) SELECT 'B'
    SELECT '会话2',@@IDENTITY AS '@@IDENTITY',IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'
    那再在会话1里面插入一条数据。这个时候,会话2里面的 @@IDENTITY 依然是2,证明 @@IDENTITY 是与会话有关的
    会话1
    INSERT INTO TestTB1 (Data) SELECT 'C'
    SELECT '会话1',@@IDENTITY AS '@@IDENTITY',IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'

     

    会话2

    SELECT * FROM dbo.TestTB1
    SELECT '会话2',@@IDENTITY AS '@@IDENTITY',,IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'

     

    模拟一下不同作用域的情况,创建了一个临时存储过程 #TEST_PRO,
    就能看到 同一会话不同作用域的 SCOPE_IDENTITY() 并不能获取到种子值
     
    TRUNCATE TABLE dbo.TestTB1
    go
    
    CREATE PROCEDURE #TEST_PRO
    AS
    BEGIN
     INSERT INTO TestTB1 (Data) SELECT 'A'
    SELECT @@identity AS '@@identity' ,
            SCOPE_IDENTITY() AS 'SCOPE_IDENTITY()' ,
            IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'
    END
    go
    
    EXEC #TEST_PRO
    
    SELECT @@identity AS '@@identity' ,
            SCOPE_IDENTITY() AS 'SCOPE_IDENTITY()' ,
            IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'

    那嵌套的情况会怎样呢?再嵌套一层看看,实验结果是跟上面是一致的,在嵌套情况下,作用域不同, SCOPE_IDENTITY() 会重新计数,如下

    TRUNCATE TABLE dbo.TestTB1
    go
    
    
    CREATE PROCEDURE #TEST_PRO_Inner
    AS
    BEGIN
     INSERT INTO TestTB1 (Data) SELECT 'A'
     SELECT 'TEST_PRO_Inner',
      @@identity AS '@@identity' ,
            SCOPE_IDENTITY() AS 'SCOPE_IDENTITY()' ,
            IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'
    END
    go
    
    
    CREATE PROCEDURE #TEST_PRO
    AS
    BEGIN
     EXEC #TEST_PRO_Inner
     SELECT 'TEST_PRO',
      @@identity AS '@@identity' ,
            SCOPE_IDENTITY() AS 'SCOPE_IDENTITY()' ,
            IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'
     INSERT INTO TestTB1 (Data) SELECT 'B'
     SELECT 'TEST_PRO_1',
      @@identity AS '@@identity' ,
            SCOPE_IDENTITY() AS 'SCOPE_IDENTITY()' ,
            IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'
    END
    go
    
    EXEC #TEST_PRO
    SELECT '外部',
      @@identity AS '@@identity' ,
            SCOPE_IDENTITY() AS 'SCOPE_IDENTITY()' ,
            IDENT_CURRENT('TestTB1') AS 'IDENT_CURRENT()'

    PS:第一次写blog,写得不好,请各位看官多包涵。多指导

  • 相关阅读:
    顺时针打印矩阵
    topK问题
    9. Palindrome Number(回文数)
    Spinner用法详解
    翻转字符串
    清雨的自助餐(斐波那契数列的应用)
    2. Add Two Numbers(链表尾插法)
    assign和weak的区别
    14-最长公共前缀
    12 13-int与罗马数字转换
  • 原文地址:https://www.cnblogs.com/Gin-23333/p/3988507.html
Copyright © 2011-2022 走看看