How to grab the value of the output parameter in execute sp_executesql? - sql

Please forgive newbie's ignorance!
How do I grab the value of the output parameter in execute sp_executesql?
I can see the output but cannot get to it:
DECLARE #LastActivity nvarchar(100)
DECLARE #LastActivityDate datetime
DECLARE #sql nvarchar(MAX)
DECLARE #RowsToProcess int
DECLARE #CurrentRow int
DECLARE #SelectCol1 nvarchar(100)
DECLARE #SelectCol2 nvarchar(100)
DECLARE #SelectCol3 nvarchar(100)
DECLARE #LastDate TABLE (RowID int not null primary key identity(1,1), col4 nvarchar(MAX), col5 sql_variant)
DECLARE #table1 TABLE (RowID int not null primary key identity(1,1), col1 nvarchar(100),col2 nvarchar(100),col3 nvarchar(100))
INSERT into #table1 (col1,col2,col3)(SELECT t.name AS col1, c.name AS col2, m.Field1 as col3
FROM sys.columns c INNER JOIN
sys.tables t ON c.object_id = t.object_id INNER JOIN
sys.schemas s ON t.schema_id = s.schema_id INNER JOIN
dbo.MERGE_TABLES m ON m.Table_Name=t.name
WHERE c.name LIKE '%[_]DATE%' and m.[Enabled]='Y')
SET #RowsToProcess=##ROWCOUNT
SET #CurrentRow=0
WHILE #CurrentRow<#RowsToProcess
BEGIN
SET #CurrentRow=#CurrentRow+1
SELECT #SelectCol1=col1,#SelectCol2=col2,#SelectCol3=col3 FROM #table1 WHERE RowID=#CurrentRow
SET #sql='SELECT ' + '[dbo].[ConvertToDatetime](MAX(' + #SelectCol2 + '))' + ' FROM ' + #SelectCol1 + ' Where ' + #SelectCol3 + ' = ' + '''0722607QZ'''
Declare #params as nvarchar(MAX)
Set #params = '#date sql_variant output'
Declare #date as sql_variant;
execute sp_executesql
#sql
,#params
,#date output
Select #date
INSERT into #LastDate VALUES (#sql, #date)
end
select col4,col5 from #LastDate
select col4,col5 from #LastDate gives me the SQL script in clo4 but col5 is empty! I need to store the #date as I still need to get the Max(#date)
Thanx a million.
SET #sql='set #date =('SELECT ' + '[dbo].[ConvertToDatetime](MAX(' +
#SelectCol2 + '))' + ' FROM ' + #SelectCol1 + ' Where ' + #SelectCol3
+ ' = ' + '''0722607QZ''' ) '
the above sql gives me error: Incorrect syntax near '.'
SET #sql='set #date =(SELECT [dbo].[ConvertToDatetime](MAX( + #SelectCol2 + ))
FROM #SelectCol1 Where #SelectCol3 ''=0722607QZ'' ) '
The above sql gives the error: Must declare the scalar variable "#SelectCol2"
SET #sql='SELECT ' + #date + '=convert(nvarchar(100), [dbo].[ConvertToDatetime](MAX(' + #SelectCol2 + ')))' + ' FROM ' + #SelectCol1 + ' Where ' + #SelectCol3 + ' = ' + '''0722607QZ'''
the above produces the error : Implicit conversion from data type sql_variant to nvarchar is not
allowed. Use the CONVERT function to run this query.
SET #sql='SELECT ' + #date + '=convert(nvarchar(MAX),(MAX(' + #SelectCol2 + '))' + ' FROM ' + #SelectCol1 + ' Where ' + #SelectCol3 + ' = ' + '''0722607QZ'''
the above produces no error but all output is NULL, no values.

Your syntax looks ok but you never assign to the output variable #date hence no value.
Instead of;
SET #sql='SELECT ...'
You need;
SET #sql='set #date = (SELECT ...'
Can't you use a better type than sql_variant?

Related

SQL Server : how to insert using variable

