How to modify stored procedure to give null instead of 0 - sql

How to modify a stored procedure to return null instead of 0 ?
Modification request to a stored procedure used for a report. Asked to display blank in the report. Meaning need to return null instead of 0 (zero).
Current code:
Approach = ISNULL(Approach, 0) ,
Possible new code:
Approach = ISNULL(Approach, '') ,

In you sql code add this line
CASE WHEN Approach = 0 THEN NULL END AS Approach
so in your stored procedure when Approach will come as 0 then it will be replaced with NULL

Went about it in SSDT/SSRS
=IIF(Sum(Fields!"Field".value)=0,"",Sum(Fields!"Field".value))

Related

Is there a more concise version of the CASE WHEN foo.bar IS NULL THEN 0 ELSE 1 END paradigm?

The goal is simply to check whether a field is NULL or not, yielding a value of 1 when the field is not NULL, and 0 otherwise. I can't use COALESCE here, because if the field isn't NULL, I just want to return 1, not the value of the field.
I have a gut feeling that there's already a function that does this - something like NULL_STATUS_INTEGER(foo.bar), for example - instead of needing to write out the full CASE statement of CASE WHEN foo.bar IS NULL THEN 0 ELSE 1 END. I'm not saying that the CASE version is absurdly long, but I just find it strange that there's not a shorter way to do this.
I'm primarily interested in solutions that aren't confined to one SQL vendor, but I happen to be using SAS, if there happens to be a SAS-specific way to do this in PROC SQL.
Comparisons are also boolean, return a true/false
proc sql;
create table want as
select *, name = 'Alfred' as flag
from sashelp.class;
quit;
data want;
set sashelp.class;
flag = (name = 'Alfred');
run;
EDIT:
Another option is to use IFN()/IFC(), which factor in three conditions, FALSE, TRUE, MISSING. IFN()/IFC() can be used in SQL or a data step in SAS.
x = ifc(name="Alfred", 1, 0, .);

How to set a NULL when entering NULL keeps the old value

