--我的表
CREATE TABLE [dbo].[t_Products](
[ProductID] [nvarchar](50) NOT NULL,--产品编号
[ProductName] [nvarchar](50) NOT NULL,--产品名称
[Producer] [nvarchar](50) NOT NULL,--生产商
[AddTime] [datetime] NOT NULL,--入库时间
[Classify] [nvarchar](50) NOT NULL,--分类
[Price] [decimal](10, 2) NOT NULL,--价格
)
--自己写的存储过程,本人菜鸟,写不来
CREATE PROCEDURE Get_Result
(
    @startIndex int,--起始索引
    @endIndex int,--结束索引
    @docount bit,--标记。0:查出符合条件的产品的详细信息;1:查出符合条件的产品的总数
    @Classify nvarchar(50),--产品分类
    @ProductName nvarchar(50),--产品名称
    @minPrice decimal,--价格范围
    @maxPrice decimal--价格范围)
AS
SET NOCOUNT ON
IF(@docount=1)
SELECT COUNT(*) AS Counts FROM t_Products
ELSE
BEGIN
DECLARE @indextable TABLE(id int IDENTITY(1,1),nid nvarchar(50))
SET ROWCOUNT @endIndex
INSERT INTO @indextable(nid) SELECT ProductID FROM t_Products ORDER BY ProductID DECLARE @strsql nvarchar(4000)
SET @strsql='SELECT * FROM t_Products A,'+@indextable+' B WHERE A.ProductID=B.nid AND B.id BETWEEN '+@startIndex+' AND '+@endIndex+' ORDER BY B.id'

