我正在尝试编写动态查询。搜索条件将来自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 :(得分:2)
问题是您的过滤器未添加到WHERE
子句中,而是作为条件添加到您的上一个LEFT OUTER JOIN
。如果未满足条件,则仅影响最后JOIN
,而不影响其他结果,这就是您返回所有行的原因。
要解决此问题,请在初始SQL字符串后添加WHERE
子句:
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 Injection的攻击。</ p>
编辑:
由于City
和State
位于同一个表中,并且其中一个按预期工作而不是另一个,我认为这与您的LEFT OUTER JOIN
无法正常工作有关。
相反,我认为它与针对State
但不针对City
的修剪有关。
首先,在检查LTRIM
之前,它对RTRIM
,IS NOT NULL
没有任何作用。无论是NULL
还是不是,修剪都不会改变它。
接下来,在动态SQL中,调用TRIM
函数。这不是内置的T-SQL函数,所以除非你有自己的用户定义函数TRIM
,否则这实际上应该给你一个运行时错误。