Stored procedure with conversion date - sql-server

I have a stored procedure that takes on range of dates:
Create Procedure Search_PO
(
#usersID CHAR(10),
#poNo VARCHAR(20),
#poDateFrom Date,
#poDateTo Date,
)
As
Begin
If (#poNo = '')
Begin
Set #poNo = Null
End
If (#poDateFrom = '01/01/0001')
Begin
Set #poDateFrom = Null
End
If (#poDateTo = '01/01/0001')
Begin
Set #poDateTo = Null
End
Select * From PurchaseOrder p, Users u, Warehouse w
Where p.warehouseID = w.warehouseID
and w.usersID = u.usersID
and u.usersID = #usersID
and ((p.poNo like '%' + #poNo + '%') or #poNo Is Null)
and (p.poDate >= convert(date, #poDateFrom, 103) Or #poDateFrom Is Null)
and (p.poDate <= convert(date, #poDateTo, 103) Or #poDateTo Is Null)
End
This worked normally when I had selected dates where it was below 12(number of months), it throws me back an error of conversion from varchar into date
I believe this is due to the fact that:
Date format in SQL Server is mm/dd/yyyy
Date format in Visual Studio is dd/mm/yyyy
I tried using this code as a standalone code to check if my conversion is working:
select * from PurchaseOrder where poDate <= convert(date,'31/5/2017',103)
It does work, but when I execute my stored procedure:
exec Search_PO 'US00000001','','1/1/0001','31/5/2017'
It returns me the conversion error again. Thank you in advance for any kind of help.

I think the problem is in
exec Search_PO 'US00000001','','1/1/0001','31/5/2017'
You should pass date type parameter on yyyymmdd or yyyy-mm-dd format, not dd/mm/yyyy.
Change it to:
exec Search_PO 'US00000001','','1/01/01','2017/05/31'
And you don't need to convert convert(date, #poDateFrom, 103), its type is DATE already.
just
and (p.poDate >= #poDateFrom Or #poDateFrom Is Null)
and (p.poDate <= #poDateTo Or #poDateTo Is Null)

Can you send the dates as text variables and then make the conversion in the stored procedure? You can use SET DATEFORMAT dmy to aling SQL Server and Visual Studio date formats.
With this modification your SP would be like this:
Create Procedure Search_PO
(
#usersID CHAR(10),
#poNo VARCHAR(20),
#poDateFrom_Chr VARCHAR(10),
#poDateTo_Chr VARCHAR(10),
)
As
Begin
DECLARE #poDateFrom DATE
DECLARE #poDateTo DATE
SET DATEFORMAT dmy
SET #poDateFrom = #poDateFrom_Chr
SET #poDateTo = #poDateTo_Chr
SET DATEFORMAT mdy
If (#poNo = '')
Begin
Set #poNo = Null
End
If (#poDateFrom = '01/01/0001')
Begin
Set #poDateFrom = Null
End
If (#poDateTo = '01/01/0001')
Begin
Set #poDateTo = Null
End
Select * From PurchaseOrder p, Users u, Warehouse w
Where p.warehouseID = w.warehouseID
and w.usersID = u.usersID
and u.usersID = #usersID
and ((p.poNo like '%' + #poNo + '%') or #poNo Is Null)
and (p.poDate >= convert(date, #poDateFrom, 103) Or #poDateFrom Is Null)
and (p.poDate <= convert(date, #poDateTo, 103) Or #poDateTo Is Null)
End
Hope it helps.

You are currently converting your two date paramenters twice - once in the procdeure declaration (implicitly) and once in your select statement (explicitly). Your procedure is failing at the point where the #poDateFrom and #poDateTo parameters are being implicitly cast as date in the stored procedure declaration. If you're not in control of the format of the date being passed to your procedure you should change the parameter type to varchar.
i.e.
ALTER Procedure Search_PO
(
#usersID CHAR(10),
#poNo VARCHAR(20),
#poDateFrom VARCHAR(10),
#poDateTo VARCHAR(10),
)
This will avoid the implicit conversion and rely only on your explicit conversion (i.e. convert(date, #poDateFrom, 103) ) which, as you've already shown, will work for string value '31/5/2017'

Related

Converting end user local to UTC and back

Wondering if I'm doing this correctly or if I went too far or not far enough.
I have a scheduling/POS system which each location has it's own data.
Each location will report on it's own data.
The "owner" will be able to run reports for all locations.
I'm storing datetime as UTC.
Each location has it's timezone stored.
The end user passes over appointment information to the application which calls a stored proc. This grabs the locations stored timezone and converts local to UTC.
DECLARE #offeset VARCHAR(6)
SELECT #offeset = tz.current_utc_offset FROM sys.time_zone_info tz
INNER JOIN Location cl ON cl.TimeZoneStandardName = tz.[name]
WHERE cl.LocationID = #locationID
DECLARE #newStart DATETIME = dbo.fnConvertLocalToUTC(#startTimeLocal, #offset)
DECLARE #newEnd DATETIME = dbo.fnConvertLocalToUTC(#endTimeLocal, #offset)
Function: fnConvertLocalToUTC
ALTER function [dbo].[fnConvertLocalToUTC](
#datetime datetime2,
#offset varchar(6)
)
returns datetime2
as
BEGIN
return SWITCHOFFSET(CONVERT(datetimeoffset, CONVERT(varchar, #datetime, 121) + ' ' + #offset), 0)
END
Pulling a list of today's appointments I created a view that contains the following to convert UTC back to their local time.
SELECT ....
, CONVERT(VARCHAR(19), dbo.fnConvertUTC(a.StartTimeUTC, cl.TimeZoneStandardName), 120) AS StartTime
, CONVERT(VARCHAR(19), dbo.fnConvertUTC(a.EndTimeUTC, cl.TimeZoneStandardName), 120) AS EndTime
FROM Appointment a
INNER JOIN Location cl ON cl.LocationID = a.LocationID
WHERE
CAST(dbo.fnConvertUTC(a.StartTimeUTC, cl.TimeZoneStandardName) AS DATE) = CAST(dbo.fnConvertUTC(GETUTCDATE(), cl.TimeZoneStandardName) AS DATE)
Function: fnConvertUTC
ALTER function [dbo].[fnConvertUTC](
#datetime datetime2,
#timezonename varchar(60)
)
returns datetime2
as
BEGIN
return CONVERT(datetime, SWITCHOFFSET(#datetime, DATEPART(TZOFFSET, #datetime AT TIME ZONE #timezonename)))
END

Multiple Condition in Where Clause for the same column

How do I write a MS SQL statement for the below condition?
I have a form that allows users to enter dates (fromDate & toDate) and ID (fromID & toID) in range. The fields can be blank for all OR enter only either from or to field OR enter both from and to fields. Selection is based on the entered values to select. Below are the conditions checking in where clause for value entered.
no value entered => skip all conditions
value entered in fromDate only => Date = frDate
value entered in toDate only => Date <= toDate
value entered in both fromDate & toDate => Date between fromDate and toDate
Condition is applied to ID field as well.
Any advice is highly appreciated.
Thanks in advance.
You can solve your problem using dynamic query. Your question is not fully clear. Here i'm giving you a solution which will help you to solve your problem. Try this:
1. Create Dynamic query in a Store Procedure
CREATE PROCEDURE sp_YourSPName
/* Input Parameters */
#FromDate DATETIME ,
#ToDate DATETIME
AS
SET NOCOUNT ON
/* Variable Declaration */
DECLARE #SQLQuery AS NVARCHAR(4000)
DECLARE #ParamDefinition AS NVARCHAR(2000)
/* Build the Transact-SQL String with the input parameters */
SET #SQLQuery = 'Select * From YourTableName where (1=1) '
/* check for the condition and build the WHERE clause accordingly */
IF (#FromDate IS NOT NULL)
AND (#ToDate IS NOT NULL)
SET #SQLQuery = #SQLQuery +
' And (YourDate BETWEEN #FromDate AND #ToDate)'
IF (#FromDate IS NULL)
AND (#ToDate IS NOT NULL)
SET #SQLQuery = #SQLQuery + ' And (YourDate <= #ToDate)'
IF (#FromDate IS NOT NULL)
AND (#ToDate IS NULL)
SET #SQLQuery = #SQLQuery + ' And (YourDate = #FromDate)'
/* Specify Parameter Format for all input parameters included
in the stmt */
SET #ParamDefinition = '#StartDate DateTime,
#EndDate DateTime'
/* Execute the Transact-SQL String with all parameter value's Using sp_executesql Command */
EXECUTE sp_Executesql #SQLQuery,
#ParamDefinition,
#FromDate,
#ToDate
IF ##ERROR <> 0
GOTO ErrorHandler
SET NOCOUNT OFF
RETURN(0)
ErrorHandler :
RETURN(##ERROR)
GO
2. Execute Store Procedure:
EXEC sp_YourSPName '01 Oct 2018', '01 Oct 2018'
For more info see this link
You can use IS NULL to check param has value
SELECT * FROM Table
WHERE (#FromDate IS NULL OR Date > #FromDate) AND (#ToDate IS NULL OR Date < #ToDate)
Same type of query will be used for Id
Below is the EXAMPLE and not the exact query you can try to put it in your way using CASE statements
SELECT values
FROM Table
WHERE CASE
WHEN fromDate = null & todate = null THEN
WHEN fromDate != null & toDate != null THEN Date between fromDate and toDate
WHEN fromDate != null THEN Date = frDate
WHEN toDate != null THEN Date = toDate

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..

ISDATE Function for different date formats in TSQL

I need to convert VARCHAR values into DATETIME in multiple columns of a view for sorting and formatting (displaying in locale format) purposes in another application on SQL Server 2008.
There are currently two problems.
The input format of the VARCHAR values differ (but consistent at
column level)
Also there may be faulty values (e.g.: 20..05.2015)
Unfortunately the TRY_CONVERT function is available just for SQL Server 2012 and later.
ISDATE does not work because the view contains different date formats and I can neither set the language inside user defined functions nor in views, which would cause ISDATE to work with german date formats for example.
Is there any easier solution for my problem?
My first thought was to write a function like
FUNCTION TryConvertStringAsDatetime ( #value VARCHAR(MAX),
#format INT
)
that uses the format numbers of the CONVERT function, but checking for every possible format manually scares me a bit.
Example: TryConvertStringAsDatetime('20.05.2015', 104) (with some pseudocode)
SET #day = character 1 and 2
SET #month = character 4 and 5
SET #year = character 7, 8, 9 and 10
SET #dateODBCFormat = #year - #month - #day (concatenated with hyphen and not subtracted :)
IF ISDATE(#dateODBCFormat ) = 1
RETURN CONVERT(DATETIME, #dateODBCFormat, 120)
ELSE
RETURN CONVERT(DATETIME, 0) (does the job)
This is the function I now came up with:
CREATE
FUNCTION TryConvertStringAsDatetime ( #value VARCHAR(MAX),
#format INT
)
RETURNS DATETIME
AS
/*
Tries to convert a given VARCHAR value to DATETIME.
Returns NULL if no value was specified or the value is not in the correct format.
*/
BEGIN
DECLARE #length INT = LEN(#value)
IF #length IS NULL OR #length < 10 OR #length > 23
RETURN NULL
DECLARE #day VARCHAR(2),
#month VARCHAR(2),
#year VARCHAR(4),
#time VARCHAR(9)
IF #format = 104 --dd.mm.yyyy hh:mi:ss(24h)
BEGIN
SET #day = SUBSTRING(#value, 1, 2)
SET #month = SUBSTRING(#value, 4, 2)
SET #year = SUBSTRING(#value, 7, 4)
END
ELSE IF #format IN (120, 121) --yyyy-mm-dd hh:mi:ss(24h)
BEGIN
SET #year = SUBSTRING(#value, 1, 4)
SET #month = SUBSTRING(#value, 6, 2)
SET #day = SUBSTRING(#value, 9, 2)
END
ELSE
RETURN NULL -- currently only german and ODBC supported
IF #length > 11
SET #time = SUBSTRING(#value, 12, #length - 11)
SET #value = #year + '-' + #month + '-' + #day + ISNULL(' ' + #time, '')
IF ISDATE(#value) = 1
RETURN CONVERT(DATETIME, #value, 121)
RETURN NULL
END
I would probably go with something like this:
CREATE FUNCTION TryConvertToDate
(
#InputString varchar(20)
)
RETURNS Datetime
BEGIN
DECLARE #DateTime datetime = NULL
SET #DateTime =
CASE
WHEN LEN(#InputString) = 10 AND PATINDEX('[0-9][0-9].[0-9][0-9].[0-9][0-9][0-9][0-9]', #InputString)=1 THEN
CONVERT(DateTime, #InputString, 104) -- German
WHEN LEN(#InputString) = 10 AND PATINDEX('[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]', #InputString)=1 THEN
CONVERT(DateTime, #InputString, 120) -- ODBC
ELSE
NULL -- unsuported format
END
RETURN #DateTime
END
Note: Testing for length and using patindex ensures only general format, so you need the call this function inside a try block in case the days and months are inverted and will cause a conversion error.
On the other hand, adding supported formats to this function is very easy - all you have to do is add a when clause with the correct patindex and length and the correct convert style.
Another option is to ensure the string can actually be converted to date.
This will make your function more complicated and thus harder to write, but will be easier to work with as it will reduce to minimum the chance of raising a conversion error:
CREATE FUNCTION TryConvertToDate
(
#InputString varchar(20)
)
RETURNS Datetime
BEGIN
DECLARE #DateValue date, #Days int, #Months int, #Years int
IF LEN(#DateString) = 10 AND PATINDEX('[0-9][0-9].[0-9][0-9].[0-9][0-9][0-9][0-9]', #InputString)=1 -- German format
BEGIN
SELECT #Days = CAST(LEFT(#InputString, 2) As int),
#Months = CAST(SUBSTRING(#InputString, 4, 2) as int),
#Years = CAST(RIGHT(#InputString, 4) as int)
-- NOTE: you will need to add a condition for leap years
IF (#Days < 31 AND #Months IN(4,6,9,12)) OR (#Days < 30 AND #Months = 2)
SET #DateValue = convert(date, #InputString, 104)
END
IF LEN(#InputString) = 10 AND PATINDEX('[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]', #InputString)=1 -- ODBC format
BEGIN
SELECT #Days = CAST(RIGHT(#InputString, 2) As int),
#Months = CAST(SUBSTRING(#InputString, 6, 2) as int),
#Years = CAST(LEFT(#InputString, 4) as int)
-- NOTE: you will need to add a condition for leap years
IF (#Days < 31 AND #Months IN(4,6,9,12)) OR (#Days < 30 AND #Months = 2)
SET #DateValue = convert(date, #InputString, 120)
END
RETURN #DateValue
END
You might have better luck in terms of both speed and functionality doing this in SQLCLR (as noted by #Tab and #Zohar in various comments).
.NET / C# code:
using System;
using System.Data.SqlTypes;
using System.Globalization;
using Microsoft.SqlServer.Server;
public class TryConvertStuff
{
[SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static SqlDateTime TryConvertDateTime([SqlFacet(MaxSize = 50)] SqlString
StringDate, [SqlFacet(MaxSize = 10)] SqlString Culture)
{
CultureInfo _Culture = CultureInfo.CurrentCulture;
if (!Culture.IsNull && Culture.Value.Trim() != String.Empty)
{
_Culture = CultureInfo.GetCultureInfo(Culture.Value);
}
DateTime _RealDate;
if (DateTime.TryParse(StringDate.Value, _Culture,
DateTimeStyles.None, out _RealDate))
{
return _RealDate;
};
return SqlDateTime.Null;
}
}
Tests:
SELECT dbo.TryConvertDateTime(N'2019-04-20', N'en'); -- 2019-04-20 00:00:00.000
SELECT dbo.TryConvertDateTime(N'2019-04-20f', N'en'); -- NULL
SELECT dbo.TryConvertDateTime(N'2019.04.20', N'en'); -- 2019-04-20 00:00:00.000
SELECT dbo.TryConvertDateTime(N'20.04.2019', N'en'); -- NULL
SELECT dbo.TryConvertDateTime(N'20.04.2019', N'de'); -- 2019-04-20 00:00:00.000
SELECT dbo.TryConvertDateTime(N'20.04.2019', NULL); -- NULL

Search Stored Procedure (SQL Server) -- Conversion failed when converting date and/or time from character string -- Simple?

I have a stored procedure that I pass 3 variables bankNumber, branchNumber and DateFrom to.
Based on these variables I want to query the table (seen in picture below stored procedure) to return all records that meet the criteria I pass (through variables).
Instead I am getting this error:
Conversion failed when converting date and/or time from character string
It seems to be failing when I pass it the DateFrom variable.
Thank you for your help
ALTER PROCEDURE [dbo].[Search_Records]
#bankNumber varchar(3),
#branchNumber varchar(3),
#dateCreated datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE
#Bank_Number varchar(3) = #bankNumber,
#Branch_Number varchar(3) = #branchNumber,
#DateFrom datetime = #dateCreated,
#DateTo datetime = #dateCreated
SELECT DISTINCT
A.bankNumber,
A.branchNumber,
A.dateCreated
FROM
dbo.CENSORED A
WHERE
(#Branch_Number IS NULL OR bankNumber LIKE #BankNumber + '%')
AND (#Branch_Number IS NULL OR branchNumber LIKE #Branch_Number + '%')
AND (#DateFrom IS NULL OR dateCreated LIKE + #DateFrom + '%')
AND (#DateTo IS NULL OR dateCreated LIKE + #DateTo + '%')
END
You cannot use the LIKE operator with Datetime value. If you are matching only on month you would need to use MONTH() function. LIKE operator can only be used with string data types.
Dont see the point of all these Variables declared in your stored procedure, a simplified version should look something like ....
ALTER PROCEDURE [dbo].[Search_Records]
#bankNumber varchar(3),
#branchNumber varchar(3),
#dateCreated datetime
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT
A.bankNumber,
A.branchNumber,
A.dateCreated
FROM
dbo.CENSORED A
WHERE
(#Branch_Number IS NULL OR bankNumber LIKE #bankNumber + '%')
AND (#Branch_Number IS NULL OR branchNumber LIKE #branchNumber + '%')
AND (#dateCreated IS NULL OR (MONTH(dateCreated) = MONTH(#dateCreated)
AND
YEAR(dateCreated) = YEAR(#dateCreated)))
END
Note
this will produce a very inefficient execution plan, consider using dynamic sql for queries with optional parameters like this one.

Resources