Reputation: 11
I am trying to write a dynamic query. The search criteria will come from an ASP page and be passed over to a stored procedure in the SQL Server 2005 Express database. The search is not giving any errors but it returns all data in the database and does not filter based on the variables. someone please help?
I am posting the stored procedure here:
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
Upvotes: 1
Views: 1488
Reputation: 37388
The problem is that your filters aren't being added to a WHERE
clause, and instead are being added as conditions to your last LEFT OUTER JOIN
. When the criteria isn't met, it is only affecting that last JOIN
, and not your other results, which is why you're getting all rows returned.
To fix this, add a WHERE
clause following to your initial SQL string:
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'
Any additional criteria will be added to your initially always true (1=1
) WHERE
clause, this should properly filter results.
NOTE: Your current implementation is vulnerable to SQL Injection.
EDIT:
Since City
and State
are in the same table, and one works as expected and not the other, I don't think this is related to your LEFT OUTER JOIN
not working as expected.
Instead, I'm thinking it has something to do with the trimming that is done against State
but not against City
.
First, it doesn't do anything to LTRIM
, RTRIM
the value before checking if it IS NOT NULL
. Either it's NULL
or it isn't, and trimming won't change that.
Next, in your dynamic SQL, you call a TRIM
function. This isn't a built in T-SQL function, so unless you have your own user defined function called TRIM
, this should actually be giving you a run-time error.
Upvotes: 2