Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Help with SELECT

Author  Topic 

Jakes Daddy
Starting Member

7 Posts

Posted - 2006-04-24 : 10:09:23
Hi,
First posting, so please go easy on me !

I am writing a stored procedure that takes a series of input parameters and executes a SELECT statement using them in the WHERE clause:

SET @ISBN = '%' + @ISBN + '%'
SET @TITLE= '%' + @TITLE+ '%'
SET @AUTHOR= '%' + @AUTHOR+ '%'

SELECT ISBN, TITLE, AUTHOR
FROM BOOKS
WHERE
ISBN LIKE @ISBN OR
TITLE LIKE @TITLE OR
AUTHOR LIKE @AUTHOR

(@ISBN, @TITLE and @AUTHOR are the input params of the stored proc)

The code works fine (ish ), but the problem is that if the proc is called with empty values for any of the params, the query returns all records (as you would expect as the query would effectively be WHERE ISBN LIKE %% ....)
I can understand why this is happening, but am looking for a way round this.

Basically I what I'm trying to achieve is a search where the user can enter as much or as little detail as required - they might enter author details, or title details, or both, or ISBN, or .... you get the idea

I need to do this as a stored proc as I need to help prevent SQL injections, and for the same reason I really dont want to compose a string of the SELECT command and EXECUTE it within the SP

I think I need to use CASE statements in the WHERE clauses - but not really sure how it would be structured.

Any help with this would be very much appreciated,

TIA

Nathan

PSamsig
Constraint Violating Yak Guru

384 Posts

Posted - 2006-04-24 : 10:31:22
Using AND instead of OR would be a start
Go to Top of Page

Srinika
Master Smack Fu Yak Hacker

1378 Posts

Posted - 2006-04-24 : 10:34:13
Create ur "Where clause" Seperately and use Dynamic SQL

eg.

...


if @ISBN is not null
Set @Where = ' ISBN LIKE @ISBN OR'
.....
.....

Set @Where = ' Where ' + @Where + ' 1=0'

Execute ('SELECT ISBN, TITLE, AUTHOR FROM BOOKS ' + @Where )



Srinika
Go to Top of Page

Jakes Daddy
Starting Member

7 Posts

Posted - 2006-04-24 : 10:48:32
quote:
Originally posted by Srinika

Create ur "Where clause" Seperately and use Dynamic SQL

eg.

...


if @ISBN is not null
Set @Where = ' ISBN LIKE @ISBN OR'
.....
.....

Set @Where = ' Where ' + @Where + ' 1=0'

Execute ('SELECT ISBN, TITLE, AUTHOR FROM BOOKS ' + @Where )



Srinika




From my original posting:
quote:
I need to do this as a stored proc as I need to help prevent SQL injections, and for the same reason I really dont want to compose a string of the SELECT command and EXECUTE it within the SP

I am sure the answer to this is CASE - any other help with this ?
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2006-04-24 : 10:51:49
See if this helps
http://www.sqlteam.com/item.asp?ItemID=2077

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

RyanRandall
Master Smack Fu Yak Hacker

1074 Posts

Posted - 2006-04-24 : 10:58:13
Hi Jakes,

It's not clear (to me at least) what behaviour it is you want. If you can describe it, I think think you'll get what you need.

For example...

a) What behaviour do you want when all inputs are 'blank'?
b) What behaviour do you want when both isbn and title have values? (either one or the other or both criteria should be met?)

And, by the way, what is the value of isbn when it has an 'empty value'?


Ryan Randall
www.monsoonmalabar.com London-based IT consultancy

Solutions are easy. Understanding the problem, now, that's the hard part.
Go to Top of Page

PSamsig
Constraint Violating Yak Guru

384 Posts

Posted - 2006-04-24 : 10:58:41
Do i really have to repeat my self ?
Go to Top of Page

Jakes Daddy
Starting Member

7 Posts

Posted - 2006-04-24 : 11:16:46
Ryan,
Yes, good question; I should explain my requirements a little better.

