Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing SQL stored procedure entirety of WHERE clause

Tags:

sql

sql-server

I have a SQL stored procedure of the form

SELECT [fields] FROM [table] WHERE @whereSql

I want to pass the procedure an argument (@whereSql) which specifies the entire WHERE clause, but the following error is returned:

An expression of non-boolean type specified in a context where a condition is expected

Can this be done?

like image 792
alpheus Avatar asked Jun 21 '10 14:06

alpheus


People also ask

Can I use stored procedure in where clause?

You can not use Stored Procedure in where clause but can use User Defined Function in where clause. If you cant convert SP to function then you have to first get bit value from executing SP and use that variable in where clause..

How do you pass where clause as a parameter in SQL Server?

SQL Server does not support "parameterizing" the WHERE clause or any syntactic construct. You have to construct the SQL String using string concatenation operations and then execute the constructed string using the dynamic EXEC statement.

Can we pass parameter to stored procedure in SQL?

You can also pass parameters to a stored procedure, so that the stored procedure can act based on the parameter value(s) that is passed.

Can we pass a list to a stored procedure in SQL Server?

There are several ways to do this. While using older versions of SQL Server, I've used to the XML method to pass array or list to stored procedure. In the latest versions of SQL Server, we can use the User Defined Data Type (UDT) with a base type of table to send array or list through a parameter.


3 Answers

The short answer is that you can't do it like this -- SQL Server looks at the contents of a variable as a VALUE. It doesn't dynamically build up the string to execute (which is why this is the correct way to avoid SQL injection attacks).

You should make every effort to avoid a dynamic WHERE as you're trying to do, largely for this reason, but also for the sake of efficiency. Instead, try to build up the WHERE clause so that it short-circuits pieces with lots of ORs, depending on the situation.

If there's no way around it, you can still build a string of your own assembled from the pieces of the command, and then EXEC it.

So you could do this:

DECLARE @mywhere VARCHAR(500)
DECLARE @mystmt VARCHAR(1000)
SET @mywhere = ' WHERE MfgPartNumber LIKE ''a%'' '
SELECT @mystmt = 'SELECT TOP 100 * FROM Products.Product AS p ' + @mywhere + ';'
EXEC( @mystmt )

But I recommend instead that you do this:

SELECT TOP 100 * 
    FROM Products.Product AS p 
    WHERE 
        ( MfgPartNumber LIKE 'a%' AND ModeMfrPartNumStartsWith=1)
    OR  ( CategoryID = 123 AND ModeCategory=1 )
like image 65
Chris Wuestefeld Avatar answered Oct 12 '22 22:10

Chris Wuestefeld


I believe this can be done using Dynamic SQL. See below:

CREATE PROCEDURE [dbo].[myProc]
@whereSql nvarchar(256)

AS
    EXEC('SELECT [fields] FROM [table] WHERE ' + @whereSql)
GO

That said, you should do some serious research on dynamic SQL before you actually use it. Here are a few links that I came across after a quick search:

  • http://www.sommarskog.se/dynamic_sql.html

  • http://msdn.microsoft.com/en-us/library/aa224806%28SQL.80%29.aspx

  • http://www.itjungle.com/fhg/fhg100505-story02.html

like image 27
Abe Miessler Avatar answered Oct 12 '22 22:10

Abe Miessler


Make sure you read this fully

www.sommarskog.se/dynamic_sql.html

like image 32
Madhivanan Avatar answered Oct 13 '22 00:10

Madhivanan