I've created the following procedure and every time I try to execute it I get the error
Must declare the scalar variable #BatchId
Essentially, all that I'm trying to do is insert the contents of a raw table into a master table with a batch id (created by a sequencer) for all inserted rows. This seemed simple enough but isn't working properly.
CREATE PROCEDURE [dbo].[usp_SessionsAppend]
#RawTable NVARCHAR(500)
AS
DECLARE #BatchId BIGINT, #SQLString NVARCHAR(MAX)
SET #BatchId = NEXT VALUE FOR [dbo].[BatchID]
SET #SQLString =
'INSERT INTO [Master].[Sessions] (
[ImportTimestamp]
,[TransactionId]
,[ParticpantId]
,[ProviderId]
,[ActivityDate]
,[Attended]
,[Minutes]
,[SurveyCompleted]
,[Instructor]
,[InstructorID]
,[ProgramCode]
,[BatchId]
)
SELECT
GETDATE() AS [ImportTimeStamp]
,NEWID() AS [TransactionId]
,[ParticpantId]
,[ProviderId]
,[ActivityDate]
,[Attended]
,[Minutes]
,[SurveyCompleted]
,[Instructor]
,[InstructorID]
,[ProgramCode]
,#BatchId
FROM' + #RawTable
EXECUTE (#SQLString)
Any help or insight would be greatly appreciated.
Use sp_executesql to pass parameters into the dynamic SQL.
eg
declare #BatchId int = NEXT VALUE FOR [dbo].[BatchID]
declare #RawTable nvarchar(200) = 'foo';
declare #SQLString nvarchar(max) =
'INSERT INTO [Master].[Sessions] (
[ImportTimestamp]
,[TransactionId]
,[ParticpantId]
,[ProviderId]
,[ActivityDate]
,[Attended]
,[Minutes]
,[SurveyCompleted]
,[Instructor]
,[InstructorID]
,[ProgramCode]
,[BatchId]
)
SELECT
GETDATE() AS [ImportTimeStamp]
,NEWID() AS [TransactionId]
,[ParticpantId]
,[ProviderId]
,[ActivityDate]
,[Attended]
,[Minutes]
,[SurveyCompleted]
,[Instructor]
,[InstructorID]
,[ProgramCode]
,#BatchId
FROM ' + quotename(#RawTable)
print #SQLString
exec sp_executesql #SQLString, N'#BatchId int', #BatchId = #BatchId;
Related
How can I store my execution result in datetime variable?
My query look like this:
Declare #F VARCHAR(50) = (select replace ('H-10','-',''));
DECLARE #SQLQuery AS NVARCHAR(500)
set #SQLQuery=
N'SELECT
top 1 DATEADD(MINUTE, -330, time_stamp) as time
FROM
DMD_'+#F+'_DC_data
ORDER BY
time_stamp ASC';
DECLARE #SOR_time datetime
set #SOR_time=Exec (#SQLQuery)
If you want to store the ... execution result in datetime variable..., one solution is to execute the generated statement using sp_executesql with an OUTPUT parameter:
DECLARE #F varchar(50) = (select replace ('H-10', '-', ''));
DECLARE #SOR_time datetime
DECLARE #SQLQuery AS nvarchar(500)
SET #SQLQuery =
N'SELECT TOP 1 #SOR_time = DATEADD(MINUTE, -330, time_stamp) ' +
N'FROM QUOTE_NAME(DMD_' + #F + '_DC_data) ' +
N'ORDER BY time_stamp ASC'
;
DECLARE #rc int
EXEC #rc = sp_executesql
#SQLQuery,
N'#SOR_time datetime OUTPUT',
#SOR_time OUTPUT
IF #rc <> 0 PRINT 'Error'
Try following way. Execute query result store into the table instead of assign to a variable.
Declare #F VARCHAR(50) = (select replace ('H-10','-',''));
DECLARE #SQLQuery AS NVARCHAR(500)
set #SQLQuery=
N'SELECT
top 1 DATEADD(MINUTE, -330, time_stamp) as time
FROM
DMD_'+#F+'_DC_data
ORDER BY
time_stamp ASC';
DECLARE #TempTable TABLE (SOR_time datetime)
insert #TempTable
exec (#SQLQuery)
select * from #TempTable
You can just assign to variable inside query if result set is just a single variable
Declare #F VARCHAR(50) = (select replace ('H-10','-',''));
DECLARE #SQLQuery AS NVARCHAR(500)
DECLARE #SOR_time DATETIME
set #SQLQuery=
N'SELECT
top 1 #SOR_time = DATEADD(MINUTE, -330, time_stamp)
FROM
DMD_'+#F+'_DC_data
ORDER BY
time_stamp ASC';
-- PRINT #SQLQuery
Exec (#SQLQuery)
SELECT #SOR_time
How can I store the result of exec in a variable? The output is JSON.
My SQL query is complex and dynamically generated, so I have to set a variable and execute it.
create PROCEDURE dbo.RetrievePerfCounterData #jsonOutput NVARCHAR(MAX) OUTPUT
AS
BEGIN
declare #sql NVARCHAR(MAX)
SET #sql = ' SELECT TOP (1) getdate() AS ''dateTime'' ,suser_sname()AS ''user'' FOR JSON PATH '
exec (#sql)
END
Here's my attempt at storing the data in a variable:
DECLARE #json AS NVARCHAR(MAX)
EXEC dbo.RetrievePerfCounterData #jsonOutput = #json OUTPUT
DECLARE #myVar VARCHAR(MAX)
DECLARE #SQL NVARCHAR(MAX)
IF OBJECT_ID('tempdb..#t1') IS NOT NULL DROP TABLE #t1
CREATE TABLE #t1 (col1 INT, col2 INT)
INSERT INTO #t1
SELECT 1, 1
UNION
SELECT 1, 2
SET #SQL = 'SET #myVar = (SELECT * FROM #t1 AS T FOR JSON AUTO);'
EXEC sp_executesql #SQL, N'#myVar VARCHAR(MAX) OUT', #myVar OUT
SELECT #myVar
You need to use a subquery:
SET #json = (SELECT TOP (1) getdate() AS [dateTime],suser_sname()AS [user] FOR JSON PATH);
I am inserting records using stored procedure and sp_executesql. Once I insert record using sp_executesql, i need the last inserted identity field value on that session.
ALTER proc [dbo].[spHoldTransaction]
#RegisterNo int,
#StoreID int,
#Department varchar(50),
#TransactionDateFrom date,
#TransactionDateTo date,
#Comment Varchar(50)
AS
BEGIN
DECLARE #RegisterID int;
DECLARE #DatabaseName varchar(15);
DECLARE #Batch int;
SELECT #RegisterID=ID FROM Register WHERE Register.Number = #RegisterNo;
SELECT #Batch = BatchNumber From Batch WHERE Status = 0 and RegisterID = #RegisterID
SET #DatabaseName = 'xxx'
SELECT #Department=''''+REPLACE(#Department,',',''',''')+''''
DECLARE #Qry nvarchar(MAX);
DECLARE #ParamDefinition nvarchar(MAX);
SET #ParamDefinition = N'#comment nvarchar(50),#StoreID int,#Batch int'
SET #Qry = '
INSERT INTO '+#DatabaseName+'.dbo.TransactionHold
(
[StoreID]
,[HoldComment]
,[BatchNumber]
,[ShippingNotes]
)
SELECT
#StoreID AS [StoreID]
,#Comment AS [HoldComment]
,#Batch AS [BatchNumber]
,'''' AS [ShippingNotes];
'
EXECUTE sp_executesql #Qry, #ParamDefinition, #Comment, #StoreID, #Batch
SELECT SCOPE_IDENTITY()
END
When I execute this above stored procedure, it's return empty. But TransactionHold has identity column Id
Try retrieving the identity inside the same scope of the execute sql procedure and return the value as an OUT parameter. Do these changes:
SET #ParamDefinition = N'#comment nvarchar(50),#StoreID int,#Batch int, #identity int out'
SET #Qry = '
INSERT INTO '+#DatabaseName+'.dbo.TransactionHold
(
[StoreID]
,[HoldComment]
,[BatchNumber]
,[ShippingNotes]
)
SELECT
#StoreID AS [StoreID]
,#Comment AS [HoldComment]
,#Batch AS [BatchNumber]
,'''' AS [ShippingNotes];
SET #identity = ##IDENTITY
'
DECLARE #identity INT
EXECUTE sp_executesql #Qry, #ParamDefinition, #Comment, #StoreID, #Batch, #identity OUT
SELECT #identity
I declared a variable #Obj and assign a complete table name 'ODS..Account' to it.
DECLARE #Obj VARCHAR(255)
Then I used it in a query immediately after FROM Clause. I perceive it is just a string, unable to act as a table object. So how can I fix the code to get it works? Cheers
INSERT Control.dbo.Consistency_Check
(Table_Name
,Schema_Name
,Id
,Incremental_DateTime_Column
)
SELECT
#Tab
,'ODS'
,Id
,SystemModstamp
FROM
#Obj )
You can use a local variable as a scalar value, not as a function. To do this, you need dynamic SQL:
declare #sql varchar(max);
select #sql = '
INSERT Control.dbo.Consistency_Check(Table_Name, Schema_Name, Id, Incremental_DateTime_Column)
SELECT ''#Tab'', 'ODS', Id, SystemModstamp
FROM #Tab
';
select #sql = replace(#sql, '#tab', #tab);
exec sp_executesql #sql;
Slightly different way of doing it with dynamic SQL:
DECLARE #Obj VARCHAR(255) = 'dbo.table'
DECLARE #SQL NVARCHAR(MAX) = ''
SET #SQL = #SQL +
'INSERT Control.dbo.Consistency_Check
(Table_Name
,Schema_Name
,Id
,Incremental_DateTime_Column
)
SELECT
#Tab
,''ODS''
,Id
,SystemModstamp
FROM
' + #Obj + ''
EXEC (#SQL)
You cannot. You probably want to use dynamic query. i.e. workout the SQL query string into a variable and exec using sp_executesql.
You may use the same variable name in the dynamic SQL but I changed it to #p_Tab for the example.
DECLARE #Tab int = 3
DECLARE #SQLString nvarchar(500)
DECLARE #ParmDefinition nvarchar(500) = N'#p_Tab int';
Declare #TableName nvarchar(100) = 'ODS..Account'
/* Build the SQL string dynamicly.*/
SET #SQLString = N'INSERT Control.dbo.Consistency_Check
(Table_Name
,Schema_Name
,Id
,Incremental_DateTime_Column
)
SELECT
#p_Tab
,''ODS''
,Id
,SystemModstamp
FROM
'+ #TableName
EXECUTE sp_executesql #SQLString, #ParmDefinition,
#p_Tab = #Tab
Further reference: https://msdn.microsoft.com/en-us/library/ms188001.aspx
i want to do this:
DECLARE #str varchar(max)
DECLARE #cnt bigint
set #str= 'where column=value'
set #cnt= (select count(*) from user+#str)
but the where clause is not working. getting no error but it will just ignore the where condition.
I previously suggested wrapping your last line in EXEC(), but you can't do this and return results to a variable. To do that, use the following in place of your last line:
create table #temp (theCount int)
insert into #temp EXEC('select count(*) from Photos '+#str)
set #cnt= (select top 1 theCount from #temp)
drop table #temp
Check below code, in your case condition is dynamic so you need to dynamic sql.
DECLARE #sSQL nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #str nvarchar(500);
set #str= 'where column=value'
SELECT #sSQL = N'SELECT #retvalOUT = COUNT(*) FROM user '+ #str +' ' ;
SET #ParmDefinition = N'#retvalOUT int OUTPUT';
EXEC sp_executesql #sSQL, #ParmDefinition, #retvalOUT=#retval OUTPUT;
SELECT #retval;
use the execute sql syntax http://technet.microsoft.com/en-us/library/ms188001.aspx
Hope this will solve your problem