最近開發寫存儲過程的時候碰到一個問題。應用場景為:后台展示數據列表,進行查詢的時候,執行存儲過程報錯:必須聲明標量變量“@xxxx”
由於上家公司都是用的orm框架,很少寫原生的sql,所以把它記下來,慢慢積累經驗。
1-數據庫表設計如下
表名:UserInfo(ID, UserName, UserDept)。
2-存儲過程為將列表進行分頁展示,但是由於自己沒有看懂那個分頁的存儲過程(不想誤導別人),就把他簡化了一下,看懂了再整理一篇博客出來。
簡化成了展示所有的用戶,可以根據UserName查詢
ALTER PROCEDURE [dbo].[p_userinfo_list] @username varchar(50) = '' as set nocount on set transaction isolation level read uncommitted set xact_abort on DECLARE @sql nvarchar(1024) if @username != '' set @sql = 'select * from t_userinfo where username=@username' --錯誤寫法 --set @sql = 'select * from t_userinfo where username = '''+ convert(varchar, @username)+ '''' 正確寫法 else set @sql = 'select * from t_userinfo' exec sp_executesql @sql
執行存儲過程:
exec p_userinfo_list '用戶1',報錯:
查了資料把where條件改進了一下:set @sql = 'select * from t_userinfo where username = '''+ convert(varchar, @username)+ ''''
再執行存儲過程,可以顯示成功。
but: 那些分號看了半天沒看懂,就請教了同事,理解如下:
'select * from t_userinfo where username = '''+ convert(varchar, @username)+ ''''
看最開頭'select XXXX'
然后再看中間的 xxx where username=''' (這里有三個'), 最后一個( ' ) 和 開頭的( 'select ) 閉合,前面兩個( '' ),第一個 ( ' ) 代表轉義,將后面的 ( ' )轉義成真正的 ( ' ) 《==》 最后分析這條sql最后的那4個( ' ) , 首尾兩個'閉合,中間兩個’和前面一樣轉義
所以真正到這個字符串拼接了以后,生成的字符串是 :
select * from t_userinfo where username = 'convert(varchar, @username)' ,這樣理解了么。
這個和js里面拼接html代碼是一樣的原理
比如:
var temp = 11;
var html = "<div class='container' onclick='add(\'"+temp+"\')'>";
"\'", \ 代表轉義,其實本質是一樣的,只不過是用的不同的語言。技術都是相通的。
還有一種報錯情況就是: 不存在列xxx(或者是說列名無效),就是sql會把你傳入的參數,看成一個列名,這時候可能也需要通過''進行轉義,大概就是這樣。
ps:google好像有時候圖片打不開,火狐,360可以打開,其他的沒試過。
以上文章如有錯誤,誤導了您,請及時指出,歡迎批評。