IF @ProductName IS NOT NULL AND @ProductName!=''
BEGIN
SET @strsql = @strsql + ' and ProductName like ''%' + @ProductName + '%'''
END
IF @Classify IS NOT NULL AND @Classify!=''
BEGIN
SET @strsql = @strsql + ' and Classify=''' + @Classify + ''''
END
IF @minPrice IS NOT NULL AND @minPrice!=0
BEGIN
SET @strsql = @strsql + ' and Price>=''' + CONVERT(varchar(30),@minPrice) + ''''
END
IF @maxPrice IS NOT NULL AND @maxPrice!=0
BEGIN
SET @strsql = @strsql + ' and Price<=''' + CONVERT(varchar(30),@maxPrice) + ''''
END
PRINT @strsql
EXEC(@strsql)
END
SET NOCOUNT OFF---------------------------------------
消息 137,级别 15,状态 2,过程 Get_Result,第 23 行
必须声明标量变量 "@indextable"。
请问这个问题该怎么改?
或者请高手帮我写一个按条件查找结果并分页的存储过程。。
要判断条件是否为空。。
谢谢。。没分了

解决方案 »

  1.   

    表变量,不能这样用。改为真实表就可以了 或者在sql字符串中定义表变量。
    --这样不行
    declare @table table(id int)
    declare @sql varchar(20)
    set @sql ='insert into '+@table+' select 1'
    exec(@sql)--这样可以
    declare @sql varchar(100)
    set @sql ='declare @table table(id int);insert into @table select 1;select * from @table'
    exec (@sql)
      

  2.   


    SET @strsql='DECLARE @indextable TABLE(id int IDENTITY(1,1),nid nvarchar(50));
    SET ROWCOUNT @endIndex;
    INSERT INTO @indextable(nid) SELECT ProductID FROM t_Products ORDER BY ProductID;
    SELECT * FROM t_Products A,@indextable B WHERE A.ProductID=B.nid AND B.id BETWEEN @startIndex AND @endIndex ORDER BY B.id'-------------------------------------------
    消息 137,级别 15,状态 2,第 2 行
    必须声明标量变量 "@endIndex"。
    消息 137,级别 15,状态 2,第 4 行
    必须声明标量变量 "@startIndex"。
    SET @strsql='DECLARE @indextable TABLE(id int IDENTITY(1,1),nid nvarchar(50));
    SET ROWCOUNT @endIndex;
    INSERT INTO @indextable(nid) SELECT ProductID FROM t_Products ORDER BY ProductID;
    SELECT * FROM t_Products A,@indextable B WHERE A.ProductID=B.nid AND B.id BETWEEN '+@startIndex+' AND '+@endIndex+' ORDER BY B.id'----------------------------------------------
    消息 245,级别 16,状态 1,过程 Get_Result,第 23 行
    在将 varchar 值 'DECLARE @indextable TABLE(id int IDENTITY(1,1),nid nvarchar(50));
    SET ROWCOUNT @endIndex;
    INSERT INTO @indextable(nid) SELECT ProductID FROM t_Products ORDER BY ProductID;
    SELECT * FROM t_Products A,@indextable B WHERE A.ProductID=B.nid AND B.id BETWEEN ' 转换成数据类型 int 时失败。
    请问@startIndex和@endIndex该怎么写进去呢?
      

  3.   

    给个例自己参考.
    http://topic.csdn.net/u/20100203/17/8F916471-597D-481A-B170-83BCEFE3B199.html应一个朋友的要求,贴上收藏的SQL常用分页的办法~~ 表中主键必须为标识列,[ID] int IDENTITY (1,1) 1.分页方案一:(利用Not In和SELECT TOP分页) 语句形式:  
    SELECT TOP 页记录数量 * 
    FROM 表名 
    WHERE (ID NOT IN 
      (SELECT TOP (每页行数*(页数-1)) ID 
      FROM 表名 
      ORDER BY ID)) 
      ORDER BY ID 
    //自己还可以加上一些查询条件 
    例: 
    select top 2 * 
    from Sys_Material_Type 
    where (MT_ID not in 
        (select top (2*(3-1)) MT_ID from Sys_Material_Type  order by MT_ID)) 
    order by MT_ID 2.分页方案二:(利用ID大于多少和SELECT TOP分页) 语句形式: 
    SELECT TOP 每页记录数量 * 
    FROM 表名 
    WHERE (ID > 
              (SELECT MAX(id) 
        FROM (SELECT TOP 每页行数*页数 id  FROM 表 
              ORDER BY id) AS T) 
          ) 
    ORDER BY ID 例: 
    SELECT TOP 2 * 
    FROM Sys_Material_Type 
    WHERE (MT_ID > 
              (SELECT MAX(MT_ID) 
              FROM (SELECT TOP (2*(3-1)) MT_ID 
                    FROM Sys_Material_Type 
                    ORDER BY MT_ID) AS T)) 
    ORDER BY MT_ID 3.分页方案三:(利用SQL的游标存储过程分页) 
    create  procedure SqlPager 
    @sqlstr nvarchar(4000), --查询字符串 
    @currentpage int, --第N页 
    @pagesize int --每页行数 
    as 
    set nocount on 
    declare @P1 int, --P1是游标的id 
    @rowcount int 
    exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1, @rowcount=@rowcount output 
    select ceiling(1.0*@rowcount/@pagesize) as 总页数--,@rowcount as 总行数,@currentpage as 当前页 
    set @currentpage=(@currentpage-1)*@pagesize+1 
    exec sp_cursorfetch @P1,16,@currentpage,@pagesize 
    exec sp_cursorclose @P1 
    set nocount off 4.总结: 
    其它的方案:如果没有主键,可以用临时表,也可以用方案三做,但是效率会低。 
    建议优化的时候,加上主键和索引,查询效率会提高。 通过SQL 查询分析器,显示比较:我的结论是: 
    分页方案二:(利用ID大于多少和SELECT TOP分页)效率最高,需要拼接SQL语句 
    分页方案一:(利用Not In和SELECT TOP分页)  效率次之,需要拼接SQL语句 
    分页方案三:(利用SQL的游标存储过程分页)    效率最差,但是最为通用 
      

  4.   


    CREATE PROCEDURE Get_Result
    (
    @startIndex int,--起始索引
        @endIndex int,--结束索引
        @docount bit,--标记。0:查出符合条件的产品的详细信息;1:查出符合条件的产品的总数
    @Classify nvarchar(50),--产品分类
        @ProductName nvarchar(50),--产品名称
        @minPrice decimal,--价格范围
        @maxPrice decimal--价格范围
    )
    AS
    SET NOCOUNT ON
    IF(@docount=1)
    SELECT COUNT(*) AS Counts FROM t_Products
    ELSE
    BEGIN
    DECLARE @indextable TABLE(id int IDENTITY(1,1) ,nid nvarchar(50))
    SET ROWCOUNT @endIndex
    INSERT INTO @indextable(nid) SELECT ProductID FROM t_Products  ORDER BY ProductID
    SELECT * FROM t_Products A,@indextable B WHERE A.ProductID=B.nid AND B.id BETWEEN @startIndex AND @endIndex
    (如果@Classify不为空且@Classify!=''则AND Classify = @Classify)   ORDER BY B.id
    END
    SET NOCOUNT OFF(如果@Classify不为空且@Classify!=''则AND Classify = @Classify)
    这一段该怎么写阿。。