Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating Where Clause based on variables passed to stored proc

Status
Not open for further replies.

Clanger67

Programmer
Mar 28, 2002
28
GB
I have a stored procedure into which I want to pass variables and depending on the value of the variable passed into I want to be able to change the Where clause.

I keep getting an error:
[red]Incorrect syntax near the keyword 'WHERE'[/red]

Any help would be much appreciated

Code:
 @InvoiceStatus AS Int,
 @CAADiv AS varChar(15) = NULL,
 @RegNo AS varChar(8) = NULL,
 @PolicyHolder AS varChar(150) = NULL,
 @Repairer AS varChar(150) = NULL

AS

SET NOCOUNT ON;

BEGIN
DECLARE @Where AS varChar(500);
SET @Where = 'R.dCompleted IS NOT NULL'

--AND (@CAADiv = '0' OR RN.FormRef LIKE @CAADiv + '%')
IF @CAADiv = '1'
	SET @Where = @Where + 'AND RN.FormRef LIKE CAA' + '%'
ELSE 
	IF @CAADiv = '2'
		SET @Where = @Where + 'AND RN.FormRef LIKE ENS' + '%' + ' OR RN.FormRef LIKE ETP'+ '%'
	ELSE
		IF @CAADiv = '3'
			SET @Where = @Where + 'AND RN.FormRef LIKE MIT' + '%' 
		ELSE
			IF @CAADiv = '4'
				SET @Where = @Where + 'AND RN.FormRef LIKE EVR' + '%'  
			ELSE
				IF @CAADiv = '5'
					SET @Where = @Where + 'AND RN.FormRef LIKE FLT' + '%'  
				ELSE
					IF @CAADiv = '6' 
						SET @Where = @Where + 'AND RN.FormRef LIKE MCM' + '%' 
					ELSE
						IF @CAADiv = '7' 
							SET @Where = @Where + 'AND RN.FormRef LIKE SUM' + '%' 
						ELSE
							IF @CAADiv = '8'
								SET @Where = @Where + 'AND RN.FormRef LIKE ASL' + '%'  
							ELSE
								IF @CAADiv = '9'
									SET @Where = @Where + 'AND RN.FormRef LIKE APD' + '%'  
								ELSE
									SET @Where = @Where + 'AND RN.FormRef = 0' 

--All Option selected
IF @InvoiceStatus = '0'
	SET @Where = @Where + 'AND rac.FullyAllocated = 0 OR rac.FullyAllocated = 1 OR rac.FullyAllocated IS NULL '
	--SET @InvoiceStatus = ''
ELSE
	--History Option selected
	IF @InvoiceStatus = '2'
		SET @Where = @Where + 'AND rac.FullyAllocated = 1 '
		--SET @InvoiceStatus = '1'
	ELSE
		--Open Option selected
		SET @Where = @Where + 'AND rac.FullyAllocated = 0 OR rac.FullyAllocated IS NULL '

SELECT R.ID AS RepairID,RN.FormRef AS Reference, V.RegNo,Cust.Name AS PolicyHolder, 
Repairer.Name AS Repairer, R.CurrentStatus, 
(Sum(RAC.TotalValue) - Isnull(Sum(RAC2RAI.Allocated) ,0)) AS TotalInvAwaiting, 
Isnull(Sum(RAC2RAI.Allocated) ,0) as TotalInvReceived, 
min(CASE WHEN (rac.FullyAllocated IS NULL OR rac.FullyAllocated = 0) THEN Rac.dDue ELSE NULL END) AS dDue 

FROM RepairAssociatedCost RAC INNER JOIN Repair R ON R.ID = RAC.RepairID 
INNER JOIN RepairNotification RN ON RN.ID = R.RepairNotificationID 
INNER JOIN Vehicle V ON V.ID = R.VehicleID 
LEFT JOIN Notification N ON N.ID = R.NotificationID 
LEFT JOIN Company Cust ON (Cust.ID = N.CustomerID OR Cust.ID = RN.CustomerID) 
INNER JOIN Company Repairer On Repairer.ID = R.RepairerCompanyID 
LEFT JOIN (Select RACostID, Sum(Amount) AS Allocated 
FROM RAC2RAI GROUP BY RACostID) RAC2RAI ON RAC2RAI.RACostID = RAC.ID 

SET @Where = @Where + 'AND (@RegNo = '' OR RegNo = @RegNo) '
SET @Where = @Where + 'AND (@PolicyHolder = 0 OR Cust.Name = @PolicyHolder) '
SET @Where = @Where + 'AND (@Repairer = 0 OR Repairer.Name = @Repairer)'

[highlight]WHERE @Where = @Where[/highlight]

GROUP BY R.ID , RN.FormRef, V.RegNo,Cust.Name,Repairer.Name,R.CurrentStatus 
ORDER BY RN.FormRef
END

Thanks very much

David
 
No you can't do that. A variable can be used as a placeholder for a value in your SQL statement, but not a placeholder for the SQL syntax. Without trying to figure out your entire query, you are going to have to either case statements or a bunch of if statements.
 
If you want to continue building your query like you are doing, you would have to execute you query using dynamic sql. I wouldn't recommend that approach though, and would suggest looking up the CASE method.


-------------------------------------------------------