OK, I have a web application that is backed by a database. Within the database is this table (BOOKS), which (no prizes for guessing ...) contains records about books !
I am writing a page for the web site which allows the user to search the BOOKS table. I am presenting the following HTML input fields: title, author, and ISBN

I would like the user to be able to search on any combination of fields, and I want to do OR matching (this bit is for you PSamsig !)
If the user enters just something in the title field, the WHERE clause should be just WHERE TITLE LIKE @TITLE. The same goes for author and ISBN
If the user enters details into title and author, the WHERE clause should be WHERE TITLE LIKE @TITLE OR AUTHOR LIKE @AUTHOR
The reason I want to use OR (PSamsig !!) is that I want to show results where the user has entered something in any 2 fields that do not match. EG. They enter 'SQL' in the title field, and 'Jakes Daddy' in the author field. I have not written any SQL books, but there are lots of SQL books in my database, as there are lots of books by the author 'Jakes Daddy'. I want to display books that match either SQL or that were written by Jakes Daddy - not nothing (which an AND would produce).
(And the final comment on the AND/OR - I know the difference between the two and have decided to use OR - thank you !)

Phew, out of rant mode ! Back to normal ....

If the user does not enter a value for a given field on the web page, I would imagine that it is presented to the SP as an empty string rather than a null (but I dont know that for sure)

Hope this helps understand my requirements a little better .... over you guys !

Thanks again

Nathan
Go to Top of Page

RyanRandall
Master Smack Fu Yak Hacker

1074 Posts

Posted - 2006-04-24 : 11:37:20
Wow, you managed to write all that and I still don't see an answer to a)

Ryan Randall
www.monsoonmalabar.com London-based IT consultancy

Solutions are easy. Understanding the problem, now, that's the hard part.
Go to Top of Page

PSamsig
Constraint Violating Yak Guru

384 Posts

Posted - 2006-04-24 : 11:45:32
I think I get it, dynamic SQL would be the easy answer, static is something I have to think about (never yet used COALESCE() before, maybe now is the time)
Go to Top of Page

Jakes Daddy
Starting Member

7 Posts

Posted - 2006-04-24 : 11:52:08
quote:
Originally posted by RyanRandall

Wow, you managed to write all that and I still don't see an answer to a)

Ryan Randall
www.monsoonmalabar.com London-based IT consultancy

Solutions are easy. Understanding the problem, now, that's the hard part.


Whoops ! Yes, forgot to answer that one
Basically it would never happen. The server side code of the webpage checks for any one of the input values - if all are blank it does nothing but represent the web form. If any one of the fields have a value, the stored proc is called with all fields from the form (even the 'empty' ones) as params to the SP. (hence my thinking that 'empty' values are sent as an empty string "", and not nulls)

Nathan
Go to Top of Page

jen
Master Smack Fu Yak Hacker

4110 Posts

Posted - 2006-04-24 : 11:52:17
pass the value of your criteria as is... append the % inside the sproc
null + any string = null

so your criteria would be field1 like null which is false
--edit
i forgot... nullify if space... nullif(@variable,'')

--------------------
keeping it simple...
Go to Top of Page

PSamsig
Constraint Violating Yak Guru

384 Posts

Posted - 2006-04-24 : 11:53:48
Nope, no COALESCE() this time either

SELECT ISBN, TITLE, AUTHOR
FROM BOOKS
WHERE
ISBN LIKE CASE WHEN @ISBN = '' THEN NULL ELSE '%' + @ISBN + '%' END
OR
TITLE LIKE CASE WHEN @TITLE = '' THEN NULL ELSE '%' + @TITLE + '%' END
OR
AUTHOR LIKE CASE WHEN @AUTHOR = '' THEN NULL ELSE '%' + @AUTHOR + '%' END
Go to Top of Page

RyanRandall
Master Smack Fu Yak Hacker

1074 Posts

Posted - 2006-04-24 : 12:01:19
There's some proof of my sig if ever I saw it.

