當前位置:首頁 » 編程語言 » sql捕獲錯誤原因
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql捕獲錯誤原因

發布時間: 2022-07-28 14:39:25

❶ 如何在sql存儲過程中處理錯誤

一、存儲過程中使用事務的簡單語法

在存儲過程中使用事務時非常重要的,使用數據可以保持數據的關聯完整性,在Sql server存儲過程中使用事務也很簡單,用一個例子來說明它的語法格式:

CreateProcereMyProcere
(@Param1nvarchar(10),
@param2nvarchar(10)
)
AS
Begin
SetNOCOUNTON;
SetXACT_ABORTON;
BeginTran
Deletefromtable1wherename=』abc』;
Insertintotable2values(value1,value2,value3);
CommitTran
End

說明:

1 、使用存儲過程執行事物,需要開啟XACT_ABORT參數(默認值為Off),將該參數設置為On,表示當執行事務時,如果出錯,會將transcation設置為uncommittable狀態,那麼在語句塊批處理結束後將回滾所有操作;如果該參數設置為Off,表示當執行事務時,如果出錯,出錯的語句將不會執行,其他正確的操作繼續執行。


2、當SET NOCOUNT 為 ON 時,不返回計數(計數表示受 Transact-SQL 語句影響的行數,例如在Sql server查詢分析器中執行一個delete操作後,下方窗口會提示(3)Rows Affected)。當 SET NOCOUNT 為 OFF 時,返回計數,我們應該在存儲過程的頭部加上SET NOCOUNT ON 這樣的話,在退出存儲過程的時候加上 SET NOCOUNT OFF這樣的話,以達到優化存儲過程的目的。

二、事務內設置保存點

用戶可以在事務內設置保存點或標記。保存點定義如果有條件地取消事務的一部分,事務可以返回的位置。如果將事務回滾到保存點,則必須(如果需要,使用更多的 Transact-SQL 語句和 COMMIT TRANSACTION 語句)繼續完成事務,或者必須(通過將事務回滾到其起始點)完全取消事務。若要取消整個事務,請使用 ROLLBACK TRANSACTION transaction_name 格式。這將撤消事務的所有語句和過程。如:

代碼

CreateProcereMyProcere
AS
Begin
SetNOCOUNTON;
SetXACT_ABORTON;
begintranok--開始一個事務OK
deletefromrxqzwhereqz='rx015'--刪除數據
savetranbcd--保存一個事務點命名為bcd
updateszsetname='李麗s'wherename='李麗'--修改數據

if@@error<>0--判斷修改數據有沒有出錯
begin--如果出錯
rollbacktranbcd--回滾事務到BCD的還原點
committranok--提交事務
end
else--沒有出錯
committranok--提交事務
End

說明:1、@@error判斷是否有錯誤,為0表示沒有錯誤,但是對那種重大錯誤無法捕捉,而且@@error只能前一句sql語句生效。

三、存儲過程使用try…catch捕獲錯誤

在存儲過程中可以使用try…catch語句來捕獲錯誤,如下:

CreateProcereMyProcere
(@Param1nvarchar(10),
@param2nvarchar(10)
)
AS
Begin
SetNOCOUNTON;
Begintry
Deletefromtable1wherename=』abc』;
Insertintotable2values(value1,value2,value3);
Endtry
BeginCatch
SELECTERROR_NUMBER()ASErrorNumber,
ERROR_MESSAGE()ASErrorMessage;
EndCatch
End

說明:1、捕獲錯誤的函數有很多,如下:

ERROR_NUMBER() 返回錯誤號。

ERROR_SEVERITY() 返回嚴重性。

ERROR_STATE() 返回錯誤狀態號。

ERROR_PROCEDURE() 返回出現錯誤的存儲過程或觸發器的名稱。

ERROR_LINE() 返回導致錯誤的常式中的行號。

ERROR_MESSAGE() 返回錯誤消息的完整文本。該文本可包括任何可替換參數所提供的值,如長度、對象名或時間。

