• 一个存储过程中的小问题


    今天一下午我就用来写这个存储过程了。遇到了好几个问题,现在解决了,就晒一晒,看看各位大牛有没有啥更好的办法,算是抛砖引玉吧。。。

    这个存储过程是我用来搜索拥有某种技能的用户的

    存储过程
    create PROCEDURE [dbo].[selectuserbypageandsearch]
    @categoryid int,
    @sex int,
    @skillid int,
    @ishaved int,
    
    @pageindex int,
    @pagesize int
    
    AS
    DECLARE @strSQL varchar(5000)
    declare @whereSQL varchar(1000)
    set @whereSQL='where 1=1 and dbo.Users.isskillopened=1'
    if @ishaved>0
    set @whereSQL=@whereSQL+'and dbo.Myskills.ishaved='+ltrim(STR(@ishaved))+''
    if @sex>=0 
    set @whereSQL =@whereSQL +' and dbo.Users.sex='+STR(@sex)+''
    if @skillid>0
    set @whereSQL =@whereSQL +' and dbo.Myskills.sid='+STR(@skillid)+''
    if @skillid<=0 and @categoryid>=0
    set @whereSQL =@whereSQL +' and dbo.Skills.categoryid='+STR(@categoryid)+''
    
    
    IF @pageindex = 1
    BEGIN
    
    SET @strSQL ='SELECT DISTINCT TOP '+ STR(@pagesize) + '  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao
    FROM    dbo.Myskills INNER JOIN
                dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN
                dbo.Users ON dbo.Myskills.uid = dbo.Users.id
                '+ STR(@whereSQL) + ''
    
    end
    ELSE
    BEGIN
    SET @strSQL ='SELECT DISTINCT TOP '+ STR(@pagesize) + '  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao
    FROM    dbo.Myskills INNER JOIN
                dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN
                dbo.Users ON dbo.Myskills.uid = dbo.Users.id
                '+ STR(@whereSQL) + ' and dbo.Users.id >(SELECT ISNULL(MAX([id]),0) FROM (SELECT TOP '+STR((@pageindex-1)*@pagesize)+' id FROM [User] '+ STR(@whereSQL) + ' ORDER BY id) as A) ORDER by dbo.Users.id desc '
    end
    select @strSQL
    EXEC(@strSQL)
    GO

    写好之后,把它执行一下。。。。

    我使用的是下面的代码

     exec selectuserbypageandsearch 1,-1,0,0,1,10  

    果然有问题。。。。水平太菜。。。没办法。。错误显示的是

    消息 8114,级别 16,状态 5,过程 selectuserbypageandsearch,第 27 行
    从数据类型 varchar 转换为 float 时出错。

    好吧,我见过这个错误,那就修改它。。。(虽然我不知道为什么要这么改。。。)

    alter PROCEDURE [dbo].[selectuserbypageandsearch]
    @categoryid int,
    @sex int,
    @skillid int,
    @ishaved int,
    
    @pageindex int,
    @pagesize int
    
    AS
    DECLARE @strSQL varchar(5000)
    declare @whereSQL varchar(1000)
    set @whereSQL='where dbo.Users.isskillopened=1'
    if @ishaved>0
    set @whereSQL=@whereSQL+'and dbo.Myskills.ishaved='+ltrim(STR(@ishaved))+''
    if @sex>=0 
    set @whereSQL =@whereSQL +' and dbo.Users.sex='+STR(@sex)+''
    if @skillid>0
    set @whereSQL =@whereSQL +' and dbo.Myskills.sid='+STR(@skillid)+''
    if @skillid<=0 and @categoryid>=0
    set @whereSQL =@whereSQL +' and dbo.Skills.categoryid='+STR(@categoryid)+''
    
    
    IF @pageindex = 1
    BEGIN
    
    SET @strSQL ='SELECT DISTINCT TOP '+ STR(@pagesize) + '  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao
    FROM    dbo.Myskills INNER JOIN
                dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN
                dbo.Users ON dbo.Myskills.uid = dbo.Users.id
                '+ Convert(varchar,@whereSQL) + ''--有@wheresql的都修改一下
    
    end
    ELSE
    BEGIN
    SET @strSQL ='SELECT DISTINCT TOP '+ STR(@pagesize) + '  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao
    FROM    dbo.Myskills INNER JOIN
                dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN
                dbo.Users ON dbo.Myskills.uid = dbo.Users.id
                '+ Convert(varchar,@whereSQL) + ' and dbo.Users.id >(SELECT ISNULL(MAX([id]),0) FROM (SELECT TOP '+STR((@pageindex-1)*@pagesize)+' id FROM [User] '+ Convert(varchar,@whereSQL) + ' ORDER BY id) as A) ORDER by dbo.Users.id desc '
    end
    select @strSQL
    EXEC(@strSQL)
    GO

    这次消息界面显示的错误是

    (1 行受影响)
    消息 102,级别 15,状态 1,第 5 行
    '=' 附近有语法错误。

    这是咋回事??我一看select出来的语句。。。

    SELECT DISTINCT TOP         10  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao  FROM    dbo.Myskills INNER JOIN              dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN              dbo.Users ON dbo.Myskills.uid = dbo.Users.id              where dbo.Users.isskillopened=

    一到“=”这就断了。。。我以为是因为1的问题。。。

    于是我就加上了Convert函数,准备把它变成varchar类型的。但是不行,报同样的错误。

    这是咋回事。。。。我就纠结开了,我在等号前又加了个空格。。。

    这次报的是另外的错误

    消息 4145,级别 15,状态 1,第 5 行
    在应使用条件的上下文(在 'isskillopened' 附近)中指定了非布尔类型的表达式。

    这是什么错误。。以前没见过。。。百度了一些,没有和我的情况类似的。。。

    我又在where后面加了个1=1.。。。

    这时候,我的存储过程变成了。。。

    alter PROCEDURE [dbo].[selectuserbypageandsearch]
    @categoryid int,
    @sex int,
    @skillid int,
    @ishaved int,
    
    @pageindex int,
    @pagesize int
    
    AS
    DECLARE @strSQL varchar(5000)
    declare @whereSQL varchar(1000)
    set @whereSQL='where 1=1 and dbo.Users.isskillopened =1'--这里修改了一下
    if @ishaved>0
    set @whereSQL=@whereSQL+'and dbo.Myskills.ishaved='+ltrim(STR(@ishaved))+''
    if @sex>=0 
    set @whereSQL =@whereSQL +' and dbo.Users.sex='+STR(@sex)+''
    if @skillid>0
    set @whereSQL =@whereSQL +' and dbo.Myskills.sid='+STR(@skillid)+''
    if @skillid<=0 and @categoryid>=0
    set @whereSQL =@whereSQL +' and dbo.Skills.categoryid='+STR(@categoryid)+''
    
    
    IF @pageindex = 1
    BEGIN
    
    SET @strSQL ='SELECT DISTINCT TOP '+ STR(@pagesize) + '  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao
    FROM    dbo.Myskills INNER JOIN
                dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN
                dbo.Users ON dbo.Myskills.uid = dbo.Users.id
                '+ Convert(varchar,@whereSQL) + ''
    
    end
    ELSE
    BEGIN
    SET @strSQL ='SELECT DISTINCT TOP '+ STR(@pagesize) + '  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao
    FROM    dbo.Myskills INNER JOIN
                dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN
                dbo.Users ON dbo.Myskills.uid = dbo.Users.id
                '+ Convert(varchar,@whereSQL) + ' and dbo.Users.id >(SELECT ISNULL(MAX([id]),0) FROM (SELECT TOP '+STR((@pageindex-1)*@pagesize)+' id FROM [User] '+ Convert(varchar,@whereSQL) + ' ORDER BY id) as A) ORDER by dbo.Users.id desc '
    end
    select @strSQL
    EXEC(@strSQL)
    GO

    现在的错误变成了

    消息 4145,级别 15,状态 1,第 5 行
    在应使用条件的上下文(在 'isskil' 附近)中指定了非布尔类型的表达式。

    后面的几个字母为啥不出现了。。。这时候我突然想到了有关T-SQL的10个好习惯(http://kb.cnblogs.com/page/160066/)里的第二条。。varchar要声明长度,果然,在@wheresql变量变换的时候没有加上varchar的长度,默认的长度为一,造成的结果。

    最后的代码,终于不出错了。。
     1 alter PROCEDURE [dbo].[selectuserbypageandsearch]
     2 @categoryid int,
     3 @sex int,
     4 @skillid int,
     5 @ishaved int,
     6 
     7 @pageindex int,
     8 @pagesize int
     9 
    10 AS
    11 DECLARE @strSQL varchar(5000)
    12 declare @whereSQL varchar(1000)
    13 set @whereSQL='where dbo.Users.isskillopened =1'
    14 if @ishaved>0
    15 set @whereSQL=@whereSQL+'and dbo.Myskills.ishaved='+ltrim(STR(@ishaved))+''
    16 if @sex>=0 
    17 set @whereSQL =@whereSQL +' and dbo.Users.sex='+STR(@sex)+''
    18 if @skillid>0
    19 set @whereSQL =@whereSQL +' and dbo.Myskills.sid='+STR(@skillid)+''
    20 if @skillid<=0 and @categoryid>=0
    21 set @whereSQL =@whereSQL +' and dbo.Skills.categoryid='+STR(@categoryid)+''
    22 
    23 
    24 IF @pageindex = 1
    25 BEGIN
    26 
    27 SET @strSQL ='SELECT DISTINCT TOP '+ STR(@pagesize) + '  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao
    28 FROM    dbo.Myskills INNER JOIN
    29             dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN
    30             dbo.Users ON dbo.Myskills.uid = dbo.Users.id
    31             '+ Convert(varchar(1000),@whereSQL) + ''--这里修改一下
    32 
    33 end
    34 ELSE
    35 BEGIN
    36 SET @strSQL ='SELECT DISTINCT TOP '+ STR(@pagesize) + '  dbo.Users.id, dbo.Users.name, dbo.Users.nickname,dbo.Users.xuehao
    37 FROM    dbo.Myskills INNER JOIN
    38             dbo.Skills ON dbo.Myskills.sid = dbo.Skills.id INNER JOIN
    39             dbo.Users ON dbo.Myskills.uid = dbo.Users.id
    40             '+ Convert(varchar(1000),@whereSQL) + ' and dbo.Users.id >(SELECT ISNULL(MAX([id]),0) FROM (SELECT TOP '+STR((@pageindex-1)*@pagesize)+' id FROM [User] '+ Convert(varchar(1000),@whereSQL) + ' ORDER BY id) as A) ORDER by dbo.Users.id desc '
    41 end
    42 select @strSQL
    43 EXEC(@strSQL)
    44 GO
  • 相关阅读:
    C#获取Word文档页数,并跳转到指定的页面获取页面信息
    GC 垃圾回收
    Open Flash Chart 之线图
    Open Flash Chart 之线图(二)
    Nullable可空类型
    System.AppDomain类
    C# 事件
    C#方法的参数 Ref Out Params 4种类型的参数
    单向链表
    C# 结构体 struct
  • 原文地址:https://www.cnblogs.com/wlzcool/p/2966337.html
Copyright © 2020-2023  润新知