儲存乙個記錄到資料庫又馬上返回ID號

2021-05-25 06:38:42 字數 2732 閱讀 5292

有的時候我們需要取得剛新增記錄的id值,很多人都說用"select top 1 id from tablename order by id desc",這種方法大部分情況下是可行的,為什麼是大部分呢?當資料庫更新非常頻繁時,可能你在執行insert後select前其他人也新增了新記錄,那返回的值就不準確了。

在一條   insert、select   into   或大容量複製語句完成後,@@identity   中包含此語句產生的最後的標識值。若此語句沒有影響任何有標識列的表,則   @@identity   返回   null。若插入了多個行,則會產生多個標識值,@@identity   返回最後產生的標識值。如果此語句激發乙個或多個執行產生標識值的插入操作的觸發器,則語句執行後立即呼叫   @@identity   將返回由觸發器產生的最後的標識值。若   insert   或   select   into   語句失敗或大容量複製失敗,或事務被回滾,則   @@identity   值不會還原為以前的設定。   

在返回插入到表的   @@identity   列的最後乙個值方面,@@identity、scope_identity   和   ident_current   函式類似。     

@@identity   和   scope_identity   將返回在當前會話的所有表中生成的最後乙個標識值。但是,scope_identity   只在當前作用域內返回值,而   @@identity   不限於特定的作用域。  

ident_current   不受作用域和會話的限制,而受限於指定的表。ident_current   返回任何會話和任何作用域中為特定表生成的標識值。有關更多資訊,請參見   ident_current。  

示例  

下面的示例向帶有標識列的表中插入一行,並用   @@identity   顯示在新行中使用的標識值。  

insert   into   jobs   (job_desc,min_lvl,max_lvl)  

values   ('accountant',12,125)  

select   @@identity   as   'identity'

就是用這種插入馬上又查詢,立即返回id,一樣是可以的,不管你的軟體是不是網路版,不管有多少的客戶端同時操作同乙個表,返回來的id不會有錯。因為這些我都測試過。sqlserver還是挻牛b的,哈哈。。

這個問題的原意的是這樣的:

資料表中,主鍵為自增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)

這樣就可以了;

看來觸發器還是蠻好玩的喲;

怎樣執行儲存過程,返回乙個記錄集和乙個返回值?

create procedure aaaa ret int output as select from table1 set ret 0 go 怎麼同時取到select的結果和 ret的返回值呢 cmd new sqlcommand aaaa conn cmd.commandtype command...

乙個資料庫儲存過程小問題

這個資料庫建立沒有什麼難度,但是我就是陷入了一種錯誤的思維,一直跳不出來,剛剛靈光一現,跳出迴圈,終於跳出錯誤的模式,構建好了乙個資料庫儲存過程。1 建立乙個儲存過程no grade,顯示有所選課程沒有成績的學生的學號 姓名 所選全部課程名稱及其成績。use stu cou go create pr...

資料庫 乙個題目

求至少用了 商 s1 所 的全部零件的工程號 的兩種解法 這個問題存在歧義,博主的是一種理解,我的理解是選擇的工程嚴格地用了 商 s1 所 的全部零件,且這些零件不是由其他 商 的。select distinct jno from select jno from spj where sno s1 a...