Having some Dynamic SQL issues with INT type - sql-server-2000

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) + ''''

Related

SQL : Getting Incorrect Syntax near '=' While using CASE statement with variables

I am trying to perform the below query where some variables are being used. This below SQL code is a part of a stored procedure. Idea is to dynamically set the target columns and its values based on FileKey.
DECLARE #TargetColNames nvarchar(max) = '';
DECLARE #SourceColNames nvarchar(max) = '';
DECLARE #SourceColNamesInsert nvarchar(max) = '';
DECLARE #UpdateColumns nvarchar(max) = '';
SELECT
CASE
WHEN #FileKey IN ('s_1','s_2')
THEN #TargetColNames = #TargetColNames + ' [CreatedUser], [UpdatedUser], [CreatedDateTime],[UpdatedDateTime],[IsDeleted],[DeletedOn]'
ELSE #TargetColNames = #TargetColNames + ' [CreatedUser], [UpdatedUser], [CreatedDateTime], [UpdatedDateTime]'
END,
#SourceColNames = CONCAT('CreatedUser','UpdatedUser','CreatedDateTime', 'UpdatedDateTime'),
#SourceColNamesInsert = CONCAT(''',#User, ''',''',#User, ''', 'Getdate()', 'Getdate()' ),
CASE
WHEN #FileKey IN ('s_1','s_2')
THEN #UpdateColumns = CONCAT('Target.UpdatedUser= ''',#User,''', 'Target.[IsDeleted]=0','Target.[DeletedOn]=null')
ELSE #UpdateColumns = CONCAT('Target.UpdatedUser= ''',#User,''', 'Target.UpdatedDateTime=Getdate()')
END
The above SQL statement throws an error:
Msg 102, Level 15, State 1, Procedure uspDynamicStageToPropLayer1, Line 165 [Batch Start Line 5]
Incorrect syntax near '='.
What am I missing here? Maybe this is quite a silly mistake...
Also, by doing concat with your quoted parts, you might allow SQL injection into your query even building dynamically. What if a user's name (or forced parameter has a leading single quote, then garbage injection such as
#User = ';drop table X --
Having said that, some of the stuff could be more simplified, such as
SELECT
#TargetColNames = #TargetColNames
+ ' [CreatedUser], [UpdatedUser], [CreatedDateTime], [UpdatedDateTime]'
+ CASE WHEN #FileKey IN ('s_1','s_2')
THEN ', [IsDeleted], [DeletedOn]'
else ''
end
For the insert, you will probably get a failure. If you look at a possible result of the #User
#SourceColNamesInsert = concat(''',#User, ''',''',#User, ''',
'Getdate()', 'Getdate()' ),
will result with the value below which is not what I think is intended. Notice no comma's between values because the triple ' is creating start and end literals, and leaves no actual comma between column insert values.
',#User, '',#User, 'Getdate()Getdate()
But instead...
select concat('''#User'', ''#User''', ', Getdate(), Getdate()' );
which will result in...
'#User', '#User', Getdate(), Getdate()
The ''' actually creates an opening quoted string immediately with the value after it, then the '' (double) closes the quoted string, but it also adds the comma separator before the next '' (double) to start second user and ''' (triple) to close the second #User, then adding comma and both getdate() calls.
'#User', '#User', Getdate(), Getdate()
Now, if the value for #User was 'Bob', and your intent was to have the string output as
'Bob', 'Bob', Getdate(), Getdate()
change to
select concat('''', #User, ''', ','''', #User, '''', ', Getdate(), Getdate()' );
The '''' (quad) means I want to open a string, do a single quote (by the inner two ''), and close this as its own string. then get the value of the #User. Then follow by an open string ' with '' for closing the quote around the name, then open a single quote to start the next, the comma before starting the next quote for the second user and closing it as well via '''', then the value of the user again, and finally closing the second user with close quote ''''. Finally adding a comma and getdate() calls. Yes, stupid tricky in the quoting.
An easier implementation without CONCAT() is just using + between each explicit part such as
select '''' + #User + '''' + ', ' + '''' + #User + '''' + ', Getdate(), getdate()' ;
where each '''' is a single quote thus resulting in
' + Bob + ' + , + ' + Bob + ' + , Getdate(), getdate()
resulting in
'Bob', 'Bob', Getdate(), getdate()
I'll leave the final UpdateColumns to you to confirm your intended output.
But, as mentioned, beware of possible SQL injection when you are dynamically building SQL statements with embedded parameter values as this appears to be doing.
Here is another way to approach this:
Declare #FileKey varchar(10) = 's_3'
, #TargetColNames nvarchar(max) = ''
, #SourceColNames nvarchar(max) = ''
, #SourceColNamesInsert nvarchar(max) = ''
, #UpdateColumns nvarchar(max) = '';
Set #TargetColNames = concat_ws(', ', '[CreatedUser]', '[UpdatedUser]', '[CreatedDateTime]', '[UpdatedDateTime]');
If #FileKey In ('s_1', 's_2')
Set #TargetColNames = concat_ws(', ', #TargetColNames, '[UpdatedDateTime]', '[IsDeleted]', '[DeletedOn]');
Print #TargetColNames;
Set #SourceColNames = concat_ws(', ', '[CreatedUser]', '[UpdatedUser]', '[CreatedDateTime]', '[UpdatedDateTime]');
Set #SourceColNamesInsert = concat_ws(', ', quotename('#User', char(39)), quotename('Getdate()', char(39)), quotename('Getdate()', char(39)));
Print #SourceColNames;
Print #SourceColNamesInsert;

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)

