zoukankan      html  css  js  c++  java
  • C#中自动增量字段值的获取方法

        由于系统需要在使一个整形字段值加1之后立刻获得该字段的值,如果不考虑并发的情况,这个问题非常简单,可以使用两条SQL语句来实现,先Update 表 set 字段=字段+1 where clause,然后再Select 字段 where clause。但是现在几乎不可能不存在并发更改数据的情况,因此使用两条SQL就有可能导致同时访问这段代码的不同客户端会获取错误数据,因此在并发情况下如何控制记录的连贯更新、读取访问是一个问题。类似的问题有如何获取Identity列的新增值,参见我之前的一个文档:http://www.cnblogs.com/badwood316/archive/2007/09/01/877876.html
        解决这个问题的方法有很多种,可以锁定表记录、可以使用事务、使用select ... for update等,但都不是很简洁。今天在网上搜到一篇文章,是利用触发器来实现的,又学到了一手:http://hi.baidu.com/2hill/blog/item/dbc9dd135e5b4dd2f7039ec0.html
        他的方法是在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语句来实现自增一个字段并取回自增前/后的值。
        需要注意的是文章中指出在触发器中可以返回一个记录集,但是不支持大量的输出文本,这一点比较含糊,何为大量?文本又是指何种字段?
        最后,结合上面所说,给出自己的代码:
        先是C#代码,其中的db.GetDs()函数是返回sql执行后的数据集(DataSet对象),其函数的代码见我之前的文章,而此处其实是把update语句作为一个select对待,可以获取其结果集。同时,还可以获得update执行所影响到的行数,这个就需要通过SqlCommand对象的ExecuteNonQuery()函数了,此处不再介绍。
    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 2000的数据库,但不知道Oracle数据库是否也能这样支持,需要进一步考证。
  • 相关阅读:
    LwIP源代码文件目录解析
    规划2014!
    test
    111
    df
    第一次北京之行
    Android02--debug.keystore的注册信息
    Android01--开发环境搭建
    dfd
    1007
  • 原文地址:https://www.cnblogs.com/badwood316/p/970599.html
Copyright © 2011-2022 走看看