I am trying to insert data into a SQL Server table using a variable. I tried
DECLARE #table NVARCHAR(50) = 'ToolList',
#val NVARCHAR(50) = 'test'
EXEC ('INSERT INTO ' + #table + 'SELECT ' + #val)
and
EXEC ('INSERT INTO ' + #table + '([col1]) VALUES(' + #val +')'
but still get an error that says
Incorrect syntax near 'test'.
you missed a space before SELECT and the #val should enclosed in single quote
DECLARE #table nvarchar(50) = 'ToolList',
#val nvarchar(50) = 'test'
EXEC ( 'INSERT INTO ' + #table + ' SELECT ''' + #val + '''')
when you use Dynamic SQL, it is easier to form the query in a variable so that you can print out , inspect the value before execution
select #sql = 'INSERT INTO ' + #table + ' SELECT ''' + #val + ''''
print #sql
exec (#sql)
You'd better use sp_executesql that allows for statements to be parameterized, to avoid the risk of SQL injection.
DECLARE #Query NVARCHAR(1000),
#table NVARCHAR(50) = 'ToolList'
SET #Query = 'INSERT INTO ' + #table + ' SELECT #val'
EXEC sp_executesql #Query, N'#val nvarchar(50)', #val = 'test'
sp-executesql-transact-sql
You can also use CHAR(39) instead of adding single quotes every time for better readability. And also, you have not added a space after the variable which contains the table name.
Query
declare #table nvarchar(50) = 'ToolList',
#val nvarchar(50) = 'test2';
declare #sql as varchar(max) = 'insert into ' + #table
+ ' select ' + char(39) + #val + char(39);
exec(#sql);
You need 4 singlequotes before the #val field as it is a string and all strings needs to be encapsulated in single quotes.
You can print the dynamic string using PRINT command check what the final string you are going to execute.
DECLARE #table VARCHAR(50) = 'ToolList'
DECLARE #val VARCHAR(50) = 'test'
DECLARE #DSQL AS VARCHAR(MAX) = ''
SET #DSQL = #DSQL + ' INSERT INTO [' + #table + ']' + '
SELECT ' + '''' + #val + ''''
--PRINT #DSQL
EXEC(#DSQL)

Return Row Count Using Dynamic SQL

I'm trying to run the following Dynamic SQL statement:
#Tbl, #Fld, and #LookupValue have all been set according to Table to search, Field (Or Column) to search and column value to compare.
DECLARE #Sql AS VARCHAR(500)
SET #Sql = 'SELECT COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
I want to store the result into a variable so I can check to see if there are any returned rows. This statement is in the middle of a WHILE construct that is checking several tables and fields.
If records are found, then I want to display:
SET #Sql = 'SELECT ' + #Fld +
' FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
Yes, you can store it in a typed variable and use sp_executesql like
DECLARE #Sql AS NVARCHAR(500);
DECLARE #cnt INT;
SET #Sql = 'SELECT #cnt = COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + '''';
EXEC sp_executesql #Sql, N'#cnt INT OUTPUT', #cnt OUTPUT;
SELECT #cnt;
you can create a temporary table and store the count value.
if object_id('tempdb.#mycount') is null
create table #mycount ( countVal int);
DECLARE #Sql AS VARCHAR(500)
SET #Sql = 'INSERT INTO #mycount
SELECT COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
select countVal from #mycount
-- once the temp table usage is done, you can delete it
drop table #mycount

Operand data type nvarchar is invalid for subtract operator

I m trying to create a dynamic sql query.But in the dynamic query i couldnt figure how to use complex functions.I tried many combination but it s till giving eror.it is giving eror in the
column which includes RTIM LTRIM function.code and error as shown below.
declare #karorani decimal set #karorani=0
declare #toplamkar decimal set #toplamkar=0
declare #toplamciro decimal set #toplamciro=0
declare #odemetipi nvarchar(12) set #odemetipi='Hepsi'
declare #columns nvarchar(100) set #table='new_flightreservation'
declare #sqlcommand nvarchar(max) set #columns='new_salesorderid'
declare #table nvarchar(100)
set #sqlcommand='select ' + #columns + ' from ' + #table +' M ' + 'LEFT JOIN '+
'new_new_paymnet_'+#table +' F '+ ' on ' + ' M.'+#table+'Id'+'=F.'+#table+'Id' +
' left join new_payment P '+'on '+ 'F.new_paymentid=P.new_paymentId where
'(LTIM(RTRIM((left (P.new_name,(CHARINDEX('-',P.new_name)-1))))=#odemetipi //error
or #odemetipi+=Hepsi)'
execute (#sqlcommand)
error: Operand data type nvarchar is invalid for subtract operator.
There's lots of issues with this code
Try
declare #karorani decimal set #karorani=0
declare #toplamkar decimal set #toplamkar=0
declare #toplamciro decimal set #toplamciro=0
declare #odemetipi nvarchar(12) set #odemetipi='Hepsi'
declare #table sysname set #table='new_flightreservation'
declare #columns nvarchar(100) set #columns='new_salesorderid'
declare #sqlcommand nvarchar(max)
set #sqlcommand='
select ' + #columns + '
from ' + #table +' M ' + '
left join new_new_paymnet_' + #table +' F
on M.' + #table + 'Id=F.' + #table + 'Id
left join new_payment P
on F.new_paymentid=P.new_paymentId
where (ltim(rtrim((left(P.new_name,(charindex(''-'',P.new_name)-1))))=''' + #odemetipi + '''
or ''' + #odemetipi + '''=''Hepsi'')'
print #sqlcommand
-- exec(#sqlcommand)

Table Columns as parameters to Stored Procedure [duplicate]

I have created a procedure in dynamic SQL which has a select statement and the code looks like:
ALTER PROCEDURE cagroup (
#DataID INT ,
#days INT ,
#GName VARCHAR(50) ,
#T_ID INT ,
#Act BIT ,
#Key VARBINARY(16)
)
AS
BEGIN
DECLARE #SQL NVARCHAR(MAX)
DECLARE #SchemaName SYSNAME
DECLARE #TableName SYSNAME
DECLARE #DatabaseName SYSNAME
DECLARE #BR CHAR(2)
SET #BR = CHAR(13) + CHAR(10)
SELECT #SchemaName = Source_Schema ,
#TableName = Source_Table ,
#DatabaseName = Source_Database
FROM Source
WHERE ID = #DataID
SET #SQL = 'SELECT ' + #GName + ' AS GrName ,' + #BR
+ #T_ID + ' AS To_ID ,' + #BR
+ #DataID + ' AS DataSoID ,' + #BR
+ #Act + ' AS Active ,' + #BR
+ Key + ' AS key' + #BR
+ 'R_ID AS S_R_ID' + #BR
+ 'FROM' + #DatabaseName + '.'
+ #SchemaName + '.'
+ #TableName + ' t' + #BR
+ 'LEFT OUTER JOIN Gro g ON g.GName = '
+ #GName + #BR + 'AND g.Data_ID] =' + #DataID + #BR
+ 't.[I_DATE] > GETDATE() -' + #days + #BR
+ 'g.GName IS NULL
AND ' + #GName + ' IS NOT NULL
AND t.[Act] = 1' + #BR
PRINT (#SQL)
END
When I am executing this procedure with this statement:
Exec dbo.cagroup 1,10,'[Gro]',1,1,NULL
I am getting the following error.
Msg 245, Level 16, State 1, Procedurecagroup, Line 33
Conversion failed when converting the nvarchar value 'SELECT [Gro] AS GName ,
' to data type int.
Where am I doing wrong?
You need to CAST all numbers to nvarchar in the concatenation.
There is no implicit VBA style conversion to string. In SQL Server data type precedence means ints are higher then nvarchar: so the whole string is trying to be CAST to int.
SET #SQL = 'SELECT ' + #GName + ' AS GrName ,' + #BR
+ CAST(#T_ID AS nvarchar(10)) + ' AS To_ID ,' ...
Edit: Will A has a good point: watch for NULLs!
If you have to build this kind of dynamic SQL, it is better to get the column information from the meta-data than to pass it around.
Select * from Information_Schema.Columns Where Table_name=#TableName
The you have to write an ugly cursor to build the SQL. Expect performance problems. I do lots of this during development to write code for me, but I don't dare run it in production.

Dynamic SQL error converting nvarchar to int

I have created a procedure in dynamic SQL which has a select statement and the code looks like:
ALTER PROCEDURE cagroup (
#DataID INT ,
#days INT ,
#GName VARCHAR(50) ,
#T_ID INT ,
#Act BIT ,
#Key VARBINARY(16)
)
AS
BEGIN
DECLARE #SQL NVARCHAR(MAX)
DECLARE #SchemaName SYSNAME
DECLARE #TableName SYSNAME
DECLARE #DatabaseName SYSNAME
DECLARE #BR CHAR(2)
SET #BR = CHAR(13) + CHAR(10)
SELECT #SchemaName = Source_Schema ,
#TableName = Source_Table ,
#DatabaseName = Source_Database
FROM Source
WHERE ID = #DataID
SET #SQL = 'SELECT ' + #GName + ' AS GrName ,' + #BR
+ #T_ID + ' AS To_ID ,' + #BR
+ #DataID + ' AS DataSoID ,' + #BR
+ #Act + ' AS Active ,' + #BR
+ Key + ' AS key' + #BR
+ 'R_ID AS S_R_ID' + #BR
+ 'FROM' + #DatabaseName + '.'
+ #SchemaName + '.'
+ #TableName + ' t' + #BR
+ 'LEFT OUTER JOIN Gro g ON g.GName = '
+ #GName + #BR + 'AND g.Data_ID] =' + #DataID + #BR
+ 't.[I_DATE] > GETDATE() -' + #days + #BR
+ 'g.GName IS NULL
AND ' + #GName + ' IS NOT NULL
AND t.[Act] = 1' + #BR
PRINT (#SQL)
END
When I am executing this procedure with this statement:
Exec dbo.cagroup 1,10,'[Gro]',1,1,NULL
I am getting the following error.
Msg 245, Level 16, State 1, Procedurecagroup, Line 33
Conversion failed when converting the nvarchar value 'SELECT [Gro] AS GName ,
' to data type int.
Where am I doing wrong?
You need to CAST all numbers to nvarchar in the concatenation.
There is no implicit VBA style conversion to string. In SQL Server data type precedence means ints are higher then nvarchar: so the whole string is trying to be CAST to int.
SET #SQL = 'SELECT ' + #GName + ' AS GrName ,' + #BR
+ CAST(#T_ID AS nvarchar(10)) + ' AS To_ID ,' ...
Edit: Will A has a good point: watch for NULLs!
If you have to build this kind of dynamic SQL, it is better to get the column information from the meta-data than to pass it around.
Select * from Information_Schema.Columns Where Table_name=#TableName
The you have to write an ugly cursor to build the SQL. Expect performance problems. I do lots of this during development to write code for me, but I don't dare run it in production.