2013-07-08 145 views
1

我正在嘗試編寫動態查詢。搜索標準將來自ASP頁面,並將 傳遞給SQL Server 2005 Express數據庫中的存儲過程。搜索不會給出任何錯誤,但會返回數據庫中的所有數據,並且不會基於變量進行過濾。有人請幫忙?動態查詢無法正常工作

我在這裏張貼的存儲過程:

set ANSI_NULLS ON 
set QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[spSearchResource] 
    @ResourceID int, 
    @Name varchar(75), 
    @City varchar(75), 
    @State varchar(2), 
    @County varchar(30), 
    @Specialty varchar(100), 
    @Zip varchar(5), 
    @English bit, 
    @Spanish bit, 
    @French bit, 
    @Italian bit, 
    @Chinese bit, 
    @Japanese bit, 
    @GenderType varchar(8), 
    @Within int, 
    @Children bit, 
    @Adolescents bit, 
    @Adults bit, 
    @Geriatrics bit, 
    @Insurance varchar(50) 
AS 
BEGIN 

    DECLARE @strSql varchar(4000); 

    SET @strSql = 'select r.resourceid, r.flag, r.note, r.Name, r.ContactName, r.Website, r.Email, >r.GenderType, loc.Street, loc.city, loc.State, loc.Zip, loc.County,phone.areacode, 
       phone.phonenum,phone.extension,spec.specialty, 
    ins.insurance,pop.children,pop.Adolescents,  
    pop.adults,pop.geriatrics,lan.english,lan.spanish,lan.french,lan.italian,lan.chinese,lan.japanese 
    from resource r left outer join resourcelocation loc on (r.resourceid = loc.resourceid) 
    left outer join resourcephone phone on (r.resourceid = phone.resourceid) 
    left outer join resourceinsurance ins on (r.resourceid = ins.resourceid) 
    left outer join resourcepopulation pop on (r.resourceid = pop.resourceid) 
    left outer join resourcespecialty spec on (r.resourceid = spec.resourceid) 
    left outer join resourcelanguage lan on (r.resourceid = lan.resourceid) ' 

     if (@ResourceID is not null) 
      SET @strSql = @strSql + 'and r.resourceid = ' + (CONVERT(VARCHAR(10),@ResourceID)) 

     if (@Name is not null) 
      SET @strSql = @strSql + 'and r.Name like '+''''+ @Name+'%''' 

     if (@City is not null) 
      SET @strSql = @strSql + 'and loc.city like '+''''+ @City+'%''' 

     if (ltrim(rtrim(@State)) is not null) 
      SET @strSql = @strSql + 'and loc.State = trim(@State) ' 

     if (ltrim(rtrim(@Zip)) is not null) 
      SET @strSql = @strSql + 'and loc.Zip = trim(@Zip) ' 

     if (ltrim(rtrim(@County)) is not null) 
      SET @strSql = @strSql + 'and loc.County like trim(@County) ' 

     if (ltrim(rtrim(@specialty)) is not null) 
      SET @strSql = @strSql + 'and spec.specialty = trim(@spcialty) ' 

     if (ltrim(rtrim(@insurance)) is not null) 
      SET @strSql = @strSql + 'and ins.insurance = trim(@insurance) ' 

     if (@English = 1) 
      SET @strSql = @strSql + 'and lan.english = @English' 

     if (@Spanish = 1) 
      SET @strSql = @strSql + 'and lan.spanish = @Spanish ' 

     if (@French = 1) 
      SET @strSql = @strSql + 'and lan.french = @French ' 

     if (@Italian = 1) 
      SET @strSql = @strSql + 'and lan.italian = @Italian ' 

     if (@Chinese = 1) 
      SET @strSql = @strSql + 'and lan.Chinese = @Chinese ' 

     if (@Japanese = 1) 
      SET @strSql = @strSql + 'and lan.japanese = @Japanese ' 

     if (ltrim(rtrim(@GenderType)) != 0) 
      SET @strSql = @strSql + 'and r.GenderType like trim(@GenderType) ' 

     if (@children = 1) 
      SET @strSql = @strSql + 'and pop.children = @children ' 

     if (@Adolescents = 1) 
      SET @strSql = @strSql + 'and pop.Adolescents = @Adolescents ' 

     if (@adults = 1) 
      SET @strSql = @strSql + 'and pop.adults = @adults ' 

     if (@geriatrics = 1) 
      SET @strSql = @strSql + 'and pop.geriatrics = @geriatrics ' 

     print @strSql; 
     execute (@strSql); 
    END 
+0

那麼什麼打印時,它打印字符串? – JNK

回答

2

的問題是,你的過濾器不會被添加到WHERE條款,而是被添加作爲條件你最後LEFT OUTER JOIN。當條件不符合時,它只會影響最後一個JOIN,而不會影響其他結果,這就是爲什麼您要返回所有行。

爲了解決這個問題,添加一個WHERE下列條款向您最初的SQL字符串:

SET @strSql = 'select r.resourceid, r.flag, r.note, r.Name, r.ContactName, 
... 
left outer join resourcelanguage lan on (r.resourceid = lan.resourceid) 
where 1 = 1' 

任何附加標準將被添加到您最初總是正確的(1=1WHERE條款,這應該正確地過濾結果。

注意:您當前的實現容易受到SQL Injection的影響。


編輯: 由於CityState在同一個表,一個按預期工作,而不是其他的,我不認爲這是關係到你的LEFT OUTER JOIN無法按預期工作。

相反,我認爲這與修整有關,這是針對State而不是針對City完成的。

首先,它不會對LTRIM,RTRIM做任何事情,然後檢查它是否爲IS NOT NULL。要麼是NULL要麼它不是,修剪不會改變這一點。

接下來,在您的動態SQL中,您可以調用TRIM函數。這不是一個內置的T-SQL函數,所以除非你有自己的用戶定義函數TRIM,否則這應該會給你一個運行時錯誤。

+0

+1:除了添加到引用'r'([resource])以外的任何表的'WHERE'子句的任何條件將有效地將相應的'LEFT OUTER JOIN'變爲'INNER JOIN' 。 – RBarryYoung

+0

這可能是我遇到的新問題,當我只通過城市搜索時,它仍然給我正確的答案。但是,當我只搜索狀態。查詢返回db中的所有行,即使它不是正確的狀態。狀態來自asp窗體中的下拉列表。你知道如何解決這個問題嗎? – JerseyGirl1201

+0

@RBarryYoung好點,但由於額外的條件作爲過濾器,我的猜測是,將'LEFT OUTER JOIN'轉換爲'INNER JOIN'將是預期的行爲... –