天天看点

【机房收费系统】——存储过程之字符串拼接       遇到问题       解决问题:       验证猜想:       总结:

       最近再敲机房收费系统的时候,点到组合查询这块儿,突然发现,多个条件的组合查询实现不了了,当初自己只是用“与”逻辑试了试,就以为功能实现了呢!确实是想的太简单了。

       遇到问题

       其实我在测试的时候不管输入的是一行条件还是两行条件,都是针对一条记录来尝试的,出来的结果自然也是一样(其实只有第一行条件起了作用)。这次用“或逻辑”来尝试,却出了问题,只有第一行的条件查询出了结果,而第二行的条件却没有返回值。如图所示:

       只执行了条件一的查询效果图:

【机房收费系统】——存储过程之字符串拼接       遇到问题       解决问题:       验证猜想:       总结:

       两个条件都执行时的效果图:

【机房收费系统】——存储过程之字符串拼接       遇到问题       解决问题:       验证猜想:       总结:

       我立刻想到了是存储过程的原因!于是,我便开始了对应着别人的博客来修改自己的存储过程,改了半天也没有成果,从两点半改到了四点半,我都快疯了,到底是哪里出错了。我把别人博客上的核心代码拷过来,然后改成自己的参数,一执行,居然通过了。我对照着别人的博客看了一遍又一遍,自己的代码和别人的几乎一模一样。实在是受不了了,我就去了厕所。

       写到这,可能很多人会想,是不是遇到别的同学,商量了一下就解决了。只能说你想多了,确实商量了,可别人遇到的问题和我遇到的不太一样。出去这一遭,回来就突然有了灵感,我看到了“核心代码”以外的东西——变量声明。

       解决问题:

       首先看看我原来的存储过程:

【机房收费系统】——存储过程之字符串拼接       遇到问题       解决问题:       验证猜想:       总结:

       大家都看到了,我死活没想到,居然是一个小小的变量声明绊了我将近两个小时。这里只需要把char类型改成varchar就可以了。我当时改的时候还在对自己说,这么改肯定不行吧,怎么可能是变量声明的问题呢!没想到。。。这里不得不说一下char和varchar的区别:

       char类型:定长字符型,比如设定了长度为10,即使你存储的字符只有两位,系统也会自动补充8位空格,保持整个字符长度为8。

       varchar类型:变长型字符,比如设定了长度为10,如果你存储的字符只有两位,系统就会只存储两位。

       看过char和varchar的区别后,感觉突然明白了什么,是不是在字符串连接的时候,由于char类型会自动补空格,所以在连接第二个条件的字符串时超出了规定长度1000的范围,然后第二个条件的字符串都被舍弃掉了。

       验证猜想:

       要验证自己想的对不对,将字符串传出来看一下就知道了。

       1、首先在存储过程中加入一个输出参数,如图所示:

【机房收费系统】——存储过程之字符串拼接       遇到问题       解决问题:       验证猜想:       总结:

       2、新建查询,然后输入以下代码:

       declare @str varchar(500)

       exec proc_GroupSelect 'Card_ID','=','1','And','Card_ID','=','2','','','','','Student_Info',@str output

       select @str as 拼接的字符串,datalength(@str) as 字符串长度

       (1)当@a声明为varchar时,查询结果如图所示:

【机房收费系统】——存储过程之字符串拼接       遇到问题       解决问题:       验证猜想:       总结:

       (2)当@a声明为char时,查询结果如图所示:

【机房收费系统】——存储过程之字符串拼接       遇到问题       解决问题:       验证猜想:       总结:

       3、分析结果

       通过结果大家很容易的看出,在拼接字符串时,同样的条件,不同的变量类型,varchar时返回的字符串是完整的,而char时返回的字符串却少了‘And Card_ID='2'的部分。这也就是为什么使用char类型来拼接字符串时,无论怎么查都只是第一行条件的结果。

       那么为什么会这样呢?就是因为char是定长的,长度不够时会自动补空格,分析如下:

       第一次给@a赋值时,@a=Select * From Student_Info Where Card_ID='1'(44个字符)+456个空格

       第二次给@a赋值时,@a=@a+‘And Card_ID='2'(超出规定500的范围,被舍掉)

       很明显,由于@a是char类型,第一次赋值时长度不够,所以在后面补空格,但是第二次赋值时,由于@a规定长度为500,所以@a+‘And Card_ID='2'超出了规定的范围,于是‘And Card_ID='2'部分就被舍弃,只剩下了条件一。而varchar就没有这个问题了,因为它是变长的,长度不够不会补空格。

       总结:

       写完这篇文章,自己也吓了一跳。真没想到这么一个小问题,居然写了这么多,也真是服了自己钻牛角尖的性格。不过,分析过后,我相信这个问题我会记一辈子的,毕竟消耗了我那么多时间来研究它,而且还是第一次写存储过程,很多东西都是现查的,包括如何输出参数的值,统计字符串的长度等等。总之,这些问题,既然遇到了,就不要放过,努力让它成为自己的东西。

       最后,如果大家以后有解决不了的问题,那就停下工作,去趟厕所吧。真的很管用,没准回来问题就解决了呢!