首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

存储过程,必须声明标量变量有关问题

2012-02-08 
存储过程,必须声明标量变量问题各位朋友以下是我写的一个存储过程分页方法,能够编译通过,但是在使用时,老

存储过程,必须声明标量变量问题
各位朋友
以下是我写的一个存储过程分页方法,能够编译通过,但是在使用时,老是提示“消息   137,级别   15,状态   1,第   1   行
必须声明标量变量   "@TotalCount "。”请看
CREATE   PROCEDURE   Pagination
@TotalCount   INT   OUTPUT,
@TotalPage   INT   OUTPUT,
@Table   NVARCHAR(25),   --将要查询的表名
@Column   NVARCHAR(150),--将要查询的字段,可多列
@OrderColumn   NVARCHAR(50),   --排序字段
@CountColumn   NVARCHAR(20),   --取这个字段的最大值
@PageSize   INT,--分页大小
@CurrentPage   INT,   --要查询的页
@OrderType   NVARCHAR(4),--如何排序
@Condition   NVARCHAR(200)   --查询条件
AS
DECLARE   @PageCount   INT,
@strSql   NVARCHAR(500),
@strCount   NVARCHAR(100)
SET   @PageCount=@PageSize*@CurrentPage
BEGIN
IF   @Condition!= 'NO '
BEGIN
SET   @strCount= 'SELECT     @TotalCount=COUNT(*)   FROM   '+   @Table   +   '   WHERE   '+@Condition
SET   @TotalPage=CEILING(str(@TotalCount/@PageSize))
SET   @strSql= 'SELECT   TOP   '+   str(@PageSize)   + '   '+   @Column   + '   FROM   '+   @Table   +   '  
WHERE   '   +   @CountColumn   +   '> (SELECT   MAX( '+   @CountColumn   + ')  
FROM   (SELECT   TOP   '   +   str(@PageCount)+ '   '+   @CountColumn+ '  
FROM   '   +   @Table   +   '   ORDER   BY   '   +   @CountColumn   + ')   AS   T)   AND   '+   @Condition   +   '   ORDER   BY   '   +   @OrderColumn   + '   '+   @OrderType
END
ELSE
BEGIN
SET   @strCount= 'SELECT   @TotalCount=COUNT(*)   FROM   '+   @Table
SET   @TotalPage=CEILING(str(@TotalCount/@PageSize))
SET   @strSql= 'SELECT   TOP   '+   str(@PageSize)   + '   '+   @Column   + '   FROM   '+   @Table   +   '  
WHERE   '   +   @CountColumn   +   '> (SELECT   MAX( '+   @CountColumn   + ')  
FROM   (SELECT   TOP   '   +   str(@PageCount)+ '   '+   @CountColumn+ '  
FROM   '   +   @Table   +   '   ORDER   BY   '   +   @CountColumn   + ')   AS   T)  
ORDER   BY   '   +   @OrderColumn   + '   '+   @OrderType
END
EXEC   (@strCount)
EXEC   (@strSql)
END

下面是我在asp.net2.0中进行调用
public   DataTable   ShowBook(MShowBook   mshowbook)
                {
                        SqlParameter[]   parms   =   new   SqlParameter[10];
                        parms[0]   =   lzjbook.ParaInstance( "@Pagesize ",   SqlDbType.Int,   4,   mshowbook.Pagesize,   ParameterDirection.Input);
                        parms[1]   =   lzjbook.ParaInstance( "@CurrentPage ",   SqlDbType.Int,   4,   mshowbook.CureentPage,   ParameterDirection.Input);
                        parms[2]   =   lzjbook.ParaInstance( "@OrderType ",   SqlDbType.NVarChar,   4,   mshowbook.OrderType,   ParameterDirection.Input);


                        parms[3]   =   lzjbook.ParaInstance( "@TotalCount ",   SqlDbType.Int,   4,   null,   ParameterDirection.Output);
                        parms[4]   =   lzjbook.ParaInstance( "@TotalPage ",   SqlDbType.Int,   4,   null,   ParameterDirection.Output);
                        parms[5]   =   lzjbook.ParaInstance( "@Table ",   SqlDbType.NVarChar,   25,   "MainBook ",   ParameterDirection.Input);
                        parms[6]   =   lzjbook.ParaInstance( "@Column ",   SqlDbType.NVarChar,   150,   "BookName ",   ParameterDirection.Input);
                        parms[7]   =   lzjbook.ParaInstance( "@OrderColumn ",   SqlDbType.NVarChar,   50,   "AddTime ",   ParameterDirection.Input);
                        parms[8]   =   lzjbook.ParaInstance( "@CountColumn ",   SqlDbType.NVarChar,   20,   "BookID ",   ParameterDirection.Input);
                        parms[9]   =   lzjbook.ParaInstance( "@Condition ",   SqlDbType.NVarChar,   200,   "bookname= '图书名 ' ",   ParameterDirection.Input);
                        DataTable   dt   =   new   DataTable();
                        try
                        {
                                dt   =   lzjbook.GetOneRecord( "Pagination ",   CommandType.StoredProcedure,   parms);
                        }
                        catch   (Exception   e)
                        {
                                if   (e   !=   null)
                                {
                                        HttpContext.Current.Response.Redirect( "Error.aspx?errorMsg=对不起,在函数执行期间出现了错误,给您带来不便表示歉意,请稍后再试! ");
                                }
                        }
                        finally
                        {
                                lzjbook.Close();
                        }


                        return   dt;
                       
                }