2、有些錯誤,如sql語句中的表名稱輸入錯誤,這是資料庫引擎無法解析這個表名稱時,所發生的錯誤在當前的try…catch語句中無法捕獲,必須由外層調用該存儲過程的地方使用 try…catch來進行捕獲。

四、存儲過程中事務和try…catch聯合使用

在存儲過程中使用事務時,如果沒有try…catch語句,那麼當set xact_abort on時,如果有錯誤發生,在批處理語句結束後,系統會自動回滾所有的sql操作。當set xact_abort off時,如果有錯誤發生,在批處理語句結束後,系統會執行所有沒有發生錯誤的語句,發生錯誤的語句將不會被執行。

在存儲過程中使用事務時,如果存在try…catch語句塊,那麼當捕獲到錯誤時,需要在catch語句塊中手動進行Rollback操作,否則系統會給客戶端傳遞一條錯誤信息。如果在存儲過程開始處將set xact_abort on,那麼當有錯誤發生時,系統會將當前事務置為不可提交狀態,即會將xact_state()置為-1,此時只可以對事務進行Rollback操作,不可進行提交(commit)操作,那麼我們在catch語句塊中就可以根據xact_state()的值來判斷是否有事務處於不可提交狀態,如果有則可以進行rollback操作了。如果在存儲過程開始處將set xact_abort off,那麼當有錯誤發生時,系統不會講xact_state()置為-1,那麼我們在catch塊中就不可以根據該函數值來判斷是否需要進行rollback了,但是我們可以根據@@Trancount全局變數來判斷,如果在catch塊中判斷出@@Trancount數值大於0,代表還有未提交的事務,既然進入catch語句塊了,那麼還存在未提交的事務,該事務應該是需要rollback的,但是這種方法在某些情況下可能判斷的不準確。推薦的方法還是將set xact_abort on,然後在catch中判斷xact_state()的值來判斷是否需要Rollback操作。

下面我們來看看兩個例子:

一.使用Set xact_abort on

CreateprocmyProcere
As
begin
setxact_aborton;
begintry
begintran
insertintoTestStuvalues('Terry','boy',23);
insertintoTestStuvalues('Mary','girl',21);
committran
endtry
begincatch
--在此可以使用xact_state()來判斷是否有不可提交的事務,不可提交的事務
--表示在事務內部發生錯誤了。Xact_state()有三種值:-1.事務不可提交;
--1.事務可提交;0.表示沒有事務,此時commit或者rollback會報錯。
ifxact_state()=-1
rollbacktran;
endcatch
end

二.使用Set xact_abort off

CreateprocmyProcere
As
begin
setxact_abortoff;
begintry
begintran
insertintoTestStuvalues('Terry','boy',23);
insertintoTestStuvalues('Mary','girl',21);
committran
endtry
begincatch
--在此不可以使用xact_state來判斷是否有不可提交的事務
--只可以使用@@Trancount來判斷是否有還未提交的事務,未提交的事務未必
--就是不可提交的事務,所以使用@@TranCount>0後就RollBack是不準確的
if@@TranCount>0
rollbacktran;
endcatch
end


另外,對於@@Trancount需要說明的是,begin tran 語句將 @@Trancount加 1。Rollback tran將 @@Trancount遞減到 0,但 Rollback tran savepoint_name 除外,它不影響 @@Trancount。Commit tran 或 Commit work 將 @@Trancount 遞減 1。

❷ SQL 跟蹤問題 在 SQL 跟蹤中,如何判斷SQL語句執行是否錯誤。

SQL Server Profiler工具是來捕獲當前執行的SQL語句,並不能反饋執行結果和錯誤信息在查詢分析器窗口執行語句錯誤自然會提示,要知道錯誤語句在哪裡,可以像樓上那種做法,設置一些Print語句,哪裡沒列印錯誤就到哪裡。一般我這邊寫則會定義一個變數用語存放SQL語句,在執行之前加多一句print,這樣執行錯誤就知道語句是那句了如:declare @Sql varchar(2000)set @Sql='select 1'print @Sqlexec(@Sql)set @Sql='update table set abc=124'print @Sqlexec(@Sql)

