SQL: Procedure not getting a date null - sql-server

I’m executing a procedure like this:
EXEC myProcedure #name = 'Smith', #dateDeleted = NULL
I need all the Smith that don’t have a deleted date.
And this is the procedure:
CREATE PROCEDURE [dbo].[myProcedure]
#name VARCHAR(8000) = NULL
,#dateDeleted VARCHAR(8000) = NULL
AS
BEGIN
SET NOCOUNT ON;
WITH t
(name
,dateDeleted
)
AS
(
SELECT DISTINCT
name,dateDeleted FROM mytable
WHERE
(#name IS NULL OR #name = name)
AND (#dateDeleted IS NULL OR CONVERT(DATETIME, #dateDeleted, 102) = dateDeleted)
)
After the execution I have all the Smith but it does not pay any attention to the dateDeleted = NULL .. I ge all the Smiths no matter if they have a deleted date
How can I fix this?
Thanks

In your request if you pass NULL then a condition always true.Try this WHERE clause with COALESCE expression:
WHERE (#name IS NULL OR #name = name)
AND (COALESCE(#dateDeleted, dateDeleted) IS NULL
OR CONVERT(DATETIME, #dateDeleted, 102) = dateDeleted)

You need to set ansi nulls on
Execute:
set ansi_nulls on
And then execute the query.
Here is the explantion for this behaviour
http://msdn.microsoft.com/en-us/library/ms188048.aspx

Related

SQL: All the suggested GetDate () methods are not working

I'm doing an assignment and I was stuck at this place for about couple of days.
Getdate () is not working for this procedure. I used all the suggested methods.
But again I have to use the update statement here. So aren't there any procedure code to make it without using an update statement here?
Update Engineer set Enter_date = getdate() where EmpNo = 'Emp001000'
You don't need #temp_date,change #enter_date to GetDate()
exec sp_Add_New_Engineer #EmpNo='Emp00100', #EngNo= 'E00070' ,
#Eng_Type ='Electrical Engineer', #FName ='Pramila', #LName='Thivagaran',
#DOB ='1994/04/02', #Eng_Address='53/2, Peradeniya Road, Kandy', #Enter_Date = getdate(), #ProNo = 'P6'
Further I recommend formatting your code ,plus don't prefix your sps with SP_ .Here are some issues you may see when you use SP_
Where did you use #Temp_Date. You declared and assigned a value to it but never used in your remaining code. Please refer this sp below. I used your variable instead of #Enter_Date.
ALTER PROCEDURE sp_Add_New_Engineer (
#EmpNo VARCHAR(20)
,#EngNo VARCHAR(12)
,#Eng_Type VARCHAR(50)
,#FName VARCHAR(50)
,#LName VARCHAR(50)
,#DOB VARCHAR(50)
,#Eng_Address VARCHAR(100)
,#Enter_Date DATETIME
,#ProNo VARCHAR(12)
)
AS
DECLARE #Temp_Date DATETIME
SET #Temp_Date = GETDATE()
BEGIN
IF (
(
SELECT count(*)
FROM Supervisor
WHERE EmpNo = #EmpNo
) = 0
)
AND (
(
SELECT count(*)
FROM Labor
WHERE EmpNo = #EmpNo
) = 0
)
BEGIN
INSERT INTO Engineer (
EmpNo
,EngNo
,Eng_Type
,FName
,LName
,DOB
,Eng_Address
,Enter_date
,ProNo
)
VALUES (
#EmpNo
,#EngNo
,#Eng_Type
,#FName
,#LName
,#DOB
,#Eng_Address
,#Temp_Date
,#ProNo
)
END
ELSE
PRINT 'Employee Number is already in use'
END

Stored procedure Date From and Date To

I am trying to create a stored procedure for filtering orders. Basically the users have the option of filtering the order by date from and date to. So they can do search via date from, date to or use both if it makes sense?
Anyhow here is my SQL Server stored procedure so far
ALTER PROCEDURE [dbo].[CN_GetOrderItemByCustID]
#CustomerID int,
#OrderItemWRClass varchar(max) = NULL,
#OrderItemSKUName varchar(50) = NULL,
#OrderItemDateFrom Datetime,
#OrderItemDateTo Datetime
AS
BEGIN
SET NOCOUNT ON;
IF DATEDIFF(d, #OrderItemDateFrom, '01/01/1970') = 0
SET #OrderItemDateFrom = null
IF DATEDIFF(d, #OrderItemDateTo, '01/01/1970') = 0
SET #OrderItemDateTo = null
-- Insert statements for procedure here
SELECT
COM_OrderItem.OrderItemID, COM_Order.OrderID,
COM_Order.OrderDate, COM_OrderItem.OrderItemUnitCount,
COM_OrderItem.OrderItemStatus, COM_OrderItem.OrderItemSKUNAME,
COM_OrderItem.OrderItemSKUID
FROM
COM_OrderItem
INNER JOIN
COM_Order ON COM_Order.OrderID = COM_OrderItem.OrderItemOrderID
WHERE
COM_Order.OrderCustomerID = #CustomerID
OR COM_OrderItem.OrderItemWRClass LIKE #OrderItemWRClass + '%'
OR COM_OrderItem.OrderItemSKUName LIKE #OrderItemSKUName + '%'
OR CONVERT(VARCHAR, COM_Order.OrderDate, 120) LIKE #OrderItemDateFrom + '%'
ORDER BY
COM_Order.OrderDate DESC
However I am not sure on how to put the date from (OrderItemDateFrom) and date to (OrderItemDateTo) in the final SQL statement?
Should I be using OR CONVERT(VARCHAR, COM_Order.OrderDate, 120) LIKE #OrderItemDateFrom + '%' -- which gives me an error
Conversion failed when converting date and/or time from character string.
I know in a normal SQL query I would use Between OrderItemDateFrom and OrderItemDateTo
Thanks
Use this logic
ALTER PROCEDURE [dbo].[CN_GetOrderItemByCustID]
-- Add the parameters for the stored procedure here
#CustomerID int,
#OrderItemWRClass varchar(max) = NULL,
#OrderItemSKUName varchar(50) = NULL,
#OrderItemDateFrom Datetime,
#OrderItemDateTo Datetime
AS
BEGIN
SET NOCOUNT ON;
IF DATEDIFF(d,#OrderItemDateFrom,'01/01/1970')=0 SET #OrderItemDateFrom = '01/01/1970';
IF DATEDIFF(d,#OrderItemDateTo,'01/01/1970')=0 SET #OrderItemDateTo = '31/12/2199';
-- Insert statements for procedure here
SELECT COM_OrderItem.OrderItemID, COM_Order.OrderID, COM_Order.OrderDate, COM_OrderItem.OrderItemUnitCount, COM_OrderItem.OrderItemStatus, COM_OrderItem.OrderItemSKUNAME,
COM_OrderItem.OrderItemSKUID
FROM COM_OrderItem
INNER JOIN COM_Order ON COM_Order.OrderID = COM_OrderItem.OrderItemOrderID
WHERE COM_Order.OrderCustomerID = #CustomerID OR COM_OrderItem.OrderItemWRClass LIKE #OrderItemWRClass + '%' OR COM_OrderItem.OrderItemSKUName LIKE #OrderItemSKUName + '%'
OR (COM_OrderDate>=#OrderItemDateFrom && COM_OrderDate<=#OrderItemDateTo )
ORDER BY COM_Order.OrderDate DESC
Try it . It should work.
Your logic can be simplified a little by allowing NULL values for #OrderItemDateFrom and #OrderItemDateTo. Also, if filters values and column values are all DATETIMEs, you should try to compare directly to allow indexes usages (if any applied on the DATETIME column):
ALTER PROCEDURE [dbo].[CN_GetOrderItemByCustID]
#CustomerID int,
#OrderItemWRClass varchar(max) = NULL,
#OrderItemSKUName varchar(50) = NULL,
#OrderItemDateFrom Datetime = NULL, -- TODO: change caller to not provide parameter, or leave it to null
#OrderItemDateTo Datetime = NULL -- TODO: change caller to not provide parameter, or leave it to null
AS
BEGIN
SET NOCOUNT ON;
-- when working with dates try to use an unambiguous format like 'YYYY-MM-DD'
SET #OrderItemDateFrom = ISNULL(#OrderItemDateFrom, '1970-01-01')
-- assign a very large date to act like not provided
-- going one day after to catch DATETIMEs with provided time
SET #OrderItemDateTo = DATEADD(day, 1, ISNULL(#OrderItemDateTo, '3000-01-01'))
-- Insert statements for procedure here
SELECT
COM_OrderItem.OrderItemID, COM_Order.OrderID,
COM_Order.OrderDate, COM_OrderItem.OrderItemUnitCount,
COM_OrderItem.OrderItemStatus, COM_OrderItem.OrderItemSKUNAME,
COM_OrderItem.OrderItemSKUID
FROM COM_OrderItem
INNER JOIN COM_Order ON COM_Order.OrderID = COM_OrderItem.OrderItemOrderID
WHERE COM_Order.OrderCustomerID = #CustomerID
OR COM_OrderItem.OrderItemWRClass LIKE #OrderItemWRClass + '%'
OR COM_OrderItem.OrderItemSKUName LIKE #OrderItemSKUName + '%'
-- between can be used
OR (COM_OrderDate BETWEEN #OrderItemDateFrom AND #OrderItemDateTo)
ORDER BY
COM_Order.OrderDate DESC
END
Another option is to use dynamic SQL and construct it based on parameters values (i.e. insert WHERE condition if filter value is provided). This is particularly useful when filters numbers is relatively low compared to the total number of filters, as ORs are not performance friendly.
NOTE: shouldn't your filters apply in conjuction (i.e. use AND instead of OR)? It would make sense to allow the user to filter by several value in the same time.
ALTER PROCEDURE [dbo].[CN_GetOrderItemByCustID]
#CustomerID int,
#OrderItemWRClass varchar(max) = NULL,
#OrderItemSKUName varchar(50) = NULL,
#OrderItemDateFrom Datetime,
#OrderItemDateTo Datetime
AS
BEGIN
SET NOCOUNT ON;
IF DATEDIFF(d, #OrderItemDateFrom, '01/01/1970') = 0
SET #OrderItemDateFrom = null
IF DATEDIFF(d, #OrderItemDateTo, '01/01/1970') = 0
SET #OrderItemDateTo = null
-- Insert statements for procedure here
SELECT
COM_OrderItem.OrderItemID, COM_Order.OrderID,
COM_Order.OrderDate, COM_OrderItem.OrderItemUnitCount,
COM_OrderItem.OrderItemStatus, COM_OrderItem.OrderItemSKUNAME,
COM_OrderItem.OrderItemSKUID
FROM
COM_OrderItem
INNER JOIN
COM_Order ON COM_Order.OrderID = COM_OrderItem.OrderItemOrderID
WHERE
COM_Order.OrderCustomerID = #CustomerID
OR COM_OrderItem.OrderItemWRClass LIKE #OrderItemWRClass + '%'
OR COM_OrderItem.OrderItemSKUName LIKE #OrderItemSKUName + '%'
OR (#OrderItemDateFrom IS NULL OR COM_Order.OrderDate >=#OrderItemDateFrom)
OR (#OrderItemDateTo IS NULL OR COM_Order.OrderDate <=#OrderItemDateTo)
ORDER BY
COM_Order.OrderDate DESC
You should Try this.
OR (#OrderItemDateFrom IS NULL OR COM_Order.OrderDate >=#OrderItemDateFrom)
OR (#OrderItemDateTo IS NULL OR COM_Order.OrderDate <=#OrderItemDateTo)
Just Edit and try this condition..

Stored Procedure does not return data

I have the following stored procedure. It is very simple
ALTER PROCEDURE [dbo].[SPU_IsoSearch]
#searchby varchar(4),
#userinput varchar(25)
AS
IF(#userinput IS NOT NULL)
BEGIN
if(#searchby = 'fname')
BEGIN
SET NOCOUNT ON;
SELECT CustID, CustFirstName, CustLastName, CustCity, CustEmail
FROM Customers where CustFirstName like '%' + #userinput + '%'
ORDER BY CustFirstName
END
END
Then, I'm executing it:
exec spu_isoSearch 'fname','de'
And it does not return anything, just a message "Command(s) completed successfully."
But if I just write:
select * from Customers where CustFirstName like '%de%'
I will get the data.
What am I doing wrong here?
Thank you
Your parameter 'searchby' is varchar(4), try changing to varchar(5) or the appropriate length
Since it is declared as varchar(4), your if statement compares 'fnam' to 'fname', and since those are not equal, the select statement does not execute
As Ghost(User) has mentioned the parameter length and on a side note your procedure can be cleaned up a bit more something like this..
ALTER PROCEDURE [dbo].[SPU_IsoSearch]
#searchby varchar(5), --<-- As pointed out by OP "Ghost"
#userinput varchar(25)
AS
BEGIN
SET NOCOUNT ON;
IF(#searchby = 'fname' AND #userinput IS NOT NULL)
BEGIN
SELECT CustID, CustFirstName, CustLastName, CustCity, CustEmail
FROM Customers where CustFirstName like '%' + #userinput + '%'
ORDER BY CustFirstName
END
END

SQL Server: how to create a stored procedure

I'm learning sql from a book and I'm trying to write a stored procedure but I don't believe that I'm doing it correctly. Is the following way not valid in Microsoft SQL? If not, when is it valid, if ever?
create procedure dept_count(in dept_name varchar(20), out d_count integer)
begin
select count(*) into d_count
from instructor
where instructor.dept_name=dept_count.dept_name
end
I get the following error
Msg 156, Level 15, State 1, Procedure wine_change, Line 1
Incorrect syntax near the keyword 'in'.
T-SQL
/*
Stored Procedure GetstudentnameInOutputVariable is modified to collect the
email address of the student with the help of the Alert Keyword
*/
CREATE PROCEDURE GetstudentnameInOutputVariable
(
#studentid INT, --Input parameter , Studentid of the student
#studentname VARCHAR (200) OUT, -- Output parameter to collect the student name
#StudentEmail VARCHAR (200)OUT -- Output Parameter to collect the student email
)
AS
BEGIN
SELECT #studentname= Firstname+' '+Lastname,
#StudentEmail=email FROM tbl_Students WHERE studentid=#studentid
END
In T-SQL stored procedures for input parameters explicit 'in' keyword is not required and for output parameters an explicit 'Output' keyword is required. The query in question can be written as:
CREATE PROCEDURE dept_count
(
-- Add input and output parameters for the stored procedure here
#dept_name varchar(20), --Input parameter
#d_count int OUTPUT -- Output parameter declared with the help of OUTPUT/OUT keyword
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Statements for procedure here
SELECT #d_count = count(*)
from instructor
where instructor.dept_name=#dept_name
END
GO
and to execute above procedure we can write as:
Declare #dept_name varchar(20), -- Declaring the variable to collect the dept_name
#d_count int -- Declaring the variable to collect the d_count
SET #dept_name = 'Test'
Execute dept_count #dept_name,#d_count output
SELECT #d_count -- "Select" Statement is used to show the output
I think it can help you:
CREATE PROCEDURE DEPT_COUNT
(
#DEPT_NAME VARCHAR(20), -- Input parameter
#D_COUNT INT OUTPUT -- Output parameter
-- Remember parameters begin with "#"
)
AS -- You miss this word in your example
BEGIN
SELECT COUNT(*)
INTO #D_COUNT -- Into a Temp Table (prefix "#")
FROM INSTRUCTOR
WHERE INSTRUCTOR.DEPT_NAME = DEPT_COUNT.DEPT_NAME
END
Then, you can call the SP like this way, for example:
DECLARE #COUNTER INT
EXEC DEPT_COUNT 'DeptName', #COUNTER OUTPUT
SELECT #COUNTER
Try this:
create procedure dept_count(#dept_name varchar(20),#d_count int)
begin
set #d_count=(select count(*)
from instructor
where instructor.dept_name=dept_count.dept_name)
Select #d_count as count
end
Or
create procedure dept_count(#dept_name varchar(20))
begin
select count(*)
from instructor
where instructor.dept_name=dept_count.dept_name
end
CREATE PROCEDURE [dbo].[USP_StudentInformation]
#S_Name VARCHAR(50)
,#S_Address VARCHAR(500)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Date VARCHAR(50)
SET #Date = GETDATE()
IF EXISTS (
SELECT *
FROM TB_StdFunction
WHERE S_Name = #S_Name
AND S_Address = #S_Address
)
BEGIN
UPDATE TB_StdFunction
SET S_Name = #S_Name
,S_Address = #S_Address
,ModifiedDate = #Date
WHERE S_Name = #S_Name
AND S_Address = #S_Address
SELECT *
FROM TB_StdFunction
END
ELSE
BEGIN
INSERT INTO TB_StdFunction (
S_Name
,S_Address
,CreatedDate
)
VALUES (
#S_Name
,#S_Address
,#date
)
SELECT *
FROM TB_StdFunction
END
END
Table Name : TB_StdFunction
S_No INT PRIMARY KEY AUTO_INCREMENT
S_Name nvarchar(50)
S_Address nvarchar(500)
CreatedDate nvarchar(50)
ModifiedDate nvarchar(50)
Create this way.
Create procedure dept_count(dept_name varchar(20),d_count integer)
begin
select count(*) into d_count
from instructor
where instructor.dept_name=dept_count.dept_name
end
try this:
create procedure dept_count( #dept_name varchar(20), #d_count INTEGER out)
AS
begin
select count(*) into d_count
from instructor
where instructor.dept_name=dept_count.dept_name
end
To Create SQL server Store procedure in SQL server management studio
Expand your database
Expand programmatically
Right-click on Stored-procedure and Select "new Stored Procedure"
Now, Write your Store procedure, for example, it can be something like below
USE DatabaseName;
GO
CREATE PROCEDURE ProcedureName
#LastName nvarchar(50),
#FirstName nvarchar(50)
AS
SET NOCOUNT ON;
//Your SQL query here, like
Select FirstName, LastName, Department
FROM HumanResources.vEmployeeDepartmentHistory
WHERE FirstName = #FirstName AND LastName = #LastName
GO
Where, DatabaseName = name of your database
ProcedureName = name of SP
InputValue = your input parameter value (#LastName and #FirstName) and type = parameter type example nvarchar(50) etc.
Source: Stored procedure in sql server (With Example)
To Execute the above stored procedure you can use sample query as below
EXECUTE ProcedureName #FirstName = N'Pilar', #LastName = N'Ackerman';

Passing an array of ID's to a stored procedure

I have stored procedure, i want to send it an array of values. When i send more than one i'm getting an error
Error converting data type varchar to numeric.
Here is the code.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_getTransfer] #TRANSFER_ID int = null, #COMPANY VARCHAR(5),#FORMTYPE VARCHAR(30), #TRANSFER_IDS VARCHAR(500) = NULL, #SEAL_DATE datetime = NULL AS
-- Declare variables
DECLARE #rc Int
IF #SEAL_DATE IS NULL
BEGIN
SELECT
COMPANY,
FORMTYPE,
COMPANY_NAME,
COMPANY_ADDRESS1,
COMPANY_ADDRESS2,
IMID,[DESCRIPTION],AMOUNT,AMOUNT_TRANSFER,
CONSIDERATION,
TRANSFER_ID,
[DATE],
CURR,
CMF_NAME_1,
CMF_NAME_2,
CMF_ADDR_1,
CMF_ADDR_2,
CMF_ADDR_3,
CMF_ADDR_4,
CMF_POSTAL_CODE,
Cons_Curr = CASE
WHEN LTRIM(RTRIM(Cons_Curr)) <> '' THEN Cons_Curr
ELSE CURR
END,
-- Cons_Curr,
TRANSFERYEAR,
TRANSFERMONTH,
TRANSFERDAY,
dbo.CurrencyToWords(CURR) AS CURR_WORDS,
---dbo.CurrencyToWords(Cons_Curr) AS CONNS_CURR_WORDS
CONS_CURR_WORDS = CASE
WHEN LTRIM(RTRIM(CONS_CURR)) <> '' THEN dbo.CurrencyToWords(CONS_CURR)
ELSE dbo.CurrencyToWords(CURR)
END
FROM
VW_TRANSFERS
WHERE
TRANSFER_ID= #TRANSFER_ID
AND
FORMTYPE= #FORMTYPE
AND
COMPANY = #COMPANY
OR
TRANSFER_ID IN (#TRANSFER_IDS)
END
ELSE
SELECT
COMPANY,
FORMTYPE,
COMPANY_NAME,
COMPANY_ADDRESS1,
COMPANY_ADDRESS2,
IMID,[DESCRIPTION],AMOUNT,AMOUNT_TRANSFER,
CONSIDERATION,
TRANSFER_ID,
[DATE],
CURR,
CMF_NAME_1,
CMF_NAME_2,
CMF_ADDR_1,
CMF_ADDR_2,
CMF_ADDR_3,
CMF_ADDR_4,
CMF_POSTAL_CODE,
--Cons_Curr,
Cons_Curr = CASE
WHEN LTRIM(RTRIM(Cons_Curr)) <> '' THEN Cons_Curr
ELSE CURR
END,
TRANSFERYEAR,
TRANSFERMONTH,
TRANSFERDAY,
dbo.CurrencyToWords(CURR) AS CURR_WORDS,
---dbo.CurrencyToWords(Cons_Curr) AS CONNS_CURR_WORDS
CONS_CURR_WORDS = CASE
WHEN LTRIM(RTRIM(CONS_CURR)) <> '' THEN dbo.CurrencyToWords(CONS_CURR)
ELSE dbo.CurrencyToWords(CURR)
END
FROM
VW_TRANSFERS
WHERE
FORMTYPE= #FORMTYPE
AND
COMPANY = #COMPANY
AND
DATE = #SEAL_DATE
OR
TRANSFER_ID IN (#TRANSFER_IDS)
EXEC sp_getTransfer NULL, fgb, transfer, '124,444,4555,8865,24,55,69', NULL
the following code cannot work:
TRANSFER_ID IN (#TRANSFER_IDS)
Several working alternatives described here:
Arrays and Lists in SQL Server
you would have to set this up as a dynamic stored procedure or loop through the ids in code and call the stored proc each time. Do you know how to set up a dynamic procedure?
EXAMPLE
ALTER Procedure [dbo].[sp_NAME]
(#id as varchar(max)
)
as
Declare #query1 as nvarchar(max)
If #Param is null
set #Param = ''
Set #query1 = '
select whatever
from table
where id in('+#id+')'
EXECUTE sp_executesql #query1

Resources