How to use IF Else in store procedure? - sql

I am trying to execute Select query with ID parameter, now if ID is empty then I want All Rows, otherwise only row which contains this ID,
So far, I have created this Store Procedure,
IF(#CustId = null)
Begin
Select * from tblCustomer
End
Else
Begin
Select * from tblCustomer where custID=#custID
End
When I am executing this query with ID, I am getting result but when I am passing, I am not getting any result. What's correct way to do this?

Null is handled differently than other values, you need to use
IF (#CustId IS NULL)
Your current code of IF(#CustId = null) will always evaluate to False, so the else case will be executed regardless of what you pass for #CustId. This article goes into more detail about how to handle NULL values:

Related

Parameterized WHERE clause in SQL Server Stored Procedure

I have a Stored Procedure to get the details of Invoices
Some occasions I get the list of invoices by sending only the InvoiceID
But in some other occasions I need to get the list of invoices as per the search fields supplied by the user. To do this I send all the fields to the Stored Procedure and use those parameters as below. I included only 2 columns but there are more.
SELECT * FROM INVOICES I
WHERE
(#InvoiceNumber is null or I.InvoiceNumber = #InvoiceNumber)
and
(#PONo is null or I.PONo = #PONo)
Is there a way to send the condition for the WHERE clause as one parameter?
Yes, it is possible with Dynamic SQL, but I highly discourage to do that.
SELECT * FROM tbl WHERE #condition:
If you are considering to write the procedure
CREATE PROCEDURE search_sp #condition varchar(8000) AS
SELECT * FROM tbl WHERE #condition
Just forget it. If you are doing this, you have not completed the transition to use stored procedure and you are still assembling your
SQL code in the client.
It will also open your application to SQL Injection attacks.
You can use custom type to pass table as parameter https://msdn.microsoft.com/pl-pl/library/bb510489(v=sql.110).aspx or you can use default parameters
If you're using SQL Server 2016 or similar (check by calling select compatibility_level, name from sys.databases and seeing that your DB is 130 or higher) then you can use the string_split builtin function.
I found it works best like this (spread out for clarity)
CREATE PROCEDURE [dbo].[GetInvoices]
#InvoiceNumber int = NULL
#PONo nvarchar(1024) = NULL
AS
SELECT * from [Invoices] AS [i]
WHERE
i.InvoiceNumber = ISNULL(#InvoiceNunber, i.InvoiceNunber)
AND CASE
WHEN #PONo is null
THEN 1
ELSE (CASE
WHEN i.PONo IN (select value from string_split(#PONo, ','))
THEN 1
ELSE 0
END)
END
= 1
So if you pass in a null to either parameter it gets translated as where x = x which is always true, and if you pass in a CSV value, it selects it from a split table of values that, if present, results in the where clause being where 1=1, which is true or 0=1 if the value is not present in the input list.
So here you can pass in an invoice number, or PO number, or both, or neither and it should return what you expect.

How to use If/Else or Case statement for a checkbox with in a Select Query in SQL

I have a check box on front end.
If the check box is checked: data with only checked chk1 should appear on front end.
If the check box is not checked: full data should appear on front end.
Please suggest how should I proceed with the same in SQL Using If else / Case statement.
I am using:
SELECT *
FROM table1
where (some conditions) AND
CASE #a.Id_Oem_Irm
WHEN 0 THEN (a.id_oem_irm in(0,1))
WHEN 1 THEN (a.id_oem_irm in (1))
END
PS: a.Id_Oem_Irm: a is the table name, Id_oem_irm is the column name for check box.
I would recommend writing this as:
where (some conditions) AND
((#a.Id_Oem_Irm = 0 and a.id_oem_irm in(0, 1)) OR
(#a.Id_Oem_Irm = 1 and a.id_oem_irm in (1) )
)
I am not sure what #a.Id_Oem_Irm is supposed to be. I suspect you want a variable there.
Or you could tune it a bit like this:
SELECT *
FROM table1
where (some conditions) AND
(a.id_oem_irm = 1 OR
#a.Id_Oem_Irm = 0)
This is only valid if #a.Id_Oem_Irm is always 0 or 1. Otherwise, you obviously should add a #a.Id_Oem_Irm IN (0,1) or <= 1 (if it can't be negative) condition.
What is a? The alias for another table you didn't include here?
The simpler way to do this is create a storedprocedure which will take the input "#a.Id_Oem_Irm"
Example:
CREATE PROCEDURE p_get_a_data(
IN Id INT(1)
)
BEGIN
IF (Id = 0) BEGIN
--YOur query to retrieve partiular row/ column
END;
IF(Id = 1) BEGIN
--YOur query to retrieve all data
SELECT * FROM table1
where (some conditions)
END;
END
The usage of stored procedure will give you selected data and the query is precompiled in the database so it faster.
Note: I didn't quite understand what your query is returning so replace mine with yours

show error if exists duplicate data and not show for null values

i want when user do insert duplicate data(Code Value) show error for user and when user insert null value allow to user.
my code work for duplicate code but when user null value i want not show error and allow to user for insert data.
my code is:
IF EXISTS (
SELECT cd.Code
FROM chqDocuments cd
INNER JOIN chqDocumentTypes cdt
ON cdt.ID = cd.chqDocumentTypeID
INNER JOIN chqDocumentTypeClassifications cdtc
ON cdtc.ID = cdt.chqDocumentTypeClassificationID
WHERE
(cd.Code = #Code ) AND
cdtc.id = #chqDocumentTypeClassificationID_Entry And
(LTRIM(RTRIM(cdtc.Code))='11' OR LTRIM(RTRIM(cdtc.Code))='12')
)
BEGIN
RAISERROR('showerror',16,1)
RETURN
END
Assuming that #Code is the code value that the user is inputting, this code will work as-is since the following code will never evaluate to a true statement:
cd.Code = NULL -- even NULL != NULL; NULL IS NULL only works
Since that statement is never satisfied, the EXISTS clause will never be satisfied either. Thus, the user will be allowed to input NULL values for code without an error being thrown.

Return result of select query only if not empty

Working with Sql Server. Writing a stored procedure. Here is the pseudocode for what I want to achieve:
IF EXISTS ( SELECT field1
FROM t1
WHERE field1 = ... AND field2 = ...)
BEGIN
SELECT field1
FROM t1
WHERE field1 = ... AND field2 = ...
END
any better way of doing this? Any help appreciated.
Chirayu
Update: The problem is that the same query is executed twice. I cannot also just the run query once and return null (if the result is null i would like to return an alternative result).
I have done this before using a CTE and table variable, it requires more lines of code but the query is only written once, therefore your logic exists in a single place.
DECLARE #Results TABLE (Result INT);
WITH ResultsCTE AS
(
--Your query goes here
SELECT 1 as Result
WHERE 1 = 1
)
INSERT INTO #Results
SELECT Result
FROM ResultsCTE
IF (SELECT COUNT(*) FROM #Results) > 0
BEGIN
SELECT * FROM #Results
END
ELSE BEGIN
SELECT 'Do Something Else or Do Nothing!'
END
You could check ##ROWCOUNT after running the query once to determine whether or not to return the value:
http://msdn.microsoft.com/en-us/library/ms187316.aspx
If the select doesn't yield any results, no results will be returned. I don't see any reason to use a condition here, unless I'm missing something...
A stored procedure that sometimes returns a result while sometimes it doesn't would be a nightmare to use from any API. The client side API has different entry points depending on whether you return a result set (SqlCommand.ExecuteReader) or it does not return a result set (SqlCommand.ExecuteNonQuery). It would be impossible for the application to know ahead of time which API to use! Modeling tools use the SET FMTONLY option to analyze the metadata of returned result sets and the modeling tools are very confused when your returned result set start changing shape at random. In other words, you are down the wrong path, stop and turn around.
Just run the query, it no rows match your criteria it will simply return an empty result set. Which is exactly what every client API and modeling tool expects from your procedure.

Whats Select '1' for in the following stored proceedure

BEGIN
IF EXISTS(SELECT * FROM Table1 WHERE ID=#ID)
BEGIN
UPDATE Table1 SET Name=#Name WHERE ID=#ID
SELECT '1'
END
ELSE
SELECT '0'
END
Is this the row no. of the table or what ?
Also "IF EXISTS" is checking what ? the table or if the ID exists or not ??
It looks like whoever wrote that Stored Procedure is using that as a return value to indicate success or failure.
Doing things that way will result in a single row with a single column being returned for each call to the procedure.
The correct way to handle this would be to actually use the return value of the stored procedure, rather than returning the single column single row:
BEGIN
IF EXISTS(SELECT * FORM Table1 WHERE ID = #ID)
BEGIN
UPDATE Table1 SET Name = #Name WHERE ID = #ID
RETURN 1
END
RETURN 0
END
The IF EXISTS is checking if there is a row in Table1 with the given ID. If there is a row it will update that row with the given name. The Select "1" will return "1" and Select "0" returns "0". The "1" or "0" would indicate if the row was found or not.
Presumably some calling code checks this value to determine if a row was updated or not.
Rather than checking and updating (two table accesses) you might as well do this.
UPDATE Table1 SET Name=#Name WHERE ID=#ID
SELECT CASE WHEN ##Rowcount = 0 THEN 0 ELSE 1 END
If id is the PK then you can just do
UPDATE Table1 SET Name=#Name WHERE ID=#ID
SELECT ##Rowcount
Note as long as SET NOCOUNT is not on then the number of rows affected will get passed back to the client application anyway.
Select '1' is used to indicate that Table1 contains the id value #ID (a parameter) was updated. Select '0' indicates that Table1 does not contain the id value #ID.