因專案需要,在儲存過程中做容錯處理,使資料操作異常時程式仍然可以繼續執行,所以在思考這個問題,經測試後才發現的異常處理真的很弱。
所以把錯誤處理完全交給儲存過程是不可能的,還是要配合呼叫程式的錯誤處理功能才能完成.
sql2005中新增try ... catch ... 也是如此,出現嚴重錯誤時一樣無法捕獲。
以下是引用鄒大哥的測試示例:
--演示1
--測試的儲存過程1
create proc p1
as
print 12/0
if @@error<>0
print '發生錯誤1'
select * from newid()
if @@error<>0
print '發生錯誤2'
go
--呼叫
exec p1
go
--刪除測試
drop proc p1
/*--測試結果
伺服器: 訊息 8134,級別 16,狀態 1,過程 p1,行 6
遇到被零除錯誤。
發生錯誤1
伺服器: 訊息 208,級別 16,狀態 1,過程 p1,行 10
物件名 'newid' 無效。
--*/
/*--結論1:
錯誤1,不是嚴重的錯誤,所以sql會執行下去
錯誤2,屬於嚴重的錯誤,所以sql沒有執行下去,因為沒有第二個print的結果
--*/
--演示2,儲存過程巢狀呼叫中的錯誤
--測試的儲存過程1
create proc p1
as
print 12/0
if @@error<>0
print '發生錯誤1'
select * from newid()
if @@error<>0
print '發生錯誤2'
go
--測試的儲存過程2
create proc p2
as
exec p1
if @@error<>0
print '呼叫 儲存過程1 異常結束'
else
print '呼叫 儲存過程1 正常結束'
go
--呼叫
exec p2
go
--刪除測試
drop proc p1,p2
/*--測試結果
伺服器: 訊息 8134,級別 16,狀態 1,過程 p1,行 8
遇到被零除錯誤。
發生錯誤1
伺服器: 訊息 208,級別 16,狀態 1,過程 p1,行 12
物件名 'newid' 無效。
呼叫 儲存過程1 異常結束
--*/
/*--結論2:
被呼叫的儲存過程發生嚴重錯誤時,呼叫它的儲存過程可以捕獲錯誤,並可以繼續執行下去
--*/
--演示3,更嚴重的錯誤,無法用 set xact_abort on 來自動回滾事務
set xact_abort on --我們希望能自動回滾事務
begin tran
create table #t(id int)
insert #t select 1
select * from newid()
commit tran
go
select * from #t
rollback tran
/*--測試結果
(所影響的行數為 1 行)
伺服器: 訊息 208,級別 16,狀態 1,行 5
物件名 'newid' 無效。
id
-----------
1
(所影響的行數為 1 行)
--*/
/*--結論3:
我們希望 set xact_abort on 可以實現出錯時自動回滾事務
但結果令我們希望,出錯時,事務並沒有被回滾
因為我們查詢到了#t的結果,而且最後的回滾語句也並沒有報錯
--*/
強名稱(3)強名稱的脆弱性
通過前文共同體驗了強名稱對程式集的保護方式和原理,但是這種保護的強度到底有多大呢?能有效地防禦惡意篡改者嗎?先看下面的例子。回到上篇文章的 清單 9 7,重新對 strongnamereferencelib 專案進行強名稱簽名,然後編譯 strongname 專案。在 strongname 專案的b...
勒索病毒暴露了網路安全的脆弱性
日前,一款叫做wannacry的病毒在全球範圍內快速爆發,被這款病毒攻擊的計算機的幾乎所有檔案都將被加密鎖定。全球150多個國家的網路被攻擊。中英兩國受害最為嚴重,英國的nhs服務受到了大規模的網路攻擊,至少40家醫療機構內網被黑客攻陷。在中國,北京 上海 江蘇 天津等多地的出入境 派出所等公安網也...
自然角度論有機體的反脆弱性
最近看了黑天鵝的作者的反脆弱性一書,突然有了個想法,解釋我們的世界。人類具有反脆弱性,什麼是反脆弱性,比如,你打疫苗,打部分病毒,毒量比較小,但是身體產生了抗性。比如,你在工廠天天搬重物的工作,身體很累,但是身體產生了適應性,你的肌肉開始增長。脆弱性,也就是你在溫和的場所,懶散,閒得慌,舒適,無壓力...