How to set NULL in a Coalesce - sql

Quick question on Coalesce:
clw.ClawbackPercent = Coalesce(#ClawbackPercent, clw.ClawbackPercent)
Lets say for column 'ClawbackPercent' I have a value of 100.
If I execute a proc and set parameter #ClawbackPercent to have the value NULL, it keeps the value 100 in the row for that column which is great.
However, if I want to set 100 to actually be NULL, what do I need to write in the exec proc statement or what do I need to add in the Coalesce statement?
Thank you

It sounds like you want 100 to be the Default value of a stored proc parameter, not necessarily to replace all NULLs with this value. If this is the case, you don't want a COALESCE but you do need to provide a default value for the parameter on the proc definition.
e.g.
CREATE PROC dbo.MyProc (
#MyParam INT = 100
)
AS
-- My code here
If somebody executes this proc without specifying a value for #MyParam, the default of 100 will be assigned. If they explicitly specify #MyParam = NULL then NULL will be assigned..

Then probably you should not use coalesce, instead you can use case statement as below:
clw.ClawbackPercent = CASE WHEN #ClawbackPercent = 100
THEN NULL
ELSE
#ClawbackPercent END
in the select statement

You have to write in the following way:
CREATE PROCEDURE sp_test(
#ClawbackPercent VARCHAR(30)
) AS
BEGIN
SELECT COALESCE(#ClawbackPercent, '100')
END
--call as below and if you want to return second value then, EXEC sp_test NULL
--if your second, thirds... parameters are in INTEGER then simply CAST to VARCHAR
EXEC sp_test 'NULL'

Related

How to do a conditional where clause with where in PL/SQL within Procedure

I have a pretty simple Stored Procedure that I am in trouble to do because i'm new to SQL and PL/SQL. I Have a table with a name column that is a varchar(55).
I discovered that if the user executes my procedure with an empty string as a paramter the LIKE statment brings all rows from TABLE1
SELECT *
FROM TABLE1
WHERE COLUMN LIKE VARIABLE || '%'
AND...
So I tried to change the query so if the VARIABLE is passed with a empty string it can still perform other conditions in the where statment.
SELECT *
FROM TABLE1
WHERE (VARIABLE <> '' AND COLUMN LIKE VARIABLE || '%')
AND...
But now wherever I pass as variable ('', NULL, 'anystring') I get no rows returned.
How can I build a query that validates if the variable is different of empty string and if it is it performs the LIKE statment with the variable correctly?
If I understand you correctly, it is not difficult thing to do. You can use conditional WHERE clause using CASE WHEN. So your query will support different scenarios, something like this:
SELECT *
FROM TABLE1
WHERE (CASE WHEN variable IS NULL AND column IS NULL THEN 1
WHEN variable LIKE '%' AND column LIKE variable||'%' THEN 1
ELSE 0
END) = 1
AND...
Basically, it checks if the variable = '' then it will compare the column against ''. Otherwise, it will compare it against variable||'%'.
Notice, Oracle treats empty string of the type VARCHAR as NULL (this does not apply to CHAR). So, in the first scenario we compare against NULL.
Hello Just a thought for this we can use Dynamic sql too. If you may try this approach. Hope it helps.
CREATE OR REPLACE PROCEDURE SPS_TEST_OUT(
p_input_in IN VARCHAR2
)
AS
lv_sql LONG;
lv_where VARCHAR2(100);
BEGIN
lv_where:= CASE WHEN p_input_in IS NULL OR p_input_in = '' THEN
''
ELSE
' AND COLUMN1 LIKE '''||p_input_in||'''%'
END;
lv_sql:='SELECT * FROM TABLE
WHERE 1 = 1
' ||lv_where;
dbms_output.put_line(lv_sql);
END;

stored procedure with isnull(expression, replacement) return nothing

I have a stored procedure that accepts parameter and return tuple with matching values. If no parameter is passed, then return every tuple in the table
create procedure getScore
(
#clinicCode varchar = null,
)
as
begin
select * from myTable
where ClinicCode = isnull(#clinicCode, ClinicCode)
end
so I executte it
exec getScore
exec getScore 'PSH'
both of them return no tuple.
I did try select * from myTable, and they returns all tuples. Not sure why the statement from ... isnull(expression, replacement) get messed up
You need to change the declaration of
#clinicCode varchar = null,
to the actual size you require.
So something like
#clinicCode varchar(50) = null,
The reason for this is that
#clinicCode varchar
is the same as
#clinicCode varchar(1)
Which then casts your field isnull(#clinicCode, ClinicCode) to only the first letter of ClinicCode
Have a look at this example
SQL Fiddle DEMO

Bit parameter with Null value in Stored Procedure

I'm having a bit value in my table, which contains bit (0 or 1) and NULL (as default).
Here is my SProc:
CREATE PROCEDURE msp_CustomerStatistics
#Postal_MinValue int,
#Postal_MaxValue int,
#SubscriberState bit,
#CustomerType varchar(50)
BEGIN
[...]
WHERE Sub = #SubscriberState
AND Postal BETWEEN #Postal_MinValue AND #Postal_MaxValue
AND CustType = #CustomerType
END
When I pass the #SubscriberState parameter with 1 or 0, the result is correct.
But when I pass null, the result is 0, which ain't correct.
If I create a SQL select with following where clause:
WHERE Sub IS NULL
Then the result shows the correct count.
Any idea how I make my Stored Procedure working with NULL parameter in my WHERE clause too??
You can not use the = operator with null values. Comparisons with NULL always return false. Try to modify your WHERE statement to the following:
WHERE (Sub = #SubscriberState OR (#SubscriberState IS NULL AND Sub IS NULL))
You could either set null values to 0 and check it like this:
WHERE Isnull(Sub,0) = #SubscriberState
or have a tri-state sort of bodge like:
WHERE Isnull(Sub,3) = isnull(#SubscriberState,3)

How to write filtered queries using SQL stored procedures?

How can I write a SQL stored procedure where I want the parameters to be optional in the select statement?
try this.. Make the SPs input parameters that control the filtering optional, witrh default values of null. In each select statement's Where clause, write the predicate like this:
Create procedure MyProcedure
#columnNameValue [datatype] = null
As
Select [stuff....]
From table
Where ColumnName = Coalesce(#columnNameValue , ColumnName)
this way if you do not include the parameter, or if you pass a null value for the parameter, the select statement will filter on where the column value is equal to itself, (effectively doing no filtering at all on that column.)
The only negative to this is that it prevents you from being able to pass a null as a meaningfull value to explicitly filter on only the nulls.... (i.e., Select only the rows where the value is null) Once the above technique has been adopted, you would need to add another parameter to implement that type of requirement. ( say, #GetOnlyNulls TinyInt = 0, or something similar)
Create procedure MyProcedure
#columnNameValue [datatype] = null,
#GetOnlyNulls Tinyint = 0
As
Select [stuff....]
From table
Where (ColumnName Is Null And #GetOnlyNulls = 1)
Or ColumnName = Coalesce(#columnNameValue , ColumnName)

Setting a default value for a stored proc select statement

I am creating a stored proc that selects a value from a table and uses it in another procedure. If the first value that is searched doesn’t exist I need it to use a default value. I’m new to stored procs so I’m not sure of the best practices.
Here is the first select statement which may or may not return a value. If it doesn’t return a value I need to set the “#theValue” to 10 so that it can be used in the next select statement.
DECLARE #TheValue nvarchar(50)
SELECT #TheValue = deviceManager.SystemSettings.Value
FROM deviceManager.SystemSettings
WHERE (deviceManager.SystemSettings.Setting = 'expire-terminal-requests'
What would be the best solution?
DECLARE #TheValue nvarchar(50)
SELECT #TheValue = deviceManager.SystemSettings.Value
FROM deviceManager.SystemSettings
WHERE (deviceManager.SystemSettings.Setting = 'expire-terminal-requests'
-- Assuming #TheValue is an output parameter
SELECT #TheValue = ISNULL(#TheValue, 10)
Another possibility, set the default value before the query
DECLARE #TheValue nvarchar(50)
SET #TheValue = 'Some default Value'
SELECT #TheValue = deviceManager.SystemSettings.Value
FROM deviceManager.SystemSettings
WHERE deviceManager.SystemSettings.Setting = 'expire-terminal-requests'
This will always return either the default or the correct value.
Hope this helps.
#TheValue will be NULL if the select doesn't hit any rows. And NULL is a good value to indicate "not found".
One trick with NULLs is that you have to check for them with is null instead of = null, for example:
where #TheValue is NULL
coalesce returns the first non-null value from the list, is also ANSI standard.
SET #TheValue = coalesce (some_expresson_that_may_return_null
,some_other_expresson_that_may_return_null
,and_another_expresson_that_may_return_null
,default_value)