Ryan Randall
www.monsoonmalabar.com London-based IT consultancy

Solutions are easy. Understanding the problem, now, that's the hard part.
Go to Top of Page

Jakes Daddy
Starting Member

7 Posts

Posted - 2006-04-24 : 12:01:26
PSamsig - that looks sweet - I knew CASE would solve it, just could not work out the syntax myself (bit of a newbie you see !)
I'll give that a go shortly, but I'm sure that looks sound.
Thanks (and sorry for giving you a bit of a flamer earlier on !!)

Nathan
Go to Top of Page

Jakes Daddy
Starting Member

7 Posts

Posted - 2006-04-24 : 16:16:16
OK, me again !
So, the suggestion by PSamsig is working a charm - excellent. I've added a few fields (as I do !), and my code now looks like:
SELECT ISBN, TITLE, 
CASE WHEN AUTHOR='' THEN 'Not Specified' ELSE AUTHOR END AS AUTHOR,
CASE WHEN PUBLISHER='' THEN 'Not Specified' ELSE PUBLISHER END AS PUBLISHER,
FROM BOOKS
WHERE (
ISBN LIKE CASE WHEN @Isbn='' THEN NULL ELSE '%'+@Isbn+'%' END OR
TITLE LIKE CASE WHEN @Title='' THEN NULL ELSE '%'+@Title+'%' END OR
AUTHOR LIKE CASE WHEN @Author='' THEN NULL ELSE '%'+@Author+'%' END OR
PUBLISHER LIKE CASE WHEN @Publisher='' THEN NULL ELSE '%'+@Publisher+'%' END OR
REVIEWS LIKE CASE WHEN @ReviewTxt='' THEN NULL ELSE '%'+@ReviewTxt+'%' END
)
AND TITLE IS NOT NULL

All working perfectly - but hey, I wanna add to it !
I'm now passing a new parameter into the SP - @L_operator - its the logical operator for the WHERE clause, and its either 'AND' or 'OR' - basically in the query where I am currently doing an OR, I want to use @L_operator (on top of all the functionality you guys have already helped me with !)
Can I work out the correct CASE statement for this ? Can I 'eck !

As before, any help with this would very much be appreciated,
Thanks

Nathan
Go to Top of Page

jen
Master Smack Fu Yak Hacker

4110 Posts

Posted - 2006-04-24 : 21:28:29
ok paper and pencil method (not tested)...

where case when @operator='or' then the rest of your criteria...
else the 'and' criteria
end

otherwise it will be easier for you to construct the dsql inside the sproc and play around with that... but my assumption, since this is a search, you will need to consider performance and speed of retrieval, doing the way you are doing it just slows things down...

if you keep on going along this line of solutioning, then you'll get into a huff when after 1 year you go back to this sproc and try to modify it, it'll be easier to create separate sprocs now or do the filtering in your apps

but that's me

--------------------
keeping it simple...
Go to Top of Page

PSamsig
Constraint Violating Yak Guru

384 Posts

Posted - 2006-04-25 : 02:04:59
Oh why not humor him :)

