views:

149

answers:

8

I have what seems to be a really easy SQL query I can't figure out and its driving me nuts. This is SQL 2008. Basically, there is a status field where the can pick "pending", "satisfied" or all. If they send in "pending" or "satisfied" there's no problem. But when they pick all I'm having problems. Mostly because I can't figure out how to get the records where this field is null to show up (because it has to be 'is null' instead of '= null'. (This is the way the data will come over; I have no control over that.)

The code I've been using does not work for nulls.

SELECT * FROM Payment_Table where Payment.Status_code = @status_id

+5  A: 

You can try

SELECT Col1, Col2,...,Coln --Required Columns
FROM Payment_Table 
where (Payment.Status_code = @status_id OR @status_id IS NULL)
astander
Avoid select * (15 chars)
JonH
I don't know if this will work. It will return all rows if @status_id is null instead of just the rows where Payment.Status_code is null.
RandomBen
never do Select *
fuzzy lollipop
@RandomBen and that is what he / she wants. You either select the rows with a pending / satisfied value for instance Payment.Status_Code='Satisfied' OR you select ALL the records, whether they are pending or satisfied. In that case, this is correct it says @StatusID = NULL which in this case is true as True OR False = True.
JonH
Aggreed on the never SELECT *, just didnt see any fields specified for the select.
astander
A: 

You can use coalesce or IsNull on your Payment.StatusCode field, this will allow you to do a substitution for null with a specific value.

keithwarren7
A: 
SELECT * 
FROM Payment_Table 
WHERE (Payment.Status_code is null or Payment.Status_code = @status_id) 
Chris Kannon
You are aware that this will include NULL Status_code even if a @status_id of other than NULL is provided?
astander
I think the poster meant Payment.Status_Code = @status_id OR @Status_id IS NULL otherwise it is not correct.
JonH
Oops, yes JonH, you are correct.
Chris Kannon
+1  A: 

Try

WHERE
    ((@status_id IS NULL) OR (Payment.Status_code = @status_id)) 
SQLMenace
+2  A: 

Try:

SELECT * 
FROM Payment_Table 
WHERE Payment.Status_code = ISNULL(@status_id, Status_code)

This will return all payments.

Miyagi Coder
Avoid SELECT * (15 chars)
JonH
If there are any rows in the table where Payment.Status_Code is null, your query will not return that data. This code should only be used if there is a NOT NULL constraint on the column.
G Mastros
A: 

There are many approaches depending which version of sql server you are using. This articles has an in-depth description: Dynamic Search Conditions in T-SQL

Giorgi
A: 

The best way to do this is below. However, you MUST watch out for parameter sniffing. This will become an issue as your table gets bigger and will affect your execution times randomly. This is an annoying issue that can pop up. Use the code below.

CREATE PROCEDURE GetPaymentStatus
@StatusID varchar(50)=NULL
AS
BEGIN
SET NOCOUNT ON;

DECLARE @StatusId_local varchar(50)
SET @StatusID_local = @StatusId

SELECT MyField1, MyField2
FROM Payment_Table
WHERE Payment_Table.Status=@StatusID_local 
    OR (@StatusID_local IS NULL AND Payment_Table.Status IS NULL)
END

Check out this article or google sql parameter sniffing for more info.

RandomBen
No point in redeclaring that variable. Also in most cases this is not a web app / security question...also this procedure was already posted by me 43 mins ago.
JonH
There is a point in re-declaring the variable. I am pretty sure that a parameter sniffing issue could arise. I have seen this happen before where an or statement is used where the second part of the OR clause is checking if a variable is set to NULL. It is a minor bug in SQL Server. What happens is SQL will scan the entire table looking for all cases where Payment_Table.Status=NULL, which we know won't return any results. If you declare the variable locally, you force SQL to check the part of the OR Clause that doesn't involve the table. See my link above.
RandomBen
That is not true, because you are not asking for payment_table.status=null you are asking for payment_table.status = @SomeVal where @SomeVal is either pending or assigned, no mention of null so the db engine does not bother doing any searching on that.
JonH
+1  A: 
WHERE Payment_Table.Status = ISNULL(@StatusID, Payment_Table.Status)

It usually works better then OR

Edit: you want to select rows where Payment_Table.Status = NULL when @StatusID = NULL!!

SELECT * FROM Payment_Table where Payment.Status_code = @status_id
UNION ALL
SELECT * FROM Payment_Table where Payment.Status_code IS NULL AND @StatusID IS NULL

OR

...
WHERE
    Payment_Table.Status @StatusID
    OR
    (Payment.Status_code IS NULL AND @StatusID IS NULL)
gbn