首页 > 技术文章 > SqlServer 执行存储过程 必须声明标量变量 "@xxxx"

stephenzengx 2019-05-05 14:34 原文

最近开发写存储过程的时候碰到一个问题。应用场景为:后台展示数据列表,进行查询的时候,执行存储过程报错:必须声明标量变量“@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可以打开,其他的没试过。

 以上文章如有错误,误导了您,请及时指出,欢迎批评。转载请注明出处。

推荐阅读