SELECT ISBN, TITLE,
CASE WHEN AUTHOR='' THEN 'Not Specified' ELSE AUTHOR END AS AUTHOR,
CASE WHEN PUBLISHER='' THEN 'Not Specified' ELSE PUBLISHER END AS PUBLISHER,
FROM BOOKS
WHERE (
ISBN LIKE CASE WHEN @L_operator = 'AND' OR @Isbn='' THEN NULL ELSE '%'+@Isbn+'%' END OR
TITLE LIKE CASE WHEN @L_operator = 'AND' OR @Title='' THEN NULL ELSE '%'+@Title+'%' END OR
AUTHOR LIKE CASE WHEN @L_operator = 'AND' OR @Author='' THEN NULL ELSE '%'+@Author+'%' END OR
PUBLISHER LIKE CASE WHEN @L_operator = 'AND' OR @Publisher='' THEN NULL ELSE '%'+@Publisher+'%' END OR
REVIEWS LIKE CASE WHEN @L_operator = 'AND' OR @ReviewTxt='' THEN NULL ELSE '%'+@ReviewTxt+'%' END
) AND
ISBN LIKE CASE WHEN @L_operator = 'OR' OR @Isbn='' THEN ISBN ELSE '%'+@Isbn+'%' END AND
TITLE LIKE CASE WHEN @L_operator = 'OR' OR @Title='' THEN TITLE ELSE '%'+@Title+'%' END AND
AUTHOR LIKE CASE WHEN @L_operator = 'OR' OR @Author='' THEN AUTHOR ELSE '%'+@Author+'%' END AND
PUBLISHER LIKE CASE WHEN @L_operator = 'OR' OR @Publisher='' THEN PUBLISHER ELSE '%'+@Publisher+'%' END AND
REVIEWS LIKE CASE WHEN @L_operator = 'OR' OR @ReviewTxt='' THEN REVIEWS ELSE '%'+@ReviewTxt+'%' END
AND TITLE IS NOT NULL



--
This one's tricky. You have to use calculus and imaginary numbers for this. You know, eleventeen, thirty-twelve and all those.
Go to Top of Page

Jakes Daddy
Starting Member

7 Posts

Posted - 2006-04-25 : 08:07:27
Thanks guys for your comments.
PSamsig - couldn't quite get your solution to work, but eventually got it going like this:
  IF @L_operator='OR'  BEGIN
-- select statement for OR
SELECT ISBN, TITLE,
CASE WHEN AUTHOR='' THEN 'Not Specified' ELSE AUTHOR END AS AUTHOR,
CASE WHEN PUBLISHER='' THEN 'Not Specified' ELSE PUBLISHER END AS PUBLISHER
FROM BOOKS
WHERE (
ISBN LIKE CASE WHEN @Isbn<>'' THEN '%'+@Isbn+'%' ELSE NULL END OR
TITLE LIKE CASE WHEN @Title<>'' THEN '%'+@Title+'%' ELSE NULL END OR
AUTHOR LIKE CASE WHEN @Author<>'' THEN '%'+@Author+'%' ELSE NULL END OR
PUBLISHER LIKE CASE WHEN @Publisher<>'' THEN '%'+@Publisher+'%' ELSE NULL END OR
REVIEWS LIKE CASE WHEN @ReviewTxt<>'' THEN '%'+@ReviewTxt+'%' ELSE NULL END
)
AND TITLE IS NOT NULL
END
ELSE BEGIN
-- select statement for AND
SELECT ISBN, TITLE,
CASE WHEN AUTHOR='' THEN 'Not Specified' ELSE AUTHOR END AS AUTHOR,
CASE WHEN PUBLISHER='' THEN 'Not Specified' ELSE PUBLISHER END AS PUBLISHER
FROM BOOKS
WHERE (
ISBN LIKE CASE WHEN @Isbn<>'' THEN '%'+@Isbn+'%' ELSE '%%' END AND
TITLE LIKE CASE WHEN @Title<>'' THEN '%'+@Title+'%' ELSE '%%' END AND
AUTHOR LIKE CASE WHEN @Author<>'' THEN '%'+@Author+'%' ELSE '%%' END AND
PUBLISHER LIKE CASE WHEN @Publisher<>'' THEN '%'+@Publisher+'%' ELSE '%%' END AND
REVIEWS LIKE CASE WHEN @ReviewTxt<>'' THEN '%'+@ReviewTxt+'%' ELSE '%%' END
)
AND TITLE IS NOT NULL
END

It works (so I'm happy with it), but I can see that its perhaps a bit messy/amatuer/not ideal

I am however intrigued by the suggestions to use dynamic sql - build a string of the SQL I want to run, then call it with EXECUTE

I was under the impression that this is generally a bad idea ??? I want to prevent SQL injection attacks, and isn't there something about SQL execution plans or something ???

As you can tell, I am a complete novice with this stuff, and I bow to your superior knowledge. I would just be interested to a) hear why dsql was suggested and b) if my concerns about dsql are valid ?

