| Author |
Topic |
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-24 : 12:06:04
|
Hi all,I have this stored procedure which works fine but I am unsure if I should be doing anything different to improve the overall efficiency of it or any other things that may need changing to shorten the code etc. It takes in some parameters from an ASP page and puts them through some conditional statements.Here it is:CREATE PROCEDURE [imagineDB].[sp_treatment] -- parameters @id int = 0, @ikeyword int = 0, @keyword nvarchar(100) = NULLASif @id <> 0 OR @ikeyword = 1 if @id <> 0 and @ikeyword = 0 begin SET NOCOUNT ON; SELECT id, pageTitle, description FROM ihcProcedures where id = @id order by pageTitle ASC end if @id = 0 and @ikeyword = 1 begin SET NOCOUNT ON; SELECT id, pageTitle, description FROM ihcProcedures where description like '%' + @keyword + '%' order by pageTitle ASC end if @id <> 0 and @ikeyword = 1 begin SET NOCOUNT ON; SELECT id, pageTitle, description FROM ihcProcedures where id = @id and description like '%' + @keyword + '%' order by pageTitle ASC endelse if @id = 0 and @ikeyword = 0 begin SET NOCOUNT ON; SELECT id, pageTitle, description FROM ihcProcedures order by pageTitle ASC endelse if @id = 0 and @ikeyword = 1 begin SET NOCOUNT ON; SELECT id, pageTitle, description FROM ihcProcedures where description like '%' + @keyword + '%' order by pageTitle ASC end thanks in advanceI want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2008-06-24 : 12:21:36
|
| 1. You only need to SET NOCOUNT ON once. Put it right after the AS after the CREATE PROC.2. I think you could do this all in one query since all that is changing is the WHERE clause and the parameters. All you need to do is put them all together and separate them with OR. Here's a start:WHERE (id = @id AND @id <> 0 and @ikeyword = 0) OR (...) OR (...) ...Tara KizerMicrosoft MVP for Windows Server System - SQL Serverhttp://weblogs.sqlteam.com/tarad/Subscribe to my blog |
 |
|
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-24 : 17:22:30
|
Thanks, I've moved no count out, could I put the following in a parameter:SELECT id, pageTitle, description FROM ihcProcedures where id ie @sql?I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2008-06-24 : 17:26:22
|
| I don't understand your question. If you are referring to dynamic SQL, then it is not needed here. It should rarely be used for security and performance reasons.Tara KizerMicrosoft MVP for Windows Server System - SQL Serverhttp://weblogs.sqlteam.com/tarad/Subscribe to my blog |
 |
|
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-25 : 04:10:14
|
| Yes that's what I was referring to, thought it would make my code a bit neater.I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-25 : 04:17:10
|
quote: Originally posted by Cowboy Yes that's what I was referring to, thought it would make my code a bit neater.I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is.
why do you need all these if else conditions? i think you need only thisCREATE PROCEDURE [imagineDB].[sp_treatment] -- parameters @id int = 0, @ikeyword int = 0, @keyword nvarchar(100) = NULLASSET NOCOUNT ON;SELECT id, pageTitle, description FROM ihcProcedures WHERE (id = @id or @id = 0)AND (description like '%' + @keyword + '%' OR @ikeyword = 0)ORDER BY pageTitle ASCGO |
 |
|
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-25 : 06:44:39
|
Hi Visakh, that works, the only drawback is that it pulls back the description field when it is not used under one condition.I am not sure I totally understand:WHERE (id = @id or @id = 0) how does work when it returns all the results, does it do a where 0=0?I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-25 : 06:48:31
|
quote: Originally posted by Cowboy Hi Visakh, that works, the only drawback is that it pulls back the description field when it is not used under one condition.I am not sure I totally understand:WHERE (id = @id or @id = 0) how does work when it returns all the results, does it do a where 0=0?I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is.
it just checks if @id=0 and does the filter id = @id only when @id <>0 |
 |
