SQL Server: using Case statement in Where clause creates error - sql

I have a dynamic procedure where an input variable can either be a date with the corresponding column being formatted as datetime OR a string with the corresponding columns being formatted as nvarchar.
If the input is a date then this would look like yyyy-mm-dd .
To cover this I tried to add the following to my Where clause but this creates the below error (if I remove this line then the rest of the procedure works as intended):
#searchTerm nvarchar(256) = ''
-- ...
WHERE CASE WHEN ''' + #searchCategory + ''' <> ''dateX'' THEN
(A.' + #searchCategory + ' LIKE ''%' + #searchTerm + '%'')
ELSE
(A.dateX = ''' + CAST(#searchTerm AS DATETIME) + ''')
END
-- ...
Error:
Conversion failed when converting date and/or time from character string.
Can someone tell me what I have to change here to make this work ?
Many thanks in advance, Mike.

You can't put a datetime value into a string. First cast as datetime to get it into the format you want then cast to a Varchar so it can be part of your dynamic string.
(A.dateX = ''' + CAST(CAST(#searchTerm AS DATETIME) AS VARCHAR(20)) + ''')
Or if #searchTerm is already in the format you want then you don't need to cast it
(A.dateX = #searchTerm)

Related

How to convert charater string to uniqueidentifier and use Stuff function?

I'm using function to generate the result. What am I facing now is I pass the ItemGuid as parameter and currently I am using STUFF to find the ItemCode and concatenate result. However I getting an error said that Conversion failed when converting from a character string to uniqueidentifier.
My current result before using STUFF:
From Date : 01-01-2021 to 31-03-2021 Item No: IN ('a70014a3-2e00-41f0-9c3e-6fb8c4f2ab60','26dd67c1-fe37-41fa-b8c5-ff033928a291')
My expected result:
From Date : 01-01-2021 to 31-03-2021 Item No: IN ('ITM001','ITM021')
Please see my fiddle. SQL Fiddle
Parameter used: SELECT[dbo].[func_ReportCriteria2]('2021-01-01','2021-03-31','''a70014a3-2e00-41f0-9c3e-6fb8c4f2ab60'',''26dd67c1-fe37-41fa-b8c5-ff033928a291''') AS 'RESULT 2'
--using STUFF
CREATE FUNCTION [dbo].[func_ReportCriteria2]
(#FromDate DateTime
,#ToDate DateTime
,#Item_List NVARCHAR(MAX)
)
RETURNS nvarchar(max)
AS
BEGIN
DECLARE #CRITERIA NVARCHAR(MAX)
DECLARE #sqlCommand NVARCHAR(MAX)
DECLARE #ItemResult NVARCHAR(MAX)
SET #sqlCommand = ''
IF(ISNULL(#Item_List,'') != '')
BEGIN
--find ItemCode and concatenate based on ItemGuid
--error occur here
SET #ItemResult = STUFF( (SELECT ',' + ItemCode
FROM Item
WHERE ItemGuid IN (#Item_List)
FOR XML PATH('')), 1, 1, '')
SET #sqlCommand = 'Item No: IN ('+ #ItemResult +') '
END
SET #CRITERIA = 'From Date : ' + CONVERT(NVARCHAR(19),#FromDate,105) + ' to ' + CONVERT(NVARCHAR(19),#ToDate,105)
+ CHAR(13)+CHAR(10) + #sqlCommand
RETURN #CRITERIA
END
Please check if this fit your need:
declare #FromDate CHAR(10) ,#ToDate CHAR(10), #Item_List nvarchar(MAX)
select
#FromDate = '2021-01-01',-- make sure to convert the DATE from the table to NVARCHAR using style 120
#ToDate = '2021-03-31',-- make sure to convert the DATE from the table to NVARCHAR using style 120
#Item_List = '''a70014a3-2e00-41f0-9c3e-6fb8c4f2ab60'',''26dd67c1-fe37-41fa-b8c5-ff033928a291'''
------------------ Solution --------------------
-- Important! No reason for scalar function! Use it inline your query directly
SELECT
N'From Date : ' + #FromDate + ' to ' + #ToDate + N' Item No: IN (' + STRING_AGG(''''+ItemName+'''',',') + N')'
FROM Item
WHERE ItemGuid in (
-- Your string includes quotes which we must clear befor CONVERT to GUIDE
SELECT REPLACE([value],'''','') FROM STRING_SPLIT(#Item_List, ',')
)
Note! concat input text to string might be NOT safe and NOT recommended. It has a potential to SQL Injection!
Note: You probably plan a dynamic query, which will SELECT data from the table using the above string, which you asked to build. In this case, this seems like "XY problem" since you probably do not need to build this string at all. You can use the same approach to split string input and execute a direct SELECT query from your table. If we knew what is your final requested result is, then we could help in this as well, but the approach is the same is above code
Try apply convert itemguid
Change WHERE ItemGuid IN (#ItemList)
To WHERE cast(ItemGuid as NVARCHAR(MAX)) IN (#ItemList)

SQL Query which returns records with data type date and value '01/01/2001'?

Hello I am currently converting data for a client. I am importing "|" delimited text files in to SQL Server 2008 R2. The customer has used '01/01/0001' as a blank date; however when i import this value SQL Server see's this date as "01/01/2001".
My original work around was importing as char(10) and then altering after the import. This worked for some but I have discovered that it doesn't always work!!!! Frustrating....
I need to do a search of all data types date with a value of '01/01/2001'
If you want to just update all instances to NULL (which is much better than some magic 01/01/0001 value) then you can say:
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += N'
UPDATE '
+ QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
+ '.' + QUOTENAME(OBJECT_NAME([object_id]))
+ ' SET ' + QUOTENAME(name) + ' = NULL
WHERE ' + QUOTENAME(name) + ' = ''20010101'';'
FROM sys.columns
WHERE system_type_id = 40; -- date
PRINT #sql;
--EXEC sp_executesql #sql;
Now, I suspect the cases where this didn't work are cases where the data type is NOT in fact date but rather datetime / smalldatetime. So you may want this instead:
WHERE system_type_id IN (40,42,43,58,61);
If you still want to use this hocus pocus you can change this line:
+ ' SET ' + QUOTENAME(name) + ' = NULL
To this:
+ ' SET ' + QUOTENAME(name) + ' = ''00010101''
But this won't work if the column is datetime/smalldatetime!
Note that you should always use YYYYMMDD. This MM/DD/YYYY stuff is a bad habit and prone to misinterpretation up and down the stack.

Stored Procedure to return/result a string

I just started working/learning store procedures. I'm just wondering if it's possible for a Store Procedure to return a string.
Right now the store procedure that i'm working on takes one parameter (customer #) and returns two fields- vehicle # and ETA. I'm just wondering if this could be put on a string like "Your vehicle # is 1234 with ETA in 10 minutes." or some kind of a message if no value is returned.
Thanks in advance.
CREATE PROCEDURE GetVehicleInfo
#CustId INT
OUTPUT AS
RETURN (SELECT 'Your vehicle # is ' + id + ' with ETA in ' + ETA + ' minutes'
FROM YourTable WHERE CustId = #CustId )
GO
Well, once I was returning a full link :) In MSSQL for instance, you might first declare a result table in the procedure and at the end of the procedure you can do the following statement:
SELECT 'whatever string you want to put' + columnName + ' whatever...' FROM #result
Where #result is the declared table
Edit: case where the columnName type is INT you can use the CONVERT function. Hope this helps.
For Sql server, it is as simple as the below code:
select 'Your vehicle # is ' + vehiclenum + ' with ETA in ' eta ' minutes' from table_1
where your_select_criteria
In that sql vehiclenum and eta are both column names from table_1 but you can equally do a join in this query.
If vehiclenum is an int then you need to convert it using the convert function like so:
select 'Your vehicle # is ' + convert(varchar(10), vehiclenum) + ' with ETA in ' eta ' minutes'
from table_1
where your_select_criteria
The last piece of the puzzle is getting the value out into code. As it is, this will return a record set.
Using the SqlClient you would use the ExecuteScalar method as describe here on MSDN.
var outputText = cmd.ExecuteScalar();

The best way to add a concatenated string of multiple fields to a stored procedure

I have 14 datetime fields in my database. Ive been asked to return a single field of the 14 dates as one string field. Right now my stored proc looks kinda like this:
convert(varchar, [DTMON_F],108) as mondayFrom,
convert(varchar,[DTMON_T],108) as mondayTo,
convert(varchar,[DTTUES_F],108) as tuesdayFrom,
convert(varchar,[DTTUES_T],108) as tuesdayTo,
I want to have a single field called extendedDetails that is in the format HHmm - HHmm, HHmm - HHmm
This returns for example "10:20:00" so I'll have to somehow cut this to look like "1020" and then somehow concat all of them.
convert(varchar, [DTMON_F],108) as mondayFrom
SELECT
REPLACE
(
convert(char(5), [DTMON_F],108) + ' - ' +
convert(char(5),[DTMON_T],108) + ' - ' +
convert(char(5),[DTTUES_F],108) + ' - ' +
convert(char(5),[DTTUES_T],108) + ' - ' +
...
, ':', '') AS whatever
FROM MYTABLE

Having some Dynamic SQL issues with INT type

Hello Im using SQL2000 so I build a Dynamic Query and in the last case I have this :
IF (#apepac is not null and #nompac is not null and #month is not null )
SELECT #DynaSQL_1= #DynaSQL_1 + ' AND PACIENTE.apellidos like ''' + #apepac + '%'''+
' AND PACIENTE.nombres like ''' + #nompac + '%'''+
' AND DATENAME(MONTH,honorariotecnologo.fechaestudio) = ''' + #month +'''' +
' AND YEAR(honorariotecnologo.fechaestudio) = '+#year+''
so the parameter #year is declared in this way :
DECLARE #year int,
and the error I get from SQL output is :
Msg 245, Level 16, State 1, Line syntax
43Error to convert the nvarchar value '
What could be wrong?
Thanks!
By the way, Why if the parameter is declared as INT, on the body query it must have to be casted / converted? ...
You have to cast or convert the INT to a NVARCHAR. Google CAST CONVERT TSQL.
You need to cast your #Year as a character value.
Try this:
' AND YEAR(honorariotecnologo.fechaestudio) = ' + CAST(#year AS varchar(10))
You want this to take care of the conversion error...
' AND YEAR(honorariotecnologo.fechaestudio) = '+CAST(#year AS VARCHAR)
You want this if you want to add the single quote to the end of your string.
' AND YEAR(honorariotecnologo.fechaestudio) = '+CAST(#year AS VARCHAR) + ''''