I am using Table - Valued Parameter for to build dyNamic Query Using the Following code
AlTER PROCEDURE [dbo].[ABC]
#tblName Varchar(1000),
#Details ABC_TYPE Readonly
AS
BEGIN
Declare #PK as nvarchar(1000)
Declare #SyncFlag as nvarchar(1) ='S'
Declare #SelectCommand as nvarchar(1200)
Declare #tblName2 as nvarchar(1000) ='#Details_N'
Set #PK = 'PK'
Declare #Details_N as table (Pk int)
Insert into #Details_N(Pk)
select PK from #Details
set #SelectCommand = 'Update A ' + ' set A.Sync_Flag ='''+ #SyncFlag + ''' From '+ #tblName + ' A, ' + #tblName2 + ' B ' +
' where A.' + #PK +'='+ 'B.PK'
EXEC sp_executesql #SelectCommand;
This giving me error
Must declare the table variable "#Details_N"
Not finding where my I am doing wrong
Inside dynamic query, you cannot use table variables declared outside. Use temp table instead. Also you have complicated it little too much, here is a cleaner version
DECLARE #SyncFlag AS NVARCHAR(1) ='S'
DECLARE #SelectCommand AS NVARCHAR(1200)
CREATE TABLE #Details_N(Pk INT)
INSERT INTO #Details_N(Pk)
SELECT PK
FROM #Details
SET #SelectCommand = 'Update A ' + ' set A.Sync_Flag = #SyncFlag
From '+ Quotename(#tblName) + ' A
inner join #Details_N B '+ 'on A.PK =' + 'B.PK'
EXEC Sp_executesql
#SelectCommand,
N'#SyncFlag NVARCHAR(1)',
#SyncFlag
Start using INNER JOIN syntax, old style comma separated join is deprecated
The scope of Table Variable is for specific batch (same context) while Temporary table is for SPID. The EXEC command runs in different context. Use temporary tables instead:
Declare #tblName2 as nvarchar(1000) ='#Details_N'
CREATE TABLE #Details_N (Pk int)
Insert into #Details_N(Pk)
select PK from #Details
Related
I want to pass into the procedure the table name and the values without mentioning column names because I want to be able to use this on any table.
#row would be csv string like 'test','123'
My code causes an error:
CREATE PROCEDURE test
#table NVARCHAR(100),
#row NVARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sql NVARCHAR(MAX)
SET #sql = 'INSERT INTO ' + #table+ 'VALUES (' + #row + ')'
EXEC sp_executesql #sql
END
Please try this.
SQL
CREATE PROCEDURE test
#table NVARCHAR(100),
#row NVARCHAR(max)
AS
BEGIN
DECLARE #Sql NVARCHAR(MAX)
SET #sql = 'INSERT INTO [dbo].[' + #table+ '] VALUES (' + #row + ')'
EXEC sp_executesql #sql
END
Note: if you select table name dynamic and you are pass single values it means the table has single columns
If you pass any other table and table has multiple columns your insert statement not work.
I'm using an Output clause in my Insert statement which requires use of a Table Variable. I also want the Table name to be dynamic so I'm using dynamic SQL but it won't allow use of a Table Variable. I get the error Must declare the scalar variable "#InsertedId".
CREATE PROCEDURE sp_InsertPerson #Name varchar(50), #Table varchar(20) AS
DECLARE #InsertedId TABLE (Id int)
DECLARE #SQL nvarchar(200) = 'INSERT INTO ' + #Table + ' (Name) OUTPUT INSERTED.Id INTO ' + #InsertedId + ' VALUES (' + #Name + ')'
IF (#Name is not null AND #Name != '')
EXEC(#SQL)
SELECT Id FROM #InsertedId
How can I both use the Output clause and a dynamic Table name
First of all, do not use sp_ prefix to your stored procedure, cause it reserved to System stored procedures by MS, and can lead to performance issue and other problems (as it can be a habit). Use SysName datatype for the table name, and use QUOTENAME() function when you concatenate the string.
You need to declare your table in the DynamicSQL as
CREATE PROCEDURE InsertPerson
#Name varchar(50),
#Table SysName
AS
DECLARE #SQL NVARCHAR(MAX);
SET #SQL = N'DECLARE #IDs TABLE (ID INT);'+
'INSERT INTO ' +
QUOTENAME(#Table) +
' (Name) OUTPUT INSERTED.ID INTO #IDs VALUES(#Name);'+
'SELECT * FROM #IDs';
EXECUTE sp_executesql #SQL,
N'#Name VARCHAR(50)',
#Name;
Demo
Try this;
CREATE PROCEDURE sp_InsertPerson #Name varchar(50), #Table varchar(20) AS
DECLARE #SQL nvarchar(200) = ''
SET #SQL = #SQL + 'DECLARE #InsertedId TABLE (Id int)';
SET #SQL = #SQL + 'INSERT INTO ' + #Table + ' (Name) OUTPUT INSERTED.Id INTO #InsertedId (Id) VALUES (''' + #Name + ''')'
SET #SQL = #SQL + 'SELECT Id FROM #InsertedId'
IF (#Name is not null AND #Name != '')
EXEC(#SQL)
I am attempting to create a table in T-SQL using sp_executesql. The name of the database containing the table is dynamic.
DECLARE #ID int = 1031460
DECLARE #TableName nvarchar(max) = '[MyDatabase' + CAST(#ID as nvarchar(10)) + '].[dbo].[MyTable]'
DECLARE #CreateTable nvarchar(max) = N''
SELECT #CreateTable =
N'
CREATE TABLE #TableName
(
ID int
)
'
EXECUTE sp_executeSQL #CreateTable, N'#TableName nvarchar(max)', #TableName = #TableName
This script results in this error:
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '#TableName'.
What is the best way to specify the name of the table to create dynamically based on parameters of sp_executeSQL?
You cannot pass Tablename as a parameter even we using sp_executesql procedure. You have to build you own dynamic sql query
SELECT #CreateTable =
N'
CREATE TABLE ' + #TableName + '
(
ID int
)
'
Exec sp_executesql #CreateTable
When you are passing the table name as a parameter to sp_executesql, it treats it as a literal string, to make it treat it as an object name try something like this......
DECLARE #ID int = 1031460
DECLARE #TableName nvarchar(max) = QUOTENAME('MyDatabase' + CAST(#ID as nvarchar(10)))
+ '.[dbo].[MyTable]'
DECLARE #CreateTable nvarchar(max);
SET #CreateTable = N' CREATE TABLE ' + #TableName
+ N' (
ID int
)'
Exec sp_executesql #CreateTable
EDIT
It is good practice to check if an object already exists before you try to create it.
You can check if the object already exists and drop it and then create the new one, you code should look something like.....
DECLARE #ID int = 1031460
DECLARE #TableName nvarchar(max) = QUOTENAME('MyDatabase' + CAST(#ID as nvarchar(10)))
+ '.[dbo].[MyTable]'
DECLARE #CreateTable nvarchar(max), #DropTable nvarchar(max);
-- Drop table if already exists
SET #DropTable = N' IF OBJECT_ID('''+ #TableName +''') IS NOT NULL '
+ N' DROP TABLE ' + #TableName
Exec sp_executesql #DropTable
SET #CreateTable = N' CREATE TABLE ' + #TableName
+ N' (
ID int
)'
Exec sp_executesql #CreateTable
I'm trying to load a dynamic table name in to a local table. Seems simple enough from the examples I've found, however I'm getting an error message.
-> Incorrect syntax near '#outtbl_15133897'
Hopefully, another set of eyes can see what I'm missing. Thanks
DECLARE #OutTbl TABLE ( Name varchar(100), type varchar(20), row int );
DECLARE #curName as NVARCHAR(MAX);
DECLARE #sqlCommand as NVARCHAR(MAX);
SET #curName = '#outtbl_' + LEFT(replace(replace(CONVERT (time, GETDATE()),':',''),'.',''),8);
SET #sqlCommand = 'CREATE TABLE #OutTbl ( Name varchar(100), type varchar(20), row int ); '
+ 'INSERT INTO #outtbl SELECT c.Name,c.Type, ROW_NUMBER() OVER(ORDER BY c.QueryID,c.GroupID,c.ColumnID) as row '
+ 'FROM MYDB.dbo.DynamicReport_Columns c '
+ 'INNER JOIN MYDB.dbo.DynamicReport_Tables t on t.TableID = c.TableID '
+ 'WHERE c.QueryID=1 and c.GroupID=1 and IsOutput <> ''N'';';
SET #curName = #curName + ' TABLE OUTPUT';
EXEC sys.sp_executesql #sqlCommand,#curName,#OutTbl output
I'm not 100% on this... I think I had a similar issue, but I solved it by making the temp table a global temp table... ##outtbl
I have the following query :
ALTER procedure [dbo].[jk_insertAllLocation]
#locationTbl as locationTable readonly,
#TableName varchar(100)
as
declare #tbl as locationTable,#sql varchar(max)
begin
set #sql = 'insert into ' + #TableName +'(location_id,name,address,latitude,longitude,distance,state,sub_cat,id_cat,icon_link,checkinsCount,IDSearch)
select * from ' + #locationTbl
exec sp_executesql #sql
end
I need to pass a table and a table name as parameter and I need to insert in the table name (#TableName) passed as parameter all the data in the table (#locationTbl) passed as parameter
but I know that I cannot concatenate the table (#locationTbl) in the query ...
so how can I fix this?
You can use temp tables (Temporary tables section on link):
ALTER procedure [dbo].[jk_insertAllLocation]
#locationTbl as locationTable readonly,
#TableName varchar(100)
as
begin
declare #tbl as locationTable,#sql varchar(max)
if object_id('#_tmp_location_table') is not null drop table #_tmp_location_table
select * into #_tmp_location_table from #locationTbl
set #sql = 'insert into ' + #TableName + '(location_id,name,address,latitude,longitude,distance,state,sub_cat,id_cat,icon_link,checkinsCount,IDSearch) select * from #_tmp_location_table'
exec sp_executesql #sql
end