iT邦幫忙

0

檢查sql指令是否正確的語法

我寫了一個方法,透過傳遞參數的方法,去做刪除資料的動作,想詢問是否有檢查sql指令是否正確的語法,或是相關方法呢?

if object_id(N'DeleteItem') is not null 
	drop procedure DeleteItem
go

create procedure DeleteItem
	@delete nvarchar(255)=null
	, @from nvarchar(255)=null
	, @where nvarchar(255)=null
as
begin
	
	set nocount on

	declare @query nvarchar(max)=N'
		delete ' +
		iif(@delete is not null, @delete, '') +
		iif(@from is not null, ' from ' +@from, '') +
		iif(@where is not null,' where '+ @where, '') +
		' ;'
	
    --print @query;
    
	--請問這邊有辦法先檢查@query是否正確再做執行嗎?
    --執行
    exec sp_executesql @query;

end
go

2019/12/27 更新 : try catch 或是 transcation 都可以達到目標,邦友們提供的都很有幫助,所以最後選擇我實作的方式為最佳答案,謝謝大家的幫忙~

1
tw70126_tw
iT邦新手 5 級 ‧ 2019-12-23 13:08:33
最佳解答

用transcation包起來
有錯ROLLBACK
對就COMMIT

anniecat iT邦新手 3 級 ‧ 2019-12-23 14:23:27 檢舉

謝謝你的幫忙,這個方式我比較沒有看過,看了一下這個用法,對於多個交易(sql語法)若使用這個方法是比較保險的,因為只要有一個交易錯誤,整個交易就會回復到執行前,我再試試看!

/images/emoticon/emoticon01.gif

2
ckp6250
iT邦研究生 3 級 ‧ 2019-12-20 17:33:11

用 TRY...CATCH
可行乎 ?

player iT邦大師 1 級 ‧ 2019-12-20 17:42:39 檢舉
anniecat iT邦新手 3 級 ‧ 2019-12-23 14:19:16 檢舉

先謝謝你們的幫忙~嘗試過後,try catch是可行的!

1
player
iT邦大師 1 級 ‧ 2019-12-20 17:39:46

T-SQL有個變數 @@ROWCOUNT 是你最後下的SQL指令的影響資料筆數, 只要判斷這個變數是不是大於0, 就應該知道你最後下的SQL指令有沒有正常工作了, 如果為0再去查變數 @@ERROR

https://docs.microsoft.com/zh-tw/sql/t-sql/functions/rowcount-transact-sql?view=sql-server-ver15

https://docs.microsoft.com/zh-tw/sql/t-sql/functions/error-transact-sql?view=sql-server-ver15

anniecat iT邦新手 3 級 ‧ 2019-12-23 14:36:05 檢舉

有看了一下這個方式,@@ROWCOUNT是去看資料的影響筆數,而@@ERROR則是看陳述式沒有發現任何錯誤,不過這個要檢查的精細一點,因為當影響筆數是0,就要把這個部分在另外寫出來,因為有可能沒有符合where條件而影響筆數為0,但其實本身語法是沒有錯的,很謝謝你的幫忙,我會再試試看把這兩個語法結合try catch~

1
純真的人
iT邦高手 1 級 ‧ 2019-12-20 17:42:09

你玩玩..

Begin Try
	Declare @SQL1 nvarchar(Max)='print ''列印ok''';
	Exec master.dbo.sp_executesql @SQL1;
End Try
Begin Catch
	Print N'SQL錯誤:' + Error_Message()
End Catch

Begin Try
	Declare @SQL2 nvarchar(Max)='xxx select 1';
	Exec master.dbo.sp_executesql @SQL2;
End Try
Begin Catch
	Print N'SQL錯誤:' + Error_Message()
End Catch

https://ithelp.ithome.com.tw/upload/images/20191220/2006136938OiuAQnIm.png

anniecat iT邦新手 3 級 ‧ 2019-12-23 14:20:35 檢舉

先謝謝你的幫忙~有嘗試過try catch是可行的!

1
PPTaiwan
iT邦新手 4 級 ‧ 2019-12-22 23:00:52

想請問!! 你都己經使用了 Create Procedure 為何還要透過傳 "檢查 SQL 來檢查語法的正確性?"

建立預存程式並建立時 SQL Server Management 會檢查是否有問題??

anniecat iT邦新手 3 級 ‧ 2019-12-23 14:15:25 檢舉

謝謝你的回覆,在嘗試過後,發現其實在傳參數進此Procedure執行時,若程序執行有問題,是會跳出error訊息的,只是再思考這部分是否是直接執行再報錯,而不是先檢查再報錯,查了一下資料,發現可能是前者,若是這樣的話,使用上面邦友提供的try catch就是比較好的手法
不知道我的理解有沒有對> <

PPTaiwan iT邦新手 4 級 ‧ 2019-12-26 19:07:11 檢舉

嗯!! 因為我將大量將 TSQL 邏輯都寫成 SP ,我倒是很少使用 Try catch 只用 Transction 來執行其 INSERT OR DELETE 等等。

用了 Error_Number() , XACT_State 等相關來做到 Rollback , Commit 用 Viausl Studio 來編輯 SP 等等可以減少不必要的錯誤

0
小名
iT邦新手 5 級 ‧ 2019-12-24 14:07:36

想請教一下,請問TRY CATCH內可以這樣呈現嗎? TRY時候一次包含多個BEGIN END
因為沒看過別人這樣用過想要確認一下。
BEGIN TRY
BEGIN END
BEGIN END
END TRY
BEGIN CATCH
BEGIN END
BEGIN END
END CATCH
謝謝。

anniecat iT邦新手 3 級 ‧ 2019-12-24 14:22:45 檢舉

我也沒看過耶,只不過為什麼你會有這樣的疑問呢?
正規的寫法應該是長這樣

BEGIN TRY  
     { sql_statement | statement_block }  
END TRY  
BEGIN CATCH  
     [ { sql_statement | statement_block } ]  
END CATCH  
[ ; ] 
小名 iT邦新手 5 級 ‧ 2019-12-24 15:10:35 檢舉

假如處理的東西比較多的話,用TRY CATCH會看得很雜 ,所以就試了能不能我說的方法這樣弄,目前用是可行,可以抓錯誤與成功執行,只是文章這段話 [TRY...CATCH 建構不能跨越多個 Transact-SQL 陳述式區塊。 ] 讓我疑惑能不能這樣使用,還是我誤會意思? 新手還在學習中,謝謝指教!

anniecat iT邦新手 3 級 ‧ 2019-12-24 17:49:58 檢舉

請問有範例可以看嗎?因為單看敘述,我不太清楚你這樣使用是怎麼去使用呢?
如果你是詢問裡面可不可以放if判斷式,是可以的。

我要發表回答

立即登入回答