方法一、是在Insert或Update触发器中用select来返回需要的字段值。默认情况下,当insert时,触发其insert触发器,它的默认返回值是影响到的行数,语句是:select @@rowcount。如果利用insert和update触发器中的一个技巧,那就是“当insert时,数据库会生成一个临时表,就是inserted表;这个表会记录刚刚要插入的信息,insert完,它就消失了,我们只需select art_id from inserted就会返回刚刚插入的这条记录的art_id了”。同理,“在update时,会生成deleted与inserted两个临时表,一个是修改前数据,一个是修改后数据;我们只需在update触发器写一条select * from inserted就可以了(返回修改后的记录)”。那么就可以轻松的用一条insert或update语句来实现自增一个字段并取回自增前/后的值。
    需要注意的是文章中指出在触发器中可以返回一个记录集,但是不支持大量的输出文本,这一点比较含糊,何为大量?文本又是指何种字段?

1sql = "update tbProcesses set Process_lastno=Process_lastno+1 where Process_id=" + long.Parse(processid);
2long sn = long.Parse(db.GetDs(sql).Tables[0].Rows[0]["Process_lastno"].ToString());

然后是tbProcesses表的Update触发器:

1CREATE TRIGGER tr_U_returnLastNO ON [dbo].[tbProcesses] 
2FOR UPDATE
3AS
4select Process_lastno from inserted
5

说起来似乎有些复杂,但是实现还是蛮简单的,尤其是一步到位,不需要用到锁和事务。

方法二:

在SQL Server中identity列是自动增量的列,每次插入新的列时该列会自动填入新的唯一值,在许多应用中需要在插入一条记录的之后获得刚插入记录的identity列的值,许多网站介绍了在插入后立刻执行@@identity等值即函数的查询,但是那都是在同一个session下的T-SQL,在一个存储过程中是可以用的,但是在C#中,如果用SqlDataAdapter的Fill方法来做就比较麻烦了。今晚尝试了一下,在系统特定需求下实现了获取identity列的新增值。

1            string sql = "insert into tbUsers(User_loginname,User_password,) values(";
2            sql += "'" + LogName + "'";
3            sql += ",'" + Password + "'";
4            sql += ")";
5            DataSet ds = oDB.GetDs(sql + ";select SCOPE_IDENTITY() as id");
6                string id = ds.Tables[0].Rows[0]["id"].ToString();

其中第5行的GetDs函数如下:

1        public DataSet GetDs(string str_Sql) 
2        {
3            Open();
4            SqlDataAdapter Ada = new SqlDataAdapter(str_Sql,cn);
5            DataSet ds = new DataSet();
6            Ada.Fill(ds);
7            cn.Close();
8            return ds;
9        }

此外,SCOPE_IDENTITY功能类似的还有IDENT_CURRENT 和 @@IDENTITY,因为它们都返回插入到 IDENTITY 列中的值。 
            IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。有关更多信息,请参见 IDENT_CURRENT。
            SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。

网上文章参考:

这个问题的原意的是这样的:
数据表中,主键为自增id,例如
[Art_Id] int IDENTITY(1,1) NOT NULL
当insert进入一条新记录时,返回这条新记录的art_id,前提是用一条sql语句,(如是用两条语句就不用讨论了,呵呵);

这个问题是一些公司的面试题,我来公司时,也被问到这个问题,我说不会,呵呵;

关于这个问题,我在网上搜了一下,没有太仔细的看,大多数是说不可能,或是用存储过程来解决(存储过程中也是写两句),我也没去深究,后来在工作中碰到这个问题了,研究了一下,得了一个方法,可以用一条insert语句来返回其当前记录的自增id,只是不知道这是不是最合格的答案。拿出来大家讨论讨论。

我用的数据库是Sql Server 2005;

利用了触发器;我在器发器中写一条sql语句;以后,每次insert就可以返回其id了,高手们估计已经猜到什么方法了;其实我这个方法也没有什么高明的,毕竟触发器是个特殊的存储过程罢了;

我还是先说一下我的思路吧;
大家都知道触发器这个玩意,默认情况下,当insert时,触发其insert触发器,它的默认返回值是影响到的行数,语句是:select @@rowcount;
而当insert时,数据库会生成一个临时表,就是inserted表;这个表会记录刚刚要插入的信息,insert完,它就消失了,我们只需………
select art_id from inserted
就会返回刚刚插入的这条记录的art_id了;
大伙明白了吧,呵呵,是不是很简单;

写好了触发器,以后,我们只需insert into ……就可以了,它返回的值将不再是影响到的行数,而是当前记录的自增id了;

我这个方法,实现了一条Insert语句返回其自增id,但不是一条sql语句,因为在触发器里,多写了一条语句;不知道有没有更好的办法;

当我用了这个方法后,我又想到别一个可利用的地方,就是我们显示文章时,要使文章增加一次浏览量,一般会先select出单条文章,然后再update该文章的浏览量的字段,使其加一;这要两条语句实现;如何用一条语句实现呢,很简单啦,用update触发器喽;

思路是,在update触发器中写select语句,然后,在执行时,只需使用修改浏览量的语句,就会返回当前修改的记录,我把这条记录显示到程序中就行了,就实现了新闻的显示与浏览量加一。

不过要说明一下下了,update的操作,在数据库中,其实是删除记录,然后再增加记录,也就是说,在update时,会生成deleted与inserted两个临时表,一个是修改前数据,一个是修改后数据;
我们只需在update触发器写一条select * from inserted就可以了(返回修改后的记录),以后,update时,让文章的浏览数加一时,直接返回了这个文章,呵呵,不错吧;