❸ sql語句的錯誤原因

如果是在access裡面直接執行的話,你的語句應該沒有錯誤,
但如果要在SQL Server裡面達到同樣效果的話,
需要將通配符'*'改為'%',即:
select top 5 c_name,c_stu from class where c_stu>30 and c_type=true and c_name like '%二班%' order by c_stu asc,c_type desc
試試,應該沒有問題

❹ SQL出現錯誤什麼原因

先把原庫文件備份一份,然後
在其它機器上直接附加資料庫,不要日誌文件!試試!如果不行再按以下方法試試!

在其他機器上,用這個試試:
1.設置資料庫為緊急模式
Use Master
GO
sp_configure 'allow updates', 1
reconfigure with override
GO
UPDATE sysdatabases SET status = 32768 where name = 'DB_SUSPECT'
GO

2.停掉SQL Server服務:
NET STOP MSSQLSERVER

3.把原始資料庫的數據文件DBNAME_DAT.MDF,DBNAME_LOG.LDF移走:

4.啟動SQL Server服務:
NET START MSSQLSERVER

❺ 請教CI如何捕獲SQL語句異常

try{
//代碼 代碼中通常會出現不知情卻在情理中的錯誤
int age = a.getAge();//如果a對象為空,你卻調用它的方法就會報NullPointerException異常
}catch(//異常類型 NullPointerException ne){//獲取你可以預知的異常
//異常處理就是你捕獲了這個異常你要這個異常進行哪種操作
//一般的操作就是記錄到日誌里
//然後拋出去或者返回狀態
}catch(Exception ex){//這個是所有異常的父類
//因為很多異常是不可預知的
//記錄到日誌里
//然後拋出去或者返回狀態
}

❻ 你09年問的關於VB捕捉Sql過程中錯誤,錯誤前面有select 語句,就不回報錯

可以啊,比如說exec netFeiPiao 'weq'
執行出錯的話,資料庫會把這個錯誤信息返回回來的。
你只需要在VB中捕獲就可以,vb中應該有個connection吧

connection.errorMsg大概就是這么個意思,具體怎麼寫我不知道,我是搞C++的。

❼ 在SQL Server中如何進行錯誤捕捉