Mark,
[URL unfurl="true"]http://aspnetlibrary.com[/url]
[URL unfurl="true"]http://mdssolutions.co.uk[/url] - Delivering professional ASP.NET solutions
[URL unfurl="true"]http://weblogs.asp.net/marksmith[/url]
 
That is what Mark was talking about - dynamic SQL. It's not recommended, but the 30,000 foot view of it is that you submit a string to SQL Server to execute. The first thing that comes to mind is that your Select logic is not part of the string, and you aren't instructing the server to execute the string. Did you notice the EXEC statement in that article? That's where the magic happens.
 
Mark and RiverGuy

Thanks again and I will go and have a play with the CASE WHEN and see how I get on

Cheers

David
 
I was taking a look at this, and I see some (not so obvious) problems that may cause this to return the wrong data.

First of all, the nested IF's are a little messy. I would replace them with a case statement. Logic-wise, it's the same thing, but the case syntax is easier to read, which will likely make the code easier to maintain.

You can replace this...
[tt][blue]
IF @CAADiv = '1'
SET @Where = @Where + 'AND RN.FormRef LIKE CAA' + '%'
ELSE
IF @CAADiv = '2'
SET @Where = @Where + 'AND RN.FormRef LIKE ENS' + '%' + ' OR RN.FormRef LIKE ETP'+ '%'
ELSE
IF @CAADiv = '3'
SET @Where = @Where + 'AND RN.FormRef LIKE MIT' + '%'
ELSE
IF @CAADiv = '4'
SET @Where = @Where + 'AND RN.FormRef LIKE EVR' + '%'
ELSE
IF @CAADiv = '5'
SET @Where = @Where + 'AND RN.FormRef LIKE FLT' + '%'
ELSE
IF @CAADiv = '6'
SET @Where = @Where + 'AND RN.FormRef LIKE MCM' + '%'
ELSE
IF @CAADiv = '7'
SET @Where = @Where + 'AND RN.FormRef LIKE SUM' + '%'
ELSE
IF @CAADiv = '8'
SET @Where = @Where + 'AND RN.FormRef LIKE ASL' + '%'
ELSE
IF @CAADiv = '9'
SET @Where = @Where + 'AND RN.FormRef LIKE APD' + '%'
ELSE
SET @Where = @Where + 'AND RN.FormRef = 0'
[/blue][/tt]

With this:

Code:
[COLOR=blue]Select[/color] @Where = @Where 
                + [COLOR=blue]Case[/color] @CAADIV 
                    [COLOR=blue]When[/color] [COLOR=red]'1'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE CAA' + '%'[/color]
                    [COLOR=blue]When[/color] [COLOR=red]'2'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE ENS'[/color] + [COLOR=red]'%'[/color] + [COLOR=red]' OR RN.FormRef LIKE ETP'[/color]+ [COLOR=red]'%'[/color]
                    [COLOR=blue]When[/color] [COLOR=red]'3'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE MIT'[/color] + [COLOR=red]'%'[/color]
                    [COLOR=blue]When[/color] [COLOR=red]'4'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE EVR'[/color] + [COLOR=red]'%'[/color]  
                    [COLOR=blue]When[/color] [COLOR=red]'5'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE FLT'[/color] + [COLOR=red]'%'[/color]  
                    [COLOR=blue]When[/color] [COLOR=red]'6'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE MCM'[/color] + [COLOR=red]'%'[/color]
                    [COLOR=blue]When[/color] [COLOR=red]'7'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE SUM'[/color] + [COLOR=red]'%'[/color]
                    [COLOR=blue]When[/color] [COLOR=red]'8'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE ASL'[/color] + [COLOR=red]'%'[/color]  
                    [COLOR=blue]When[/color] [COLOR=red]'9'[/color] [COLOR=blue]Then[/color] [COLOR=red]'AND RN.FormRef LIKE APD'[/color] + [COLOR=red]'%'[/color]  
                    [COLOR=blue]Else[/color] [COLOR=red]'AND RN.FormRef = 0'[/color] 
                  [COLOR=blue]End[/color]

See how much easier that is to read?

As soon as a re-formatted the code in this style, another couple of problems jumped out at me.

First, let's look at one of these:

[tt][blue]When '1' Then 'AND RN.FormRef LIKE CAA' + '%'[/blue][/tt]

The problem here is that the query engine is going to interpret CAA as a column name. What I suspect you want is for CAA to be data (not a column). So, you should put single-quotes around it. But wait... you're building this in to a string, so... how do you put single quotes in to a string? By doubling them, like this...

[tt][blue]When '1' Then 'AND RN.FormRef LIKE [!]''[/!]CAA' + '%[!]''[/!]'[/blue][/tt]

Now, for the next problem. Whenever you are mixing AND's with OR's in a where clause, you should use parenthesis to avoid confusion and prevent the wrong data from being returned. So, this...

[tt][blue]When '2' Then 'AND RN.FormRef LIKE ENS' + '%' + ' OR RN.FormRef LIKE ETP'+ '%'[/blue][/tt]

Should be...

[tt][blue]When '2' Then 'AND [!]([/!]RN.FormRef LIKE ''ENS' + '%''' + ' OR RN.FormRef LIKE ''ETP'+ '%'' [!])[/!]'[/blue][/tt]

You have a similar problem in the if block for @InvoiceStatus.

Please understand that this is not meant to be a replacement of the advice given by the others, this is in addition to their advice.

-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top