Converting Varchar to Datetime for Stored procedure input - sql

I want to use a datetime parameter in a stored procedure, in T-SQL, that if NULL will revert to 12/31/9999.
My code looks like this:
EXEC abc.someStoredProc #i_param1, #i_param2, ISNULL(#l_Termination_date, '12/31/9999')
I get an error:
Incorrect syntax near '#l_Termination_date'
I've tried using convert and cast (for example:
ISNULL(#l_Termination_date,CAST('12/31/9999' AS datetime))
but can't seem to get it right. What am I doing wrong?

You can pass variables or literals as arguments to execute a stored procedure, (or call one of a few specific functions), but what you can't do is have arbitrary expressions.
Move it to a separate step:
SET #l_Termination_date = ISNULL(#l_Termination_date,'99991231')
EXEC abc.someStoredProc
#i_param1
, #i_param2
,#l_Termination_date
(Or use a separate variable if you don't want to overwrite #l_Termination_date)

DECLARE #l_Termination_date DATE ;
SET #l_Termination_date = ISNULL(#l_Termination_date,'12/31/9999')
EXEC dbo.USP_abc.someStoredProc (
#i_param1
, #i_param2
,#l_Termination_date )

Related

How to extract value from a XML column in SQL SERVER using a variable

I want to extract value from XML using XML value function. The path of the value, in this case, is stored in a variable. Check below script
DECLARE #keyPathNg NVARCHAR(max)
DECLARE #xml_col XML
SET #keyPathNg = '/note/to/text()'
SET #xml_col = '<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Dont forghttps://stackoverflow.com/questions/10408445/the-argument-1-of-the-xml-data-type-method-value-must-be-a-string-literalet me this weekend!</body></note>'
select #xml_col.value('(sql:variable("#keyPathNg"))[1]','nvarchar(max)') ;
It's giving the output:
/note/to/text()
However, the output should be Tove
I am successfully able to extract the value when using a hardcoded path instead of the variable using the below query.
select #xml_col.value('(/note/to/text())[1]','varchar(max)')
As mentioned, in my case path is stored in a variable, please suggest.
I have read this answer on stack overflow The argument 1 of the XML data type method "value" must be a string literal, but as checked I am not getting the value of the variable as output, maybe I am missing some thing.

How to include ' in dynamic query?

I need to generate a query like this
SELECT max(batch_sk) INTO ln_batch FROM test_app.table WHERE categ_cd = 'ABC' ;
This 'ABC' is coming as an input parameter in the procedure(in_code).
I have tried different version of the below mentioned query , but not getting the correct query .
SET lv_query ='SELECT max(batch_sk) INTO ln_batch FROM test_app.table
WHERE categ_cd = ''''||in_code||'';
How to include those ' in the query?
Several things wrong here.
Mismatched / un-escaped quotes
Concatenation operates on character strings and there is no implicit
conversion from TIMESTAMP to VARCHAR. You would need to convert with explicit CAST or TO_CHAR, etc. first
SELECT … INTO is not allowed as dynamic SQL. Perhaps parameterized static SQL with a host variable?
SELECT max(batch_sk) INTO ln_batch FROM test_app.table WHERE categ_cd=:in_code;
otherwise you need a dynamic cursor to supply the value as a literal
DECLARE lv_cur CURSOR for lv_stmt;
SET lv_query ='SELECT max(batch_sk) FROM test_app.table WHERE categ_cd = '''||in_code||'''';
PREPARE lv_stmt FROM lv_query;
OPEN lv_cur;
FETCH lv_cur INTO ln_batch;
CLOSE lv_cur;

SSIS Variable in Data Flow Task used incorrectly

In the SSIS Package I have several Data flow Tasks where I want to use one input global variable named KOERSEL to go back in time and call data set specifically in time.
When I try to run it I am getting the error:
Syntax error, permission violation, or other nonspecific error.
when I change ? to 1 in the SQL command text, the code is running fine. So what am I missing?
DECLARE #dt DATETIMEOFFSET = SWITCHOFFSET(CONVERT(DATETIMEOFFSET, GETDATE()), '-04:00')
DECLARE #interval INT = ?
SET #interval = -1 * #interval
DECLARE #DATE_OPG DATE
SELECT #DATE_OPG = A.DWH_PR_DATO
FROM TABLE AS A
WHERE YEAR(A.DWH_PR_DATO)=YEAR(DATEADD(MONTH,#interval,#dt)) AND
MONTH(A.DWH_PR_DATO)=MONTH(DATEADD(MONTH,#interval,#dt))
ORDER BY A.DWH_PR_DATO DESC
SELECT DISTINCT COLUMN 1,
COLUMN 1,
COLUMN 1,
FROM TABLE 1
WHERE DATE_OPG=#DATE_OPG
UNION ALL
SELECT DISTINCT COLUMN 2,
COLUMN 2,
COLUMN 2,
FROM TABLE 2
WHERE DATE_OPG=#DATE_OPG
...
Screenshot
I don't think that the following error is the real issue.
Incorrect syntax near ')'.
The query parser was not able to parse the query because you have added a minus sign before the question mark ?. In this answer i will try to clarify the main cause of the error you are seeing.
Parameter data type vs Variable data type
Based on the official OLEDB Source - Documentation:
The parameters are mapped to variables that provide the parameter values at run time. The variables are typically user-defined variables, although you can also use the system variables that Integration Services provides. If you use user-defined variables, make sure that you set the data type to a type that is compatible with the data type of the column that the mapped parameter references.
This implies that the parameter datatype is not related to the variable data type.
So when you are using -? inside the SQL Command the query parser are not able to identify the parameter metadata even if it is mapped to an integer variable.
You can check my answer on the link below, it contains much details with experiments:
Date calculation with parameter in SSIS is not giving the correct result
Solving the problem
(1) Force parameter data type
Try using CAST() function to force the parameter data type and assign it to a variable in the same way you have declared #dt:
DECLARE #interval INT = CAST(? as INT)
--If you want to get a negative number else ignore the row below
SET #interval = -1 * #interval
DECLARE #dt DATETIMEOFFSET = SWITCHOFFSET(CONVERT(DATETIMEOFFSET,GETDATE()),'-04:00');
DECLARE #DATE_OPG DATE;
SELECT #DATE_OPG = DWH_PR_DATEO
FROM TableName
WHERE YEAR(DWH_PR_DATO) = YEAR(DATEADD(MONTH,#interval ,#dt)) AND
MONTH(DWH_PR_DATO) = MONTH(DATEADD(MONTH,#interval ,#dt))
ORDER BY DWH_PR_DATO DESC
(2) Using Expressions
You can use Expressions while building the SQL Command:
Add a variable of type string (Example: #[User::strQuery])
Define an Expression within this variable:
"DECLARE #dt DATETIMEOFFSET = SWITCHOFFSET(CONVERT(DATETIMEOFFSET,GETDATE()),'-04:00');
DECLARE #DATE_OPG DATE;
SELECT #DATE_OPG = DWH_PR_DATEO
FROM TableName
WHERE YEAR(DWH_PR_DATO) = YEAR(DATEADD(MONTH,-" + #[User::KOERSEL] + ",#dt)) AND
MONTH(DWH_PR_DATO) = MONTH(DATEADD(MONTH,-" + #[User::KOERSEL] + ",#dt))
ORDER BY DWH_PR_DATO DESC"
In the OLEDB Source choose SQL Command from variable and Select #[User::strQuery]
Experiments
I tried a similar query using the AdventureWorks database:
DECLARE #dt DATETIMEOFFSET = SWITCHOFFSET(CONVERT(DATETIMEOFFSET, GETDATE()), '-04:00')
DECLARE #interval INT = CAST(? as INT)
SET #interval = -1 * #interval
DECLARE #DATE_OPG DATE
SELECT #DATE_OPG = A.[ModifiedDate]
FROM [AdventureWorks2016CTP3].[HumanResources].[Employee] AS A
WHERE YEAR(A.[ModifiedDate])=YEAR(DATEADD(MONTH,#interval,#dt)) AND
MONTH(A.[ModifiedDate])=MONTH(DATEADD(MONTH,#interval,#dt))
ORDER BY A.[ModifiedDate] DESC
SELECT * FROM [AdventureWorks2016CTP3].[HumanResources].[Employee]
WHERE [ModifiedDate] = #DATE_OPG
And the query is parsed successfully
Instead of -? use the following logic:
-1 * (CAST(? as int))
if you just want to pass the variable as parameter without a negative sign then just use:
(CAST(? as int))
You cannot assign a negative sign to the parameter because it will cause some conflict since the query parser will not be able to define the parameter data type.
If it still throwing and exception, check the following link it contains a workaround:
Problem With Parameter Multiplied By Negative Value In Where Clause in OLE DB Source

SQL return date from function gets an error in setting variable

I get the error "Operand data type varchar is invalid for subtract operator." in line 6 where i set the dummy variable.
When i remove the first part there is no error, so i think the setting of the variable also tries to execute some of the functions in the string.
Is is possible to set a variable with functions without having the setting also trying to execute the functions? Or should this be done in an entirely different way?
All i want is the option to use dbo.TimeInterval(7) (or something like this) instead of "REPLACE([US-Date],'-','') between CONVERT(int,CONVERT(varchar(10),GETDATE()-7,112)) and CONVERT(int,CONVERT(varchar(10),GETDATE(),112))" when i want the time interval of 7 days from today...
CREATE FUNCTION dbo.TimeInterval(#Input VARCHAR(1000))
RETURNS VARCHAR(1000)
AS BEGIN
DECLARE #dummy VARCHAR(1000)
SET #dummy = 'REPLACE([US-Date],'-','') between CONVERT(int,CONVERT(varchar(10),GETDATE()-Tidsinterval,112)) and CONVERT(int,CONVERT(varchar(10),GETDATE(),112))'
SET #dummy = REPLACE(#dummy, 'Tidsinterval',#Input)
RETURN #dummy
END

why it doesnt accept a concated string as parameter in SP?

I wrote an SP that works perfectly. I was calling the SP with regular parameters and worked. However, now I need to call the SP like below
EXEC #v_nReturn = sp_get_next_value 'LP_' + #WhID + '_COUNTER'
The intellisense gives an error on the first '+' sign.
It says "incorrect syntax err...."
#WhID is NVARCHAR(10), so I shouldn't convert it to NVARCHAR.
what is the problem?
SQL Server doesn't do (full) expression parsing when you call a stored procedure. This is definitely an area where a small change would be highly convenient, although there are probably good reasons for the limitation.
As mentioned in a comment, use a separate variable:
DECLARE #arg varchar(256) = 'LP_' + #WhID + '_COUNTER';
EXEC #v_nReturn = sp_get_next_value #arg;
Be careful if #WhID is numeric. Then you need to convert the value to a string first.
Try with parens:
EXEC #v_nReturn = (sp_get_next_value 'LP_' + #WhID + '_COUNTER')