|
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-25 : 07:13:18
|
I don't see why if the id was 0 it would not look for an id with a value of 0;wouldn't that make:WHERE (id = 0 or 0 = 0) I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-25 : 07:18:19
|
quote: Originally posted by Cowboy I don't see why if the id was 0 it would not look for an id with a value of 0?I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is.
so do you have records with id value 0? But your first posted code was not looking at it (you've not included id=@id in any conditions where @Id=0However if you want to check it also, you could give some other default value. may be -1 or NULLand use id=@Id or @Id IS NULL (or)id=@Id or @Id=-1 |
 |
|
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-25 : 07:25:22
|
No I don't have any o value id's, I just can't understand the logic in the OR statement I'm a simpleton from what I understand if @id was 0 the where statement would look like this:WHERE (id = 0 or 0 = 0) so it wouldn't find anything but it is actually returning all the records.I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-25 : 08:04:45
|
quote: Originally posted by Cowboy No I don't have any o value id's, I just can't understand the logic in the OR statement I'm a simpleton from what I understand if @id was 0 the where statement would look like this:WHERE (id = 0 or 0 = 0) so it wouldn't find anything but it is actually returning all the records.I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is.
It will return all records as it will evaluate second condition even if first fails as its an OR |
 |
|
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-25 : 09:10:39
|
quote: It will return all records as it will evaluate second condition even if first fails as its an OR
so is it returning all the records because 0=0 in this case?I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-25 : 09:36:01
|
quote: Originally posted by Cowboy
It will return all records as it will evaluate second condition even if first fails as its an OR[/quote]so is it returning all the records because 0=0 in this case?I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is.[/quote]yup. Exactly |
 |
|
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-25 : 09:55:08
|
| Thanks Visakh, just another quick question would this be protected from SQL injection? I have tried '1 or '1' = '1' on my ASP page and it generates an SQL error worringly.I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2008-06-25 : 12:30:41
|
quote: Originally posted by Cowboy Thanks Visakh, just another quick question would this be protected from SQL injection? I have tried '1 or '1' = '1' on my ASP page and it generates an SQL error worringly.
You won't have any SQL injection issues with this code, but you could if you went down the dynamic SQL approach.Check my recent blog article for new MS tools that allow you to check for SQL injection vulnerabilities and specifically in ASP code.Tara KizerMicrosoft MVP for Windows Server System - SQL Serverhttp://weblogs.sqlteam.com/tarad/Subscribe to my blog |
 |
|
|
contrari4n
Starting Member
27 Posts |
Posted - 2008-06-25 : 18:42:01
|
One problem with this solution is that it will perform an index scan.All columns in an OR condition must be indexed to avoid this, but @id is a parameter and therefore not indexed! This means that or @id = 0 will force a scan of the index.Richard Fryarhttp://www.sql-server-pro.comSQL Server Articles and Tips |
 |
|
|
Cowboy
Yak Posting Veteran
72 Posts |
Posted - 2008-06-26 : 06:50:34
|
quote: Originally posted by contrari4n One problem with this solution is that it will perform an index scan.All columns in an OR condition must be indexed to avoid this, but @id is a parameter and therefore not indexed! This means that or @id = 0 will force a scan of the index.Richard Fryarhttp://www.sql-server-pro.comSQL Server Articles and Tips
Well the table is pretty small so an index scan wouldn't be too much of an issue, but I would like to avoid it if possible. Is there any way to index a parameter?I want to build a spaceship with ligthspeed capabilities and I don't even know what a wrench is. |
 |
|
|
contrari4n
Starting Member
27 Posts |
Posted - 2008-06-26 : 08:44:05
|
| Unfortunately not.There is no elegant solution to this problem. I normally revert to dynamic SQL, but make sure I am using sp_executesql to ensure reuse of execution plans.As mentioned above, you should test, test and retest to make sure there is no danger of SQL injection.Richard Fryarhttp://www.sql-server-pro.comSQL Server Articles and Tips |
 |
|
|
|