但是,报错了,select * from inserted这条语句报错,看看为什么,原来它不支持大量的文本输出,而前面取id时,是select art_id from inserted,它只返回一个或一组数字,而现在是返回整篇文章;没办法呀,只好修正一下喽select * from article where art_id in (select art_id from inserted)
这样就可以了;

看来触发器还是蛮好玩的哟;

不过触发器还是慎用为好,例如上面的文章显示,所有的修改操作都会触发它的update触发器,而很多时候,例如编辑文章时,我们无需返回当前记录,只是在显示文章时需要返回罢了,这个问题,在使用时根据具体情况采用吧。

增加一条新记录,同时返回其自增id的更多相关文章

  1. mapper文件中“添加一条新数据并返回此数据的ID(主键)”的方法

    在mapper文件的insert语句前加上<selectKey>标签即可 如下: 添加前测试: 添加后测试:

  2. oracle中plsql练习题----查询姓为“SMITH”的员工信息,并输出其员工号、姓名、工资、部门号。 – –如果该员工不存在,则插入一条新记录,员工号为2012,员工姓名为“Smith”,工资为7500元,入职日期为“2002年3月5日”,部门号为50。 – –如果存在多个名“Smith”的员工,则输出所有名为“Smith”的员工号、姓名、工资、入职日期、部门号L。

    一.思路:首先判断这个查询的是emp表,需要接收值,声明一个rowtype类型接收数据即可,第二是,存在exception,需要处理,exception中有两种异常,分别处理即可,分别输出即可. 二. ...

  3. C#运用存储过程新增一条记录并返回自动生成的ID

    @Hcy黄灿奕:http://blog.sina.com.cn/iihcy 前言: 1.存储过的好处: 存储过程相对于其他的数据库访问方法有以下的优点: (1)重复使用.存储过程可以重复使用,从而可以 ...

  4. 【MyBtis】获取数据插入postgresql后返回的自增id

    问题描述 数据库采用的是postgresql,以下面的rule表为例,该表的id设置为自增,那么经常有这样的需求,在执行insert操作后,紧接着需要获取该记录的自增id往中间表中插入数据,或者是再根 ...

  5. Mybatis插入记录并返回MySQL自增主键

    mapper Integer insertConfigAndGetId(CrawlerConfig config); xml <insert id="insertConfigAndGe ...

  6. MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)

    测试缘由 一个开发同事做了一个框架,里面主键是uuid,我跟他建议说mysql不要用uuid用自增主键,自增主键效率高,他说不一定高,我说innodb的索引特性导致了自增id做主键是效率最好的,为了拿 ...

  7. Mybatis使用generatedKey在插入数据时返回自增id始终为1,自增id实际返回到原对象当中的问题排查

    今天在使用数据库的时候,遇到一个场景,即在插入数据完成后需要返回此数据对应的自增主键id,但是在使用Mybatis中的generatedKey且确认各项配置均正确无误的情况下,每次插入成功后,返回的都 ...

  8. 【mybatis】mybatis中insert操作,返回自增id

    需求是这样的: mybatis中insert操作,返回自增id,因为这个自增id需要给后续业务用到. 原本是这样的: 将insert语句传入,正常执行insert操作,返回int永远是 0[失败] 或 ...

  9. mybatis关联查询,查询结果多条,却只返回一条记录

    原因是:主表和子表的主键字段相同,可以使用别名!这是因为mybatis的内部实现机制决定的: MyBatis为了降低内存开销,采用ResultHandler逐行读取的JDBC ResultSet结果集 ...

随机推荐

  1. 1051: 手机(MOBILE)

    #include <iostream> #include <iomanip> #include <cstdlib> #include <string> ...

  2. oj

    https://github.com/zhblue/hustoj insert into privilege(user_id,rightstr) values('wxy','administrator ...

  3. http-server使用

    https://segmentfault.com/q/1010000003926981

  4. 架构师速成7.3-devops为什么非常重要

    evops是一个非常高大上的名字,事实上说的简单点就是开发和运维本身就是一个团队的,要干就一起把事情干好.谁出了问题,站点都不行. 作为一个架构师.必需要devops,并且要知道怎样推行devops. ...

  5. 算法笔记_232:提取拼音首字母(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 在很多软件中,输入拼音的首写字母就可以快速定位到某个词条.比如,在铁路售票软件中,输入: “bj”就可以定位到“北京”.怎样在自己的软件中实现这个功 ...

  6. js 树结构数据遍历条件判断

    代码: /** * 树结构数据条件过滤 * js 指定删除数组(树结构数据) */ function filter (data, id) { var newData = data.filter(x = ...

  7. Linux文件的软链接和硬链接

    1.Linux链接概念 Linux链接分两种,一种被称为硬链接(Hard Link).还有一种被称为符号链接(Symbolic Link).默认情况下.ln命令产生硬链接. 1.1索引节点 索引节点是 ...

  8. 解决 ERROR in native method: JDWP No transports initialized, jvmtiError=AGENT_ERROR_TRANSPORT_INIT(197)

    在/etc/hosts文件中加入下面一行内容 127.0.0.1 localhost.localdomain localhost

  9. 【Java多线程】线程同步方法概览

    一:使用syncrhoized内置锁实现同步 使用互斥来实现线程间的同步,保证共享数据在同一时刻只被一个线程使用.Java中最基本的互斥手段就是syncrhoized关键字. syncrhoized的 ...

  10. jqGrid遍历所有行及获取某一行数据

    $("#gridTable").find("tbody tr").not(".jqgfirstrow").each(function (i) ...