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
 General SQL Server Forums
 New to SQL Server Programming
 Stored procedure best practice

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) = NULL
AS

if @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
end

else

if @id = 0 and @ikeyword = 0
begin
SET NOCOUNT ON;
SELECT id, pageTitle, description FROM ihcProcedures order by pageTitle ASC
end

else

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 advance

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 : 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 Kizer
Microsoft MVP for Windows Server System - SQL Server
http://weblogs.sqlteam.com/tarad/

Subscribe to my blog
Go to Top of Page

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.
Go to Top of Page

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 Kizer
Microsoft MVP for Windows Server System - SQL Server
http://weblogs.sqlteam.com/tarad/

Subscribe to my blog
Go to Top of Page

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.
Go to Top of Page

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 this


CREATE PROCEDURE [imagineDB].[sp_treatment]
-- parameters
@id int = 0,
@ikeyword int = 0,
@keyword nvarchar(100) = NULL
AS
SET NOCOUNT ON;
SELECT id, pageTitle, description
FROM ihcProcedures
WHERE (id = @id or @id = 0)
AND (description like '%' + @keyword + '%' OR @ikeyword = 0)
ORDER BY pageTitle ASC
GO
Go to Top of Page

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.
Go to Top of Page

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
Go to Top of Page

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.
Go to Top of Page

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=0
However if you want to check it also, you could give some other default value. may be -1 or NULL
and use
id=@Id or @Id IS NULL
(or)

id=@Id or @Id=-1
Go to Top of Page

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.
Go to Top of Page

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
Go to Top of Page

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.
Go to Top of Page

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
Go to Top of Page

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.
Go to Top of Page

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 Kizer
Microsoft MVP for Windows Server System - SQL Server
http://weblogs.sqlteam.com/tarad/

Subscribe to my blog
Go to Top of Page

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 Fryar
http://www.sql-server-pro.com
SQL Server Articles and Tips
Go to Top of Page

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 Fryar
http://www.sql-server-pro.com
SQL 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.
Go to Top of Page

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 Fryar
http://www.sql-server-pro.com
SQL Server Articles and Tips
Go to Top of Page
   

- Advertisement -