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
4

1 回答 1

2

问题是您的过滤器没有添加到WHERE子句中,而是作为条件添加到您的最后一个LEFT OUTER JOIN. 如果不满足条件,它只会影响 last 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=1)WHERE子句中,这应该正确过滤结果。

注意:您当前的实现容易受到SQL 注入的影响。


编辑:由于CityState在同一张桌子上,一个按预期工作,另一个按预期工作,我认为这与您LEFT OUTER JOIN没有按预期工作无关。

相反,我认为这与针对State但不针对City.

LTRIM首先,它对,RTRIM检查是否它之前的值没有任何作用IS NOT NULL。要么是,要么NULL不是,修剪不会改变这一点。

接下来,在您的动态 SQL 中,您调用一个TRIM函数。这不是内置的 T-SQL 函数,因此除非您有自己的用户定义函数,否则TRIM这实际上应该给您一个运行时错误。

于 2013-07-08T15:08:49.303 回答