方法一、是在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. 通过adb命令在Android设备中执行Java命令, 并调用so文件。

    一.难点一:无法复制so文件到/system/lib或者/vendor/lib下,提示只读 解决方法: 2.使用android device monitor放库进入到 /system/lib出现只读权 ...

  2. hadoop Mahout中相似度计算方法介绍(转)

    来自:http://blog.csdn.net/samxx8/article/details/7691868 相似距离(距离越小值越大) 优点 缺点 取值范围 PearsonCorrelation 类 ...

  3. 用 bottle.py 写了个简单的升级包上传

    可以当作一个 demo 来玩吧,在这里分享一下.里面涉及的内容包含了文件上传,cookie 设置和读取,重定向(redirect). from bottle import run, post, get ...

  4. 深入理解JVM(三)——垃圾收集策略具体解释

    Java虚拟机的内存模型分为五个部分.各自是:程序计数器.Java虚拟机栈.本地方法栈.堆.方法区. 这五个区域既然是存储空间,那么为了避免Java虚拟机在执行期间内存存满的情况,就必须得有一个垃圾收 ...

  5. .net通过url访问服务器获取服务器返回数据

    一.url为http协议 1.普通调用: public string GetInfo(string url) { //访问http方法 string strBuff = ""; U ...

  6. scala 几个函数小例子

    后续补充 /** * Created by dengy on 2017/12/18. */ object grammarPractise { def main(args: Array[String]) ...

  7. Oracle11gR2

    oracel目前企业用的最多的数据库,源码包值得下载 点击下载 安装引用: http://blog.csdn.net/cafardhaibin/article/details/25071249 htt ...

  8. rtl-sdr在win7和ubuntu16.04的安装

    硬件准备 RTL2832+R820T2 usb dongle x 1 Long wire antenna x 1 USB电视棒的购买: 在淘宝上搜索"软件无线电"或"rt ...

  9. CPP复习笔记 3

    --------------- CPP函数编译原理和成员函数的实现 从上节的分析中能够看出.对象的内存中仅仅保留了成员变量,除此之外没有不论什么其它信息,程序运行时不知道 stu 的类型为 Stude ...

  10. 【laravel5.4】php artisan 常用命令

        路由缓存:/www/wd***/php/bin/php artisan route:cache 查看全部路由并输出到txt文件:/www/wd***/php/bin/php artisan r ...