参数都传进去,就是出现“消息   137,级别   15,状态   1,第   1   行
必须声明标量变量   "@TotalCount "。”
我的这个方法我测试过了,没有问题的
请各位帮我看看,感激不尽


[解决办法]
这句换下
EXEC (@strCount)
----------------------------------------------
exec sp_executesql @strCount,N 'TotalCount int output ',@TotalCount output
你这个属于动态sql带传出参数的.
可以参考下sp_executesql的用法.
[解决办法]
SET @strCount= 'SELECT @TotalCount=COUNT(*) FROM '+ @Table + ' WHERE '+@Condition
SET @strCount= 'SELECT @TotalCount=COUNT(*) FROM '+ @Table


上面两句要用sp_executesql才能把COUNT(*)结果提取出来。
[解决办法]
EXEC (@strCount)
EXEC (@strSql)
END

-- modify to
EXEC sp_executesql @strCount,N '@totalcount int output ',@totalcount output
EXEC (@strSql)
END



[解决办法]
--如何从动态SQL中返回数值?

--如何将exec执行结果放入变量中?

declare @num int, @sql nvarchar(4000)
set @sql= 'select @a=count(*) from tableName '
exec sp_executesql @sql,N '@a int output ',@num output
select @num


[解决办法]

动态sql语句基本语法
1 :普通SQL语句可以用Exec执行

eg: Select * from tableName
Exec( 'select * from tableName ')
Exec sp_executesql N 'select * from tableName ' -- 请注意字符串前一定要加N

2:字段名,表名,数据库名之类作为变量时,必须用动态SQL

eg:
declare @fname varchar(20)
set @fname = 'FiledName '
Select @fname from tableName -- 错误,不会提示错误,但结果为固定值FiledName,并非所要。
Exec( 'select ' + @fname + ' from tableName ') -- 请注意 加号前后的 单引号的边上加空格

当然将字符串改成变量的形式也可
declare @fname varchar(20)
set @fname = 'FiledName ' --设置字段名

declare @s varchar(1000)
set @s = 'select ' + @fname + ' from tableName '
Exec(@s) -- 成功
exec sp_executesql @s -- 此句会报错


declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000)
set @s = 'select ' + @fname + ' from tableName '
Exec(@s) -- 成功
exec sp_executesql @s -- 此句正确

3. 输出参数
declare @num int, @sql nvarchar(4000)
set @sql= 'select count(*) from tableName '
exec(@sql)


--如何将exec执行结果放入变量中?

declare @num int, @sql nvarchar(4000)
set @sql= 'select @a=count(*) from tableName '
exec sp_executesql @sql,N '@a int output ',@num output
select @num


[解决办法]
修改两处:

SET @strCount= 'SELECT @TotalCount=COUNT(*) FROM '+ @Table + ' WHERE '+@Condition
exec sp_executesql @strCount, N '@TotalCount int output ', @TotalCount output
SET @TotalPage=CEILING(str(@TotalCount/@PageSize))

SET @strCount= 'SELECT @TotalCount=COUNT(*) FROM '+ @Table
exec sp_executesql @strCount, N '@TotalCount int output ', @TotalCount output


SET @TotalPage=CEILING(str(@TotalCount/@PageSize))

后面那一行:EXEC (@strCount),注释或删除。

热点排行