I have a stored procedure where it is able to update the 4 columns below as there are 4 parameters (1 parameter for each column with ClawbackID the only one that doesn't change).
Now there is no fixed amount of columns that can be updated, I may choose to update 1 column, or 3 columns or all 4 columns. So to reduce human error, I have a coalesce so that if the user enters in 'NULL' for a particular parameter whilst executing a procedure, the original amount stays.
Example for row 3 for 'ClawbackAmount', if I enter in NULL and execute, it will still display the 'ClawbackAmount' 900.54. Now the problem I have is that actually want to set this amount to 'NULL', but I don't want to lose the functionality that if I type in 'NULL' when executing my procedure that it keeps the old value.
My question is that is there a way or an idea you can think of where I type in NULL then the default values stays but if I type in something like '' then it will default to 'NULL'?
Or alternatively type in the word 'SAME' to keep the default value and then type in 'NULL' for a null value? Just ideas really to get around it?
Below is the code I have with the parameters included as they begin with #:
update clw
set clw.PaymentID = Coalesce(#PaymentID, clw.PaymentId)
,clw.ClawbackDate = Coalesce(#ClawbackDate, clw.ClawbackDate)
, clw.ClawbackPercent = Coalesce(#ClawbackPercent, clw.ClawbackPercent)
, clw.ClawbackAmount = Coalesce(#ClawbackAmount,clw.ClawbackAmount)
OUTPUT '[Fees].EBD.Clawback' 'TableName','ClawbackId', inserted.ClawbackId,
Core.updXMLFragment('PaymentId', inserted.PaymentId, deleted.PaymentId) +
Core.updXMLFragment('ClawbackDate', Convert(varchar(50),inserted.ClawbackDate, 112), Convert(varchar(50),deleted.ClawbackDate, 112)) +
Core.updXMLFragment('ClawbackPercent', inserted.ClawbackPercent, deleted.ClawbackPercent) +
Core.updXMLFragment('ClawbackAmount', inserted.ClawbackAmount, deleted.ClawbackAmount)
INTO #OutputList
from [Fees].EBD.Clawback clw
Where
ClawbackId = #ClawbackID
Below is the code for the execution as an example for row 3 if I want to make the desired change:
First Param is ClawbackID (this doesn't change but need it to know which row to manipulate.
Second Param is PaymentID which is NULL as want to keep the same
Third Param is Clawbackdate which is NULL as want to keep the same
Fourth Param is ClawbackPercent which needs to be 0.25
Last Param is ClawbackAmount which I need to set to NULL. This is an int field btw but leaving it NULL will keep the orginal amount displayed.
exec SupportAudit.BI.UpdateHotelClawback 28817, NULL, NULL, 0.25, NULL
I generally use some specific invalid value as an indicator the column should be set to NULL. In the case of ClawbackPercent and ClawbackAmount, -1 seems like a good candidate. The change would look like this:
...
, clw.ClawbackPercent = NullIf(Coalesce(#ClawbackPercent, clw.ClawbackPercent), -1)
, clw.ClawbackAmount = NullIf(Coalesce(#ClawbackAmount,clw.ClawbackAmount), -1)
...
For string parameters, '' (the empty string) might be an appropriate choice.

IS NULL not working in WHERE clause of SQL

I have written a Stored procedure in which in given table column named xx can have 0,1 or null. When I give the below condition. SP is ignoring null and returning data only for 0 value.
WHERE (CAR_INSPECTION_NEW_TEST.NODAMAGEFLAG is null OR
CAR_INSPECTION_NEW_TEST.NODAMAGEFLAG = 0) AND
CAR_INSPECTION_NEW_TEST.ISSUBJECT_TODELIVER = 0
Can any one tell what is the problem?
By simple logic it will not return rows where NODAMAGEFLAG is null as long as ISSUBJECT_TODELIVER = 0 is not also valid (because of the AND).
So, check your data please.

Difference between return statements in SQL Stored Procedure

I would like to know the difference between
IF X= 0
BEGIN
RETURN
END
and
IF X= 0
BEGIN
RETURN 1
END
Which is a better practice when used in a Stored Procedure.
Thanks in anticipation
Both are equally valid depending on your requirements. If you simply want to exit your procedure then RETURN will suffice. On the other hand if you want to tell the calling procedure the result of the call then you can do RETURN 1 or any other integer.
More on http://msdn.microsoft.com/en-us/library/ms174998.aspx

Using IF/THEN or CASE within a WHERE clause in SQL

I have been assigned the task of updating the EEO survey and reporting for a mid sized company. I am working on a stored procedure to populate a report from. All is good but for a syntax problem. One of the requirements is to dynamically allow the user to filter the results by the EEO Job Group Number. When the report page loads, it populates the table with all Job Groups Combined. I have placed a DropDownList on the page that allows the user to choose one of the 10 EEO Job Groups or by default, All Job Groups Combined (no filtering). The DDL executes postback and populates a parameter; #intEeoJobGroupID. There is not actually a 0 ID value in the table, just in the DDL. I want the (usp) query to use one set of WHERE statements if the passed parameter #intEeoJobGroupID = 0, and another if #intEeoJobGroupID <> 0. (Effectively adding another AND statement if the parameter <> 0)
I want to return the count of how many EEO records meet the requirements of the query. I have tried IF/THEN, and CASE, in many different formats, and can not seem get the syntax right. In the example below I get the message "Incorrect Syntax near the first = in the THEN statement, as well as the keyword ELSE.
Any hints?
DECLARE #intEeoJobGroupID INT
SELECT
COUNT (E.intEeoID)
FROM
dbo.NewEEO AS E
WHERE
CASE WHEN #intEeoJobGroupID = 0
THEN
E.intGenderID = 1
AND E.intRaceID = 2
ELSE
E.intGenderID = 1
AND E.intRaceID = 2
AND E.intEeoJobGroupID = #intEeoJobGroupID
You're making it way too complicated:
WHERE E.intGenderID = 1
AND E.intRaceID = 2
AND (E.intEeoJobGroupID = #intEeoJobGroupID OR #intEeoJobGroupID = 0)
As someone else already mentioned, your existing syntax was missing an "END", but it still won't work with that added. To get this right in the future, one thing you can try to do is remember that CASE expressions in SQL are just that: expressions. They are not statements, as you might be used to with if statements in c# code. You don't use CASE for flow control, to define blocks as you were trying to do.
Don't try to return a boolean from a CASE statement. Instead return some value that is then checked outside the CASE statement (and so then resulting in a boolean).
CASE WHEN #mode = 1 THEN CASE WHEN <Condition1> THEN 1 ELSE 0 END
WHEN #mode = 2 THEN CASE WHEN <Condition2> THEN 1 ELSE 0 END
END
=
1
Note: This will create Awful execution/explain plans and totally nerf performance. You are better using real IF blocks and real queries, or possibly unions...
IF #mode = 1
SELECT foo FROM bar WHERE <Condition1>
ELSE IF #mode = 2
SELECT foo FROM bar WHERE <Condition2>
Or...
SELECT foo FROM bar WHERE <condition1> AND #mode = 1
UNION ALL
SELECT foo FROM bar WHERE <condition2> AND #mode = 2
In order to prevent massive duplication of code, you may find that encapsulating the bulk of the query in a VIEW is helpful.
You can't make a comparison the result of a case condition. If you're using case in a where clause, it needs to be on one side of the operator:
CASE #case_value
WHEN 0 THEN
some_column
ELSE
some_other_column
END = #some_value
However, if you try to make your actual condition fit this rule, you'll end up not using the case statement at all, as #Joel point out.
You have to add
end
in the end of case.