Trying to use SQL Replace in a non-dynamic way

I have the following statement, where I'm passing in a parameter like this:
'0001,0003'
I was following the REPLACE answer from this question:
SQL IN Statement splitting parameter
But I'm trying to take it out of dynamic sql. My returned result is NULL. Is there anyway to get this to work?
DECLARE #partialLNum varchar(MAX)
DECLARE #lNumConCat varchar(500)
DECLARE #tTemp table(lNum varchar(15))
DECLARE #formatIN varchar(MAX)
set #partialLNum = '0001,0003'
set #formatIN = ''''+ REPLACE(#partialLNum,',',''',''')+''''
insert into #tTemp
select substring(lNum,1,2) + '-' + substring(lNum,3,3) + '-' + substring(lNum,6,2) + '-' + substring(lNum,8,3)
from [rpt].[myView]
where LNum IN (#formatIN)
select #lNumConCat = COALESCE(#lNumConCat +'' , '', '''') + LNum from #tTemp
select #lNumConCat
in takes a list of values. So:
where LNum IN ('0001,0003')
has a list with one element, that happens to have a comment in it.
One way to do what you want is using like:
where ',' + partialLNum + ',' like '%,' + LNum + ',%'
There should suffice, but there are other ways using a split() function as well.

Trying to display a combination of String MM + int DD + int YYYY in SQL Management Studio

I am trying to display a combination of String MM + int DD + int YYYY
in SQL Management Studio. However, i encountered an error like this which says
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the nvarchar value 'November ' to data type int.
My codes are:
SELECT DATENAME(MM, Check_in_date) + ' ' + DAY(Check_in_date) + ' ' +
YEAR(Check_in_date)
FROM Book_Details
Afterwards, i tried casting the Check_in_date into a varchar but encountered an error as well. Any help will be appreciated
You are trying to concatenate a string and an integer.
You need to cast #ID as a string.
try:
SELECT DATENAME(MM, Check_in_date) + ' ' + CAST(DAY(Check_in_date) AS NVARCHAR(2)) + ' ' +
CAST(YEAR(Check_in_date) AS NVARCHAR(4))
FROM Book_Details
if you don't like the space, you may use LTRIM to remove the space
Refer : link
UPDATED on year part

SQL Server: using Case statement in Where clause creates error

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)