如果在Transact-SQL中發生了錯誤,一般有兩種捕捉錯誤的方法,一種是在客戶端代碼(如c#、delphi等)中使用類似try...catch的語句進行捕捉;另外一種就是在Transact-SQL中利用Transact-SQL本身提供的錯誤捕捉機制進行捕捉。如果是因為Transact-SQL語句的執行而產生的錯誤,如鍵值沖突,使用第一種和第二種方法都可以捕捉,但是如果是邏輯錯誤,使用客戶端代碼進行捕捉就不太方便。因此,本文就如何使用Transact-SQL進行錯誤捕捉進行了討論。 非致命錯誤(non-fatal error)的捕捉 通過執行Transact-SQL而產生的錯誤可分為兩種:致命錯誤(fatal error)和非致命錯誤(non-fatal error)。在Transact-SQL中只可以捕捉非致命錯誤(如鍵值沖突),而無法捕捉致命錯誤(如語法錯誤)。在Transact-SQL中可以通過系統變數@@ERROR判斷最近執行的一條語句是否成功執行。如果發生了錯誤,@@Error的值大於0,否則值為0。下面舉一個例子說明@@ERROR的使用。 假設有一個表table1,在這個表中有兩個欄位f1,f2。其中f1是主鍵。 INSERTINTOtable1VALUES(1,'aa')INSERTINTOtable1VALUES(1,'bb')--這條語句將產生一個錯誤IF@@ERROR0PRINT'鍵值沖突'當執行第二條語句時發生鍵值沖突錯誤,@@ERROR被賦為錯誤號2627,因此輸出結果顯示'鍵值沖突'。使用@@ERROR系統變數時需要注意,@@ERROR只記錄最近一次執行的Transact-SQL語句所發生的錯誤,如果最近一次執行的Transact-SQL沒有發生錯誤,@@ERROR的值為0。因此,只能在被捕捉的那條Transact-SQL語句後使用@@ERROR。 在SQL Server中,不僅可以捕捉系統提供的錯誤,還可以自定義錯誤。有兩種方法可以定義錯誤信息。 1. 使用sp_addmessage系統存儲過程添加錯誤信息,然後使用RAISERROR拋出錯誤。 sp_addmessage將錯誤號,錯誤級別、錯誤描述等信息添加到系統表中,然後使用RAISERROR根據相應的錯誤號拋出錯誤信息。用戶自定義的信息應該從50001開始。EXECsp_addmessage@msgnum=50001, @severity=16,@msgtext='sql encounter an error(%s).',@lang='us_english'EXECsp_addmessage@msgnum=50001, @severity=16,@msgtext='sql遇到了一個錯誤(%1!).'如果使用的SQL Server版本是非英語版本,在添加本地錯誤信息時必須首先添加英文的錯誤信息。錯誤描述可以象c語言中的printf的格式字元串一樣使用參數,如%s、%d。但要注意的是在英文版的錯誤信息中要使用%s、%d等形式,而在本地化的錯誤信息中要使用%1!、%2!等形式,在每個%?(1 <= ? <= n)後需要加一個!,而且%?的數目必須和英文版的錯誤信息的參數一致。 在未插入本地化錯誤信息時,RAISERROR將使用英文版的錯誤信息。當插入本地化錯誤信息時,RAISERROR使用本地化的錯誤信息。 RAISERROR(50001,16,1,'測試') 輸出的結果: 伺服器: 消息50001 ,級別16 ,狀態1 ,行1sql遇到了一個錯誤(測試). 其中'測試'字元串通過%1傳入本地化的錯誤描述字元串中。 2. 直接使用RAISERROR將錯誤拋出。 使用第一種方法雖然使Transact-SQL語句看上去更整潔(這種方法類似於在編程語言中使用常量定義錯誤信息,然後在不同的地方通過錯誤編號引用這些錯誤信息。),但是這樣做卻使錯誤信息和資料庫的耦合度增加,因為如果將這些帶有RAISERROR的Transact-SQL放到別的SQL Server資料庫上執行,由於在其它的資料庫中還未添加錯誤信息,因此會產生RAISERROR調用錯誤,除非使用sp_addmessage將所需的錯誤信息再加入到其它的資料庫中。 基於上述原因,RAISERROR不僅可以根據錯誤代碼拋出錯誤信息,也可以直接通過錯誤描述格式字元串拋出錯誤信息。

❽ 有什麼辦法能捕捉SQL資料庫異常使其不退出對話框

很多方法可以做到
1,資料庫後台寫存儲過程,所有操作資料庫得到均通過存儲過程來進行,在存儲過程里可以用try(sql 2005支持,sql 2000可以判斷語句的返回)來捕獲錯誤,並把錯誤信息返回
2,前台代碼裡面做,和資料庫相關的調用,判斷其返回值,進行過濾處理,或者直接進行try catch捕獲異常,一般前台語言均支持try

❾ 如何捕獲sqlserver資料庫的異常

Result.next()只會在兩種情況發生異常:一是資料庫本身故障,二是已經關閉。
而在你的程序中只是為了防止出現一個異常不影響其它的,那麼可以假定了,前面的訪問是正確的。所以,第一個異常原因不可能出現的。而你不會自己主動在另一個線程關閉資料庫吧?那麼第二個異常原因也不可能出現。
所以,這個異常捕獲了,不必做任何處理,直接進行下一個就行。
while(rs.next()){
try{
//..........
}
catch(SQLException ex){}
}