一個存儲過程中的小問題


今天一下午我就用來寫這個存儲過程了。遇到了好幾個問題,現在解決了,就曬一曬,看看各位大牛有沒有啥更好的辦法,算是拋磚引玉吧。。。

這個存儲過程是我用來搜索擁有某種技能的用戶的

存儲過程
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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM