SqlServer 执行存储过程 必须声明标量变量 "@xxxx"
最近开发写存储过程的时候碰到一个问题。应用场景为:后台展示数据列表,进行查询的时候,执行存储过程报错:必须声明标量变量“@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可以打开,其他的没试过。
以上文章如有错误,误导了您,请及时指出,欢迎批评。转载请注明出处。