您的位置:新葡亰496net > 网络数据库 > 新葡亰496net:获得插入记录后的ID_MsSql_脚本之家

新葡亰496net:获得插入记录后的ID_MsSql_脚本之家

发布时间:2019-12-10 14:08编辑:网络数据库浏览(90)

    首先看看数据库里面的数据(S_Id为自增长标识列):

    最近在开发项目的过程中遇到一个问题,就是在插入一条记录的后要立即获取所在数据库中ID,而该ID是自增的,怎么做?在sql server 2005中有几种方式可以实现。 要获取此ID,最简单的方法就是在查询之后select @@indentity--SQL语句创建数据库和表复制代码 代码如下:create database dbdemogouse dbdemogocreate table tbldemo( id int primary key identity, name varchargo--执行下面SQL语句就能查出来刚插入记录对应的自增列的值insert into tbldemo values select @@identitySQL Server 2000中,有三个比较类似的功能:SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。 1)IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值,它不受作用域和会话的限制,而受限于所指定的表。 2)@@IDENTITY返回为当前会话的所有作用域中的任何表最后生成的标识值。 3) SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值。SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。@@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。

    用select @@identity得到上一次插入记录时自动产生的ID

    新葡亰496net 1

     源地址:

    SQL Server 返回最后插入记录的自动编号ID最近在开发项目的过程中遇到这么一个问题,就是在插入一条记录的后立即获取其在数据库中自增的ID,以便处理相关联的数据,怎么做?在sql server 2000中可以这样做,有几种方式。详细请看下面的讲解与对比。

    如果你使用存储过程的话,将非常简单,代码如下:SET @NewID=@@IDENTITY

    sql server 中返回上一次插入数据的ID(标识值)有三种方式:

    SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。

    一、要获取此ID,最简单的方法就是:

    说明:

    第一种 @@IDENTITY:

    IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。
    @@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。
    SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值

    create database MyDataBaseuse MyDataBasecreate table mytable,name varchar--执行这个SQL,就能查出来刚插入记录对应的自增列的值insert into mytable valuesselect @@identity

    在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。

    1 insert into Student(S_StuNo,S_Name,S_Sex,S_Height)
    2 values('013','卫庄','男','185');
    3 
    4 select @@IDENTITY        -- 返回 17 
    

    新葡亰496net:获得插入记录后的ID_MsSql_脚本之家,Server重回插入数据的ID和受影响的行数。SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。

    二、三种方式的比较

       在返回插入到表的 @@IDENTITY 列的最后一个值方面,@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数类似。

    @@IDENTITY可以返回当前连接所有范围内插入最后所生成的标识值(包括任何调用的存储过程和触发器)。这个函数不只是可以适用于表。函数返回的值是最后表插入行生成的标识值。比如,现在有一个a表和一个b表,a表插入一条数据并触发 trigger (触发器)为b表插入一条数据,这时@@IDENTITY返回的其实是b表的标识列的值,因为@@IDENTITY它总是获取最后一条变更数据的自增字段的值。@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。

    例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。

    SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。

        @@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。

    第二种 IDENT_CURRENT:

    假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。

    例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。

        IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回任何会话和任何作用域中为特定表生成的标识值。有关更多信息,请参见 IDENT_CURRENT。

    1 insert into Student(S_StuNo,S_Name,S_Sex,S_Height)
    2 values('014','大司命','女','183');
    3 
    4 select IDENT_CURRENT('Student')        --返回 18
    

    @@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。

    假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。

        示例

    IDENT_CURRENT()是一个函数,它有一个参数,它的参数就是指定要返回的标识列的值的表名。

    SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。

    @@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。

    下面的示例向带有标识列的表中插入一行,并用 @@IDENTITY 显示在新行中使用的标识值。

    IDENT_CURRENT()返回为任何会话和任何作用域中的特定表最后生成的标识值, 不受作用域和会话的限制,而受限于指定的表。

    而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分别是这两个表最后自增的值。

    SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。

        INSERT INTO infoclass (infoclass) VALUES ('Accountant')

    第三种 SCOPE_IDENTITY:

    ajqc的实验:(40条本地线程,40 40条远程线程同时并发测试,插入1200W行),得出的结论是:
    1.在典型的级联应用中.不能用@@IDENTITY,在CII850,256M SD的机器上1W多行时就会并发冲突.在P42.8C,512M DDR上,才6000多行时就并发冲突.
    2.SCOPE_IDENTITY()是绝对可靠的,可以用在存储过程中,连触发器也不用建,没并发冲突

    而IDENT_CURRENT 和 IDENT_CURRENT 返回的值分别是这两个表最后自增的值。

        这时我们插入一条记录,下面我们使用语句得到标识值:

    1 insert into Student(S_StuNo,S_Name,S_Sex,S_Height)
    2 values('015','月儿','女','165');
    3 
    4 select SCOPE_IDENTITY()        --返回 19
    

    SELECT   IDENT_CURRENT('TableName')   --返回指定表中生成的最后一个标示值   
    SELECT   IDENT_INCR('TableName')--返回指定表的标示字段增量值
    SELECT   IDENT_SEED('TableName')--返回指定表的标示字段种子值

    ajqc的实验:(40条本地线程,40 40条远程线程同时并发测试,插入1200W行),得出的结论是:

    SELECT @@IDENTITY AS 'Identity'

    新葡亰496net:获得插入记录后的ID_MsSql_脚本之家,Server重回插入数据的ID和受影响的行数。SCOPE_IDENTITY()返回为当前会话和当前作用域中的任何表最后生成的标识值。一个作用域就是一个模块——存储过程、触发器、函数或批处理。

    返回最后插入记录的自动编号
    SELECT IDENT_CURRENT('TableName')
     返回下一个自动编号:   
     SELECT   IDENT_CURRENT('TableName')     (SELECT   IDENT_INCR('TableName'))

    1.在典型的级联应用中.不能用@@IDENTITY,在CII850,256M SD的机器上1W多行时就会并发冲突.在P42.8C,512M DDR上,才6000多行时就并发冲突.2.SCOPE_IDENTITY()是绝对可靠的,可以用在存储过程中,连触发器也不用建,没并发冲突SELECT IDENT_CURRENT --返回指定表中生成的最后一个标示值 SELECT IDENT_INCR--返回指定表的标示字段增量值SELECT IDENT_SEED--返回指定表的标示字段种子值

    我的表infoclass中有个ID字段,它原的值是14插入新的记录后自动产生了值15,因些,上面命令执行后返回值:15。

     

    SELECT @@IDENTITY --返回当前会话所有表中生成的最后一个标示值

    返回最后插入记录的自动编号

        下面说说如何在.net中得到插入记录后的ID值。

    IDENT_INCR 用法:

    插入数据的同时,返回ID值

    SELECT IDENT_CURRENT返回下一个自动编号: SELECT IDENT_CURRENT (SELECT IDENT_INCRSELECT @@IDENTITY --返回当前会话所有表中生成的最后一个标示值

        因为Sqlserver为我们提供了多重查询的功能,这大大方便了我们的工作。请看:

    1 -- IDENTITY(1,1) 第一个参数是表示,自增长的起始值,第二个参数表示自增长的增长量,即一次增长多少
    2 SELECT IDENT_INCR('Student')    -- 返回 1 
    

     

    以上是针对sql server 2000的情况,但是诸如my sql或oracle中如何实现呢?怎么处理呢?本人也在摸索中。。。。如有朋友知道此处理方式,别忘了告之,一同分享!

        Dim sql As String = "INSERT INTO jobs (job_desc,min_lvl,max_lvl) VALUES ('A new job', 25, 100);" & _

    SELECT IDENT_INCR('TableName'),一个参数,'TableName' 表示指定表的表名或视图名。

    前几天在做项目时,遇到插入数据的同时,返回ID值的问题,遂记录如下:

    "SELECT job_id FROM jobs WHERE job_id = @@IDENTITY"

    返回指定表的标识字段的增量值(就是自增值,每插入一条新数值序列增加的数值)。

          插入数据的同时,返回ID值的sql语句。

    Dim cmd As New SqlCommand(sql, cn)

     

          MSSQL:

        上面可以看到,SqlCommand可以执行多条语句,各语句之间用“;"分隔。第一条执行插入,第二条则返回最后插入记录的ID值,因为查询返回的是单列的,并且值也是唯一的,所以可以使用ExecuteScalar获得:

    IDENT_SEED 用法:

               INSERT INTO test2 (aa)   VALUES ('cc')   SELECT @@IDENTITY AS SEQUENCE

    Dim jobId As Integer = CInt(cmd.ExecuteScalar())A

    1 -- IDENTITY(1,1) 第一个参数是表示,自增长的起始值,第二个参数表示自增长的增长量,即一次增长多少
    2 select IDENT_SEED('Student')    --返回 1
    

    新葡亰496net,       MYSQL:

    2. insert into 后获得自动插入的id(select @@identity)

    select IDENT_SEED('TableName'),一个参数,'TableName' 表示指定表的表名或视图名。

              select last_insert_id() as ID from T_D_NM_SHOP_TEMPLET limit 1

     

    返回指定表的标识字段的种子值(即起始值,指定标识列从哪个数值开始)。

            在ibatis中,可以这样配置:

    当运行完插入语句后,执行select   @@identity就可得到自动生成的id

     

          <!--创建任务MYSQL数据库,在MYSQL数据库中,表T_D_QT_TASK中的task_id为自增字段。-->
         <!--在插入数据,返回task_id的插入值的配置文件如下-->
        <parameterMap id="MapTask" class="java.util.HashMap">
        <parameter property="taskgroup_id" jdbcType="varchar"
       javaType="java.lang.Integer" mode="IN" />
       <parameter property="task_name" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
      <parameter property="task_content" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
      <parameter property="test_object" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
      <parameter property="status" jdbcType="varchar"
       javaType="java.lang.Integer" mode="IN" />
      <parameter property="user_id" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
      <parameter property="script_type" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
     </parameterMap>
     <insert id="insertTask" parameterMap="MapTask">
      insert into T_D_QT_TASK (`TASKGROUP_ID` ,`TASK_NAME`
      ,`TASK_CONTENT` , `TEST_OBJECT` ,`PRIORITY`,`STATUS`, `USER_ID`
      ,`SCRIPT_TYPE` ) values(?,?,?,?,'9',?,?,?)
      <selectKey resultClass="java.lang.String" keyProperty="tid">
       select last_insert_id() as TASK_ID from T_D_QT_TASK limit 1
      </selectKey>
     </insert>
    <!--创建任务ORACLE数据库, 在oracle数据库中,表T_D_QT_TASK中的task_id没有设置为自增。-->
    <!--(这样设置我得到的主键返回值总是大于实际插入值),遂取消task_id与触发器的关联。-->
    <!--直接建立一个SEQ:SEQ_D_QT_TASK获取它的返回值,直接插入到表中 .注意配置-->
    <!--中的keyProperty="task_id"。是把seq的返回值,放入到对应的映射中的task_id中-->
     <parameterMap id="MapTask" class="java.util.HashMap">
      <parameter property="task_id" jdbcType="varchar"
       javaType="java.lang.Integer" mode="IN" />
      <parameter property="taskgroup_id" jdbcType="varchar"
       javaType="java.lang.Integer" mode="IN" />
      <parameter property="task_name" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
      <parameter property="task_content" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
      <parameter property="test_object" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
      <parameter property="status" jdbcType="varchar"
       javaType="java.lang.Integer" mode="IN" />
      <parameter property="user_id" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
      <parameter property="script_type" jdbcType="varchar"
       javaType="java.lang.String" mode="IN" />
     </parameterMap>
     <insert id="insertTask" parameterMap="MapTask">
      <selectKey resultClass="java.lang.Integer"
       keyProperty="task_id">
       SELECT SEQ_D_QT_TASK.NEXTVAL AS ID FROM DUAL
      </selectKey>
      insert into T_D_QT_TASK (TASK_ID,TASKGROUP_ID ,TASK_NAME
      ,TASK_CONTENT , TEST_OBJECT ,PRIORITY,STATUS, USER_ID
      ,SCRIPT_TYPE ) values(?,?,?,?,?,'9',?,?,?)
     </insert>

    如果是sql server 最好用select SCOPE_IDENTITY() as id

    sql 获取标识递增的下一个值:

    因为@@identity全局的

    1 --获取当前标识递增的下一个值,即当前标识最大的值的下一个值
    2 select IDENT_CURRENT('Student')   IDENT_INCR('Student')
    

    同类还有IDENT_CURRENT(‘table’)

     

    IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。

    sql 返回受上一语句影响的行数:

    @@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。

    @@ROWCOUNT 返回受影响的行数(insert、select、delete、update):

    SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值

    1 select * from Student where S_Sex='女'
    2 
    3 select @@ROWCOUNT    -- 返回 6
    

    SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。

    如果行数大于 20 亿,请使用 ROWCOUNT_BIG()。

    1 select * from Student where S_Sex='男';
    2 
    3 select ROWCOUNT_BIG()    --返回 9
    

    rowcount 用法:

    rowcount的作用就是用来限定后面的sql在返回指定的行数之后便停止处理,例如下面的示例:

    1 -- 查询出前 5 条数据  
    2 set rowcount 5
    3 select * from Student where S_Sex='男';
    4 
    5 -- 查询出后 5 条数据
    6 set rowcount 5
    7 select * from Student where S_Sex='男' order by S_Id desc;
    

    也就是说在查询上面 rowcount 有着 top [number] 同样的效果。

    要取消set rowcount的限定,只要设置 set rowcount 0 就可以了。

     

    注意:set rowcount的限定对修改,删除一样有效。比如下面的示例:

    1 set rowcount 3
    2 update Student set S_BirthDate='2017-01-01'
    3 where S_Id<20
    4 
    5 select @@ROWCOUNT    --返回 3 
    
    1 set rowcount 5
    2 delete from Student where S_BirthDate is null
    3 
    4 select @@ROWCOUNT    --返回 5
    5 
    6 set rowcount 0
    7 
    8 select * from Student
    

     

    本文由新葡亰496net发布于网络数据库,转载请注明出处:新葡亰496net:获得插入记录后的ID_MsSql_脚本之家

    关键词: