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

分页存储过程:遇到被零除异常。高手帮忙解决上

2013-03-19 
分页存储过程:遇到被零除错误。高手帮忙解决下。CREATE PROCEDURE [dbo].[sp_GetPageList](@TblName nvarcha

分页存储过程:遇到被零除错误。高手帮忙解决下。

CREATE PROCEDURE [dbo].[sp_GetPageList](
    @TblName nvarchar(50) = N'',--必填:进行分页的表名
    @FieldText nvarchar(1000) = N'',--选填:显示的字段,默认为 全部字段
    @Pkey nvarchar(50) = N'',--必填:主键或唯一键(数值类型),推荐添加索引
    @WhereText nvarchar(1000) = N'',--选填:Where 条件句
    @OrderField nvarchar(100) = N'',--选填:排序字段列表,以逗号分隔
    @PageIndex int = 1,                    --选填:显示的页码,默认值为 1
    @PageSize int = 10,                    --选填:显示的页面大小,默认值为 10
    @TotalPage int OUTPUT
)
AS
BEGIN
    SET NOCOUNT ON;
    -- ******************参数检查及处理:开始******************
    -- 表名
    IF OBJECT_ID(@TblName) IS NULL
        BEGIN
            RAISERROR(N'对象"%s"不存在',1,16,@TblName)
            RETURN
        END
    IF OBJECTPROPERTY(OBJECT_ID(@TblName),N'IsTable')=0
        AND OBJECTPROPERTY(OBJECT_ID(@TblName),N'IsView')=0
        AND OBJECTPROPERTY(OBJECT_ID(@TblName),N'IsTableFunction')=0
        BEGIN
            RAISERROR(N'"%s"不是表、视图或者表值函数',1,16,@TblName)
            RETURN
    END
    -- 主键字段
    IF ISNULL(@Pkey,N'')=''
        BEGIN
            RAISERROR(N'分页处理需要主键或唯一键(数值类型)',1,16)
            RETURN
        END
    -- 显示字段
    IF ISNULL(@FieldText,N'')=N'' 
        SET @FieldText=N'*'
    -- Where 条件句
    IF ISNULL(@WhereText,N'') != N''
        SET @WhereText = N' AND ' + @WhereText + N' '
    -- 排序语句
    IF ISNULL(@OrderField,N'') != N''
        SET @OrderField = N' ORDER BY ' + @OrderField + N' '
    -- 页码
    IF ISNULL(@PageIndex,0)<1 
        SET @PageIndex=1
    -- 页大小
    IF ISNULL(@PageSize,0)<1 
        SET @PageSize=10
    -- ******************参数检查及处理:结束******************
    
    -- 计算总页数
    DECLARE @selectItemsCount nvarchar(4000)
    SET @SelectItemsCount = N'SELECT @TotalPage = COUNT( ' + @Pkey + N' ) FROM ' + @TblName + N' WHERE 1=1 ' + @WhereText


    EXEC sp_executesql @selectItemsCount , N'@TotalPage int OUTPUT,@Pkey nvarchar(1000),@TblName nvarchar(1000),@WhereText nvarchar(1000)' 
        ,@TotalPage OUTPUT,@Pkey,@TblName,@WhereText
    SET @TotalPage = (@TotalPage + @PageSize -1) / @PageSize
    
    -- 计算
    DECLARE @TopNForMain nvarchar(50)
    DECLARE @TopNForChild nvarchar(50)
    SET @TopNForMain = @PageSize
    SET @TopNForChild = @PageSize * (@PageIndex - 1)

    -- 返回数据集
    IF @PageIndex = 1
        BEGIN
            DECLARE @queryStr1 nvarchar(4000)
            SET @queryStr1 = N'SELECT TOP '+ @TopNForMain + N' ' + @FieldText + N' FROM ' + @TblName + N' WHERE 1=1 ' + @WhereText + N' ' + @OrderField
            EXEC sp_executesql @queryStr1
                ,N'@TopNForMain nvarchar(50),@FieldText nvarchar(1000),@TblName sysname,@WhereText nvarchar(1000),@OrderField nvarchar(1000)'
                ,@TopNForMain,@WhereText,@TblName,@FieldText,@OrderField
            PRINT @queryStr1
        END
    ELSE
        BEGIN
            DECLARE @queryStr2 nvarchar(4000)
            SET @queryStr2 = N'SELECT TOP ' + @TopNForMain + N' ' + @FieldText + N' FROM ' + @TblName + N' WHERE ' + @Pkey 
                + N' NOT IN ( SELECT TOP ' + @TopNForChild + N' ' + @Pkey + N' FROM ' + @TblName + N' WHERE 1=1 ' + @WhereText + N' ' + @OrderField + N' )'
                + @WhereText + @OrderField
            EXEC sp_executesql @queryStr2
                ,N'@TopNForMain nvarchar(50),@FieldText nvarchar(1000),@TblName sysname,@Pkey nvarchar(1000),@TopNForChild nvarchar(50),@WhereText nvarchar(1000),@OrderField nvarchar(1000)'
                ,@TopNForMain,@FieldText,@TblName,@Pkey,@TopNForChild,@WhereText,@OrderField
            PRINT @queryStr2
        END
    
END


GO


怎么才能不出现这样的错啊
[解决办法]
SET @TotalPage = (@TotalPage + @PageSize -1) / @PageSize
只有这里一个地方是除法运算,当然在这里加了
问题是一般这种逻辑是在程序中控制的,@PageSize参数不可以<0才对
[解决办法]
CREATE PROCEDURE [dbo].[sp_GetPageList](
    @TblName nvarchar(50) = N'', --必填:进行分页的表名
    @FieldText nvarchar(1000) = N'', --选填:显示的字段,默认为 全部字段
    @Pkey nvarchar(50) = N'', --必填:主键或唯一键(数值类型),推荐添加索引
    @WhereText nvarchar(1000) = N'', --选填:Where 条件句
    @OrderField nvarchar(100) = N'', --选填:排序字段列表,以逗号分隔
    @PageIndex int = 1,                     --选填:显示的页码,默认值为 1
    @PageSize int = 10,                     --选填:显示的页面大小,默认值为 10
    @TotalPage int OUTPUT
)
AS
BEGIN
    SET NOCOUNT ON;
    -- ******************参数检查及处理:开始******************
    -- 表名
    IF OBJECT_ID(@TblName) IS NULL
        BEGIN
            RAISERROR(N'对象"%s"不存在',1,16,@TblName)
            RETURN
        END
    IF OBJECTPROPERTY(OBJECT_ID(@TblName),N'IsTable')=0
        AND OBJECTPROPERTY(OBJECT_ID(@TblName),N'IsView')=0
        AND OBJECTPROPERTY(OBJECT_ID(@TblName),N'IsTableFunction')=0
        BEGIN
            RAISERROR(N'"%s"不是表、视图或者表值函数',1,16,@TblName)
            RETURN
    END
    -- 主键字段
    IF ISNULL(@Pkey,N'')=''
        BEGIN
            RAISERROR(N'分页处理需要主键或唯一键(数值类型)',1,16)
            RETURN
        END
    -- 显示字段
    IF ISNULL(@FieldText,N'')=N'' 
        SET @FieldText=N'*'
    -- Where 条件句
    IF ISNULL(@WhereText,N'') != N''
        SET @WhereText = N' AND ' + @WhereText + N' '
    -- 排序语句
    IF ISNULL(@OrderField,N'') != N''
        SET @OrderField = N' ORDER BY ' + @OrderField + N' '
    -- 页码
    IF ISNULL(@PageIndex,0)<1 
        SET @PageIndex=1


    -- 页大小
    IF ISNULL(@PageSize,0)<1 
        SET @PageSize=10
    -- ******************参数检查及处理:结束******************
    
    -- 计算总页数
    DECLARE @selectItemsCount nvarchar(4000)
    SET @SelectItemsCount = N'SELECT @TotalPage = COUNT( ' + @Pkey + N' ) FROM ' + @TblName + N' WHERE 1=1 ' + @WhereText
    EXEC sp_executesql @selectItemsCount , N'@TotalPage int OUTPUT,@Pkey nvarchar(1000),@TblName nvarchar(1000),@WhereText nvarchar(1000)' 
        ,@TotalPage OUTPUT,@Pkey,@TblName,@WhereText
    IF(@PageSize=0)
        BEGIN
            SET @TotalPage = 0
        END
    ELSE
        BEGIN
            SET @TotalPage = (@TotalPage + @PageSize -1) / @PageSize
        END
    
    
    -- 计算
    DECLARE @TopNForMain nvarchar(50)
    DECLARE @TopNForChild nvarchar(50)
    SET @TopNForMain = @PageSize
    SET @TopNForChild = @PageSize * (@PageIndex - 1)

    -- 返回数据集
    IF @PageIndex = 1
        BEGIN
            DECLARE @queryStr1 nvarchar(4000)
            SET @queryStr1 = N'SELECT TOP '+ @TopNForMain + N' ' + @FieldText + N' FROM ' + @TblName + N' WHERE 1=1 ' + @WhereText + N' ' + @OrderField
            EXEC sp_executesql @queryStr1
                ,N'@TopNForMain nvarchar(50),@FieldText nvarchar(1000),@TblName sysname,@WhereText nvarchar(1000),@OrderField nvarchar(1000)'
                ,@TopNForMain,@WhereText,@TblName,@FieldText,@OrderField
            PRINT @queryStr1
        END
    ELSE
        BEGIN
            DECLARE @queryStr2 nvarchar(4000)
            SET @queryStr2 = N'SELECT TOP ' + @TopNForMain + N' ' + @FieldText + N' FROM ' + @TblName + N' WHERE ' + @Pkey 
                + N' NOT IN ( SELECT TOP ' + @TopNForChild + N' ' + @Pkey + N' FROM ' + @TblName + N' WHERE 1=1 ' + @WhereText + N' ' + @OrderField + N' )'


                + @WhereText + @OrderField
            EXEC sp_executesql @queryStr2
                ,N'@TopNForMain nvarchar(50),@FieldText nvarchar(1000),@TblName sysname,@Pkey nvarchar(1000),@TopNForChild nvarchar(50),@WhereText nvarchar(1000),@OrderField nvarchar(1000)'
                ,@TopNForMain,@FieldText,@TblName,@Pkey,@TopNForChild,@WhereText,@OrderField
            PRINT @queryStr2
        END
    
END
GO
[解决办法]
你不清楚哪里需要除0?这不是你自己写的吗?我都在用2012了.....2000的样子都快记不得了。
[解决办法]
@PageSize不是传过去的参数吗,按理说不应该出现<1的情况啊
[解决办法]
关闭除零错误,遇除零则返回NULL
set arithabort off    
set ansi_warnings off   

热点排行