Thanks again

Nathan
Go to Top of Page

PSamsig
Constraint Violating Yak Guru

384 Posts

Posted - 2006-04-25 : 11:03:48
Ok I made a little mistake and I didnt take NULLs into account either, but here is the ultimate oneliner (tested this time)

SELECT ISBN, TITLE,
CASE WHEN AUTHOR='' THEN 'Not Specified' ELSE AUTHOR END AS AUTHOR,
CASE WHEN PUBLISHER='' THEN 'Not Specified' ELSE PUBLISHER END AS PUBLISHER
FROM BOOKS
WHERE (
ISBN LIKE CASE WHEN @L_operator = 'AND' OR @Isbn='' THEN NULL ELSE '%'+@Isbn+'%' END OR
TITLE LIKE CASE WHEN @L_operator = 'AND' OR @Title='' THEN NULL ELSE '%'+@Title+'%' END OR
AUTHOR LIKE CASE WHEN @L_operator = 'AND' OR @Author='' THEN NULL ELSE '%'+@Author+'%' END OR
PUBLISHER LIKE CASE WHEN @L_operator = 'AND' OR @Publisher='' THEN NULL ELSE '%'+@Publisher+'%' END OR
REVIEWS LIKE CASE WHEN @L_operator = 'AND' OR @ReviewTxt='' THEN NULL ELSE '%'+@ReviewTxt+'%' END OR
@L_operator = 'AND'
) AND
COALESCE(ISBN, '') LIKE CASE WHEN @L_operator = 'OR' OR @Isbn='' THEN COALESCE(ISBN, '') ELSE '%'+@Isbn+'%' END AND
COALESCE(TITLE, '') LIKE CASE WHEN @L_operator = 'OR' OR @Title='' THEN COALESCE(TITLE, '') ELSE '%'+@Title+'%' END AND
COALESCE(AUTHOR, '') LIKE CASE WHEN @L_operator = 'OR' OR @Author='' THEN COALESCE(AUTHOR, '') ELSE '%'+@Author+'%' END AND
COALESCE(PUBLISHER, '') LIKE CASE WHEN @L_operator = 'OR' OR @Publisher='' THEN COALESCE(PUBLISHER, '') ELSE '%'+@Publisher+'%' END AND
COALESCE(REVIEWS, '') LIKE CASE WHEN @L_operator = 'OR' OR @ReviewTxt='' THEN COALESCE(REVIEWS, '') ELSE '%'+@ReviewTxt+'%' END
AND TITLE IS NOT NULL

If it looks messy/amatuer/not ideal then its my fault, but it is a static (somewhat at least) SELECT, the good question here is (and I am not qualified to answer this) if this actually can be compiled into one execution plan, someone ?

--
This one's tricky. You have to use calculus and imaginary numbers for this. You know, eleventeen, thirty-twelve and all those.
Go to Top of Page

pootle_flump

1064 Posts

Posted - 2006-04-26 : 04:04:59
quote:
Originally posted by Jakes Daddy
I am however intrigued by the suggestions to use dynamic sql - build a string of the SQL I want to run, then call it with EXECUTE

I was under the impression that this is generally a bad idea ??? I want to prevent SQL injection attacks, and isn't there something about SQL execution plans or something ???

As you can tell, I am a complete novice with this stuff, and I bow to your superior knowledge. I would just be interested to a) hear why dsql was suggested and b) if my concerns about dsql are valid ?

Thanks again

Nathan

Hi Nathan

If you look up the entry in BOL for sp_executesql you'll see that it accepts parameters (making it more secure) and the query results in an execution plan. In fact this article shows how you can use the sproc to create multiple plans for ostensibly the same query:
http://www.sqljunkies.com/WebLog/amachanic/articles/StoredProcedureCaching.aspx

HTH
Go to Top of Page
    Next Page

- Advertisement -