SQL2005的“必须声明标量变量”错误

lwd4210 2012-10-21 06:18:26

declare @icount int
declare @sql nvarchar(2000)
set @sql = 'select @icount=count(crmcustomerid) from ' + @tablename + ' where crmcustomerid = ' + cast(@pi_iCrmcustomerId as varchar)
exec sp_executesql @sql,N'@icount int output',@icount output
select @icount as a

if @icount > 0
...........


如上代码是放在一个存储过程里执行的,报“必须声明标量变量 "@icount”错误。
...全文
657 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
lwd4210 2012-11-28
  • 打赏
  • 举报
回复
引用 16 楼 qq576420473 的回复:
引用 6 楼 的回复: 引用 2 楼 的回复: SQL code declare @icount int declare @sql nvarchar(2000) set @sql = 'select '+cast(@icount as varchar(10))+'=count(crmcustomerid) from ' + @tablename + ' where crmcus……
ms-sql里头字符串的拼接符号,不同的数据库定义不同,比如oracle就会用' || '
ChangeMyself2012 2012-10-21
  • 打赏
  • 举报
回复

--测试数据准备
if exists (select 1 from sysobjects where id = object_id('test') and type = 'U')
drop table test

CREATE table test(
id int identity(1,1),
name nvarchar(10)
)

insert into test
select 'aaa' union all
select 'bbb' union all
select 'ccc'

--select COUNT(*) from test
--3

--创建存储过程
if exists (select 1 from sysobjects where id = object_id('printCount') and type = 'p')
drop procedure printCount
go
create procedure printCount
as
begin
declare @icount int
,@sql nvarchar(2000)
set @sql = 'select @icount=count(name) from test'
exec sp_executesql @sql,N'@icount int output',@icount output
if @icount > 0
print isnull(@icount,0)
end

go
exec printCount
--3

----清除测试相关数据
--drop procedure printCount
--drop table test

sql2008 测试通过! 楼主的问题建议楼住把你贴出来的这段脚本的 @sql 变量先print 输出看下
qq576420473 2012-10-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
引用 2 楼 的回复:

SQL code

declare @icount int
declare @sql nvarchar(2000)
set @sql = 'select '+cast(@icount as varchar(10))+'=count(crmcustomerid) from ' + @tablename + ' where crmcustomerid = ' + ……
[/Quote]
大家能告诉我@sql = 'select '+cast(@icount as varchar(10))+'是什么意思吗?为什么要写那两个+加号呢?
开启时代 2012-10-21
  • 打赏
  • 举报
回复
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和

sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC

没有。还有一个最大的优点就是运用 sp_executesql,能够重用执行计划,这就大大

提供了执行性能(对于这个我在后面的例子中会详加说明),还可以编写更安全的代码

。EXEC在某些情况下会更灵活。除非您有令人信服的理由运用 EXEC,否侧尽量运用

sp_executesql.
lwd4210 2012-10-21
  • 打赏
  • 举报
回复

set @sql = 'select @icount=count(crmcustomerid) from ' + @tablename + ' where crmcustomerid = ' + cast(@pi_iCrmcustomerId as varchar)
exec sp_executesql @sql,N'@icount int output',@icount=@icount output
select @icount as a

if @icount > 0
--select @icount as b
begin --如果大于0,表存在则直接更新
set @sql = ''之前没有这一句,导致把上面的SQL也拼到下面来了,所以会报错
set @sql = @sql + 'update '+ @tablename + ' set Customername =''' + @ps_sCustomername +''''
set @sql = @sql + ',MobileNo =''' + @ps_sMobileNo + ''''
set @sql = @sql + ',Customerstatus=''' + @ps_sCustomerstatus + ''''
......


问题解决了,如红色说明部分,今天看来走了很多弯路,一直怀疑是语法写的有问题,没有注意到@sql这个多次使用变量的初始化问题。希望各位注意了,编程是个细活啊。
再次感谢楼上兄弟们的回复。马上结帖
以学习为目的 2012-10-21
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
经过“奋斗熊”的提示,发现点头绪了,在我if @icount > 1后,begin exec(sql)(去掉这个就一切正常了,哪位兄弟能帮忙解释下) end

谢谢各位的回复。
[/Quote]
if @icount > 1后面,直接begin exec(sql)这个肯定会报错的吧
开启时代 2012-10-21
  • 打赏
  • 举报
回复
最好先确定下 是哪个@icount出了问题。
declare @icount int
declare @TI int
declare @sql nvarchar(2000)
set @sql = 'select '+cast(@icount as varchar(10))+'=count(crmcustomerid) from ' + @tablename + ' where crmcustomerid = ' + cast(@pi_iCrmcustomerId as varchar)
exec sp_executesql @sql,N'@icount int output',@icount output
select @icount as a
set @TI=@icount
if @TI> 0
以学习为目的 2012-10-21
  • 打赏
  • 举报
回复
你那个crmcustomerid字段是什么类型?
lwd4210 2012-10-21
  • 打赏
  • 举报
回复
经过“奋斗熊”的提示,发现点头绪了,在我if @icount > 1后,begin exec(sql)(去掉这个就一切正常了,哪位兄弟能帮忙解释下) end

谢谢各位的回复。
lwd4210 2012-10-21
  • 打赏
  • 举报
回复
是吗?我用的是express2005,折腾了一下午,百思不得其解。
开启时代 2012-10-21
  • 打赏
  • 举报
回复
2008里 测试楼主代码 没有任何问题啊
create proc P_TEST
as
declare @tablename varchar(200)='TBA'
declare @icount int
declare @sql nvarchar(2000)
set @sql = 'select @icount=count(a) from ' + @tablename
exec sp_executesql @sql,N'@icount int output',@icount output
select @icount as a
if @icount > 0
print 'OK'
lwd4210 2012-10-21
  • 打赏
  • 举报
回复
很奇怪的是,不要后面的IF那段,储过程完全没有问题,也可以正常输出到@icount的值。
我这个存过的意思就是,执行一个动态的SQL,取到返回值后对返回值进行判断然后处理另外一个逻辑。
lwd4210 2012-10-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

SQL code

declare @icount int
declare @sql nvarchar(2000)
set @sql = 'select '+cast(@icount as varchar(10))+'=count(crmcustomerid) from ' + @tablename + ' where crmcustomerid = ' + ca……
[/Quote]

这样得出的@icount的输出值是空的。还是没有想要的。谢谢了先。
  • 打赏
  • 举报
回复
语法应该没什么错误的。
發糞塗牆 2012-10-21
  • 打赏
  • 举报
回复
如果磊仔的没问题我就不说了
DBA_磊仔 2012-10-21
  • 打赏
  • 举报
回复

declare @icount int
declare @sql nvarchar(2000)
set @sql = 'select '+cast(@icount as varchar(10))+'=count(crmcustomerid) from ' + @tablename + ' where crmcustomerid = ' + cast(@pi_iCrmcustomerId as varchar)
exec sp_executesql @sql,N'@icount int output',@icount output
select @icount as a

if @icount > 0
lwd4210 2012-10-21
  • 打赏
  • 举报
回复
补充一下,去掉 "select @icount as a"后面的内容则不报错,可以确定,后面其它地方没有用到@icount这个变量

34,838

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