SQL - Dynamic table name output with sp_executesql - sql

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

Related

How to use Table -Valued Parameter with Dynamic qry

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

Getting a temporary table returned from dynamic SQL in SQL Server 2005, and parsing

So I was requested to make a few things.... (it is Monday morning and for some reason this whole thing is turning out to be really hard for me to explain so I am just going to try and post a lot of my code; sorry) Oh - the table idea has to stay. Anything else can be changed but the idea of this table and the parsed field was not my idea but it is my responsibility to execute and make work.
Edit: Sorry the post is long. I do suggest a few possible solutions throughout but my problem is ultimately how everything is returned in a dynamically defined table/table variable from something (sp,view,function,anything...). Please take a minute to read the whole post...
First, I needed a table:
CREATE TABLE TICKET_INFORMATION (
TICKET_INFO_ID INT IDENTITY(1,1) NOT NULL,
TICKET_TYPE INT,
TARGET_ID INT,
TARGET_NAME VARCHAR(100),
INFORMATION VARCHAR(MAX),
TIME_STAMP DATETIME DEFAULT GETUTCDATE()
)
-- insert this row for testing...
INSERT INTO TICKET_INFORMATION (TICKET_TYPE, TARGET_ID, TARGET_NAME, INFORMATION) VALUES (1,1,'RT_ID','IF_ID,int=1&IF_ID,int=2&OTHER,varchar(10)=val,ue3&OTHER,varchar(10)=val,ue4')
The Information column holds data that needs to be parsed into a table. This is where I am having problems. In the resulting table, Target_Name needs to become a column that holds Target_ID as a value for each row in the resulting table.
The string that needs to be parsed is in this format:
#var_name1,#var_datatype1=#var_value1&#var_name2,#var_datatype2=#var_value2&#var_name3,#var_datatype3=#var_value3
And what I ultimately need as a result (in a table or table variable):
RT_ID IF_ID OTHER
1 1 val,ue3
1 2 val,ue3
1 1 val,ue4
1 2 val,ue4
And I need to be able to join on the result. Initially, I was just going to make this a function that returns a table variable but for some reason I can't figure out how to get it into an actual table variable. Whatever parses the string needs to be able to be used directly in queries so I don't think a stored procedure is really the right thing to be using.
This is the code that parses the Information string... it returns in a temporary table. In the end, this needs to be passed either just the information string or an ID number or something... doesn't matter what. Or somehow it can be in a view with the ticket_information table.
-- create/empty temp table for var_name, var_type and var_value fields
if OBJECT_ID('tempdb..#temp') is not null drop table #temp
create table #temp (row int identity(1,1), var_name varchar(max), var_type varchar(30), var_value varchar(max))
-- just setting stuff up
declare #target_name varchar(max), #target_id varchar(max), #info varchar(max)
set #target_name = (select target_name from ticket_information where ticket_info_id = 1)
set #target_id = (select target_id from ticket_information where ticket_info_id = 1)
set #info = (select information from ticket_information where ticket_info_id = 1)
--print #info
-- some of these variables are re-used later
declare #col_type varchar(20), #query varchar(max), #select as varchar(max)
set #query = 'select ' + #target_id + ' as ' + #target_name + ' into #target; '
set #select = 'select * into ##global_temp from #target'
declare #var_name varchar(100), #var_type varchar(100), #var_value varchar(100)
declare #comma_pos int, #equal_pos int, #amp_pos int
set #comma_pos = 1
set #equal_pos = 1
set #amp_pos = 0
-- while loop to parse the string into a table
while #amp_pos < len(#info) begin
-- get new comma position
set #comma_pos = charindex(',',#info,#amp_pos+1)
-- get new equal position
set #equal_pos = charindex('=',#info,#amp_pos+1)
-- set stuff that is going into the table
set #var_name = substring(#info,#amp_pos+1,#comma_pos-#amp_pos-1)
set #var_type = substring(#info,#comma_pos+1,#equal_pos-#comma_pos-1)
-- get new ampersand position
set #amp_pos = charindex('&',#info,#amp_pos+1)
if #amp_pos=0 or #amp_pos<#equal_pos set #amp_pos = len(#info)+1
-- set last variable for insert into table
set #var_value = substring(#info,#equal_pos+1,#amp_pos-#equal_pos-1)
-- put stuff into the temp table
insert into #temp (var_name, var_type, var_value) values (#var_name, #var_type, #var_value)
-- is this a new field?
if ((select count(*) from #temp where var_name = (#var_name)) = 1) begin
set #query = #query + ' create table #' + #var_name + '_temp (' + #var_name + ' ' + #var_type + '); '
set #select = #select + ', #' + #var_name + '_temp '
end
set #query = #query + ' insert into #' + #var_name + '_temp values (''' + #var_value + '''); '
end
if OBJECT_ID('tempdb..##global_temp') is not null drop table ##global_temp
exec (#query + #select)
--select #query
--select #select
select * from ##global_temp
Okay. So, the result I want and need is now in ##global_temp. How do I put all of that into something that can be returned from a function (or something)? Or can I get something more useful returned from the exec statement? In the end, the results of the parsed string need to be in a table that can be joined on and used... Ideally this would have been a view but I guess it can't with all the processing that needs to be done on that information string.
Ideas?
Thanks!
Edit: Still looking for answers to this. I would love to have a function that returns a table variable but I don't know how to get the results into a table variable. The result is currently in a global temporary table. Would it work if I defined my table variable in the dynamic portion of the code and then it would just magically be there to return? Or can I somehow select into a table variable from my global temp table, without first defining the columns of the table variable? Or can I create the table variable when I execute the dynamic part? The whole problem is because the columns of the end result are dynamic....... so..... I'm not sure how I could clarify the issues I'm having more. If a function that returns a table is a good route to go - could someone please provide me with code or a link as an example for returning a table variable with a dynamic column definition from a function? Plz, thnx.
You could use a table valued function. This would allow you to return the results as a table to be joined to just like you asked for.
CREATE FUNCTION dbo.GET_TICKET_INFORMATION (... some parameters... )
RETURNS #TICKET_INFORMATION TABLE
(
TICKET_INFO_ID INT IDENTITY(1,1) NOT NULL,
TICKET_TYPE INT,
TARGET_ID INT,
TARGET_NAME VARCHAR(100),
INFORMATION VARCHAR(MAX),
TIME_STAMP DATETIME DEFAULT GETUTCDATE()
)
AS
...
I used stored procedure for returning a table with a dynamic column definition
i generated dynamic name for global table:
declare #sp varchar(3)
set #sp = cast( ##spid as varchar(3) )
if object_id ( N'tempdb.dbo.#Periods' ) is not null
drop table #Periods
if object_id ( N'tempdb.dbo.##Result' + #sp ) is not null
execute ( 'drop table ##Result' + #sp )
i have sp for return periods table:
create table #Periods
(
[PERIOD_NUM] int
,[START_DATE] datetime
,[END_DATE] datetime
)
insert into #Periods
exec GET_PERIODS_TABLE_SP #pFromDate, #pToDate, #pPeriodType, 0
some fields in result table are dynamic:
select #PeriodCount = ...
declare #PeriodsScript varchar(max)
set #PeriodsScript = ''
set #i = 1
while #i <= #PeriodCount
begin
set #PeriodsScript = #PeriodsScript + ',PERIOD' + cast (#i as varchar(3))
set #i = #i + 1
end
generated and inserted data into ##Result:
declare #script varchar(max)
set #script = 'create table ##Result' + #sp +
'(ROW_NUM int'+
',BRANCH_ID int' +
',PARAM_NAME varchar(25)' +
#PeriodsScript + ')'
execute ( #script )
execute(
'insert into ##Result' + #sp + '( ROW_NUM, BRANCH_ID, NOM_SIZE_ID, PARAM_NAME )' +
'select ( row_number() over( order by BRANCH_ID, NOM_SIZE_ID ) - 1 ) * 3 + 1' +
' ,BRANCH_ID' +
' ,NOM_SIZE_ID' +
' ,''Min.price''' +
' from ( ' +
' select distinct BRANCH_ID' +
' ,NOM_SIZE_ID' +
' from ##ResultNomSizePrices' + #sp +
' ) as t'
)
and finaly, select from result table:
set #script =
'select distinct gb.TINY_NAME'+
' ,r.GROUP_NAME_1 as group1'+
' ,r.GROUP_NAME_2 as group2'+
' ,r.GROUP_NAME_3 as group3'+
' ,r.PARAM_NAME'+
' ,r.ROW_NUM'+
#PeriodsScript +
' from ##Result' + #sp + ' as r'+
' inner join dbo.GD_BRANCHES as gb'+
' on r.BRANCH_ID = gb.BRANCH_ID'+
' order by gb.TINY_NAME'+
' ,r.GROUP_NAME_1'+
' ,r.GROUP_NAME_2'+
' ,r.GROUP_NAME_3'+
' ,r.ROW_NUM'
execute ( #script )
p.s. sry for my english

Why isn't the table being created from within the stored procedure?

I am creating stored procedure in which I need to build a temporary table dynamically. I tried the following code but its not creating table. When I execute the generated Query in Query window it works fine there.
--declare query variable
DECLARE #Query nvarchar(MAX)
SET #Query = 'CREATE TABLE #final (DATE int,'
--DECLARE #COLUMNNAME VARIABLE
DECLARE #ColName nvarchar(10)
OPEN #taCur
FETCH NEXT FROM #taCur INTO #ColName
WHILE (##FETCH_STATUS = 0)
BEGIN
SET #Query = #Query + 'T_' + #ColName +' int,'
FETCH NEXT FROM #taCur INTO #ColName
END
SET #Query = #Query + 'TOTAL int,CUMM_TOTAL int)'
print #Query
EXEC sp_executesql #Query
--SET #Query = 'INSERT INTO #final (DATE) VALUES (1)'
SET #Query = 'SELECT * FROM #final'
print #Query
EXEC(#Query)
Final generated create table Query is as follow
CREATE TABLE #final (DATE int,T_211E int,T_211G int,T_211H int,T_211J int,T_211L int,T_221F int,TOTAL int,CUMM_TOTAL int)
Object #final used in CREATE and SELECT statements is not in the same scope.
Here is one way to structure the query.
Try to terminate SQL statements with semicolon. Even though it is not mandatory, it will help you differentiate the statements for readability. Note that I have included semicolon at the end of CREATE, INSERT and SELECT statements.
You can notice that CREATE, INSERT and SELECT are executed in the same transaction. Thereby, you don't lose the scope of the temporary table.
Script:
CREATE TABLE dbo.ColumnSchema
(
ColName NVARCHAR(10)
);
INSERT INTO dbo.ColumnSchema (ColName) VALUES
('211E'),
('211G'),
('211H'),
('211J'),
('211L'),
('211F');
DECLARE #Query NVARCHAR(MAX);
DECLARE #ColName NVARCHAR(10);
SET #Query = 'CREATE TABLE #final (DATE int,';
DECLARE taCursor CURSOR FOR
SELECT ColName
FROM dbo.ColumnSchema;
OPEN taCursor
FETCH NEXT FROM taCursor
INTO #ColName
WHILE (##FETCH_STATUS = 0)
BEGIN
SET #Query = #Query + 'T_' + #ColName + ' int, '
FETCH NEXT FROM taCursor
INTO #ColName
END
CLOSE taCursor;
DEALLOCATE taCursor;
SET #Query = #Query + 'TOTAL int,CUMM_TOTAL int); '
SET #Query = #Query + 'INSERT INTO #final (DATE) VALUES (1); '
SET #Query = #Query + 'SELECT * FROM #final; '
EXEC (#Query);
Output:
DATE T_211E T_211G T_211H T_211J T_211L T_211F TOTAL CUMM_TOTAL
---- ------ ------ ------ ------ ------ ------ ----- ----------
1 NULL NULL NULL NULL NULL NULL NULL NULL
Your problem is that your temp table only exists within the scope that it is created... which is within the scope of your first sp_executesql. When you call your select statement, your temp table is no longer in scope.
To fix this, you would have to build up a single string that contains everything you need to do with your temp table: your create, insert, and select all within the a single sp_executesql call.
However, you should be aware that your current approach is likely vulnerable to SQL injection if you don't have complete control over all the values that are used to build up your commands.

How to specify a table dynamically in a Stored Procedure

Thanks for the feedback, but I was hoping for help with an UPDATE command, not SELECT.
Can anyone help with the syntax for an UPDATE command?
I am passing a table name into a Stored Procedure but the SQL does not seem to recognize it.
DECLARE #userTable AS VARCHAR(200);
SET #userTable = #currTable
UPDATE #userTable
SET [lang_String] = #lang_String, [date_Changed] = #submitDate1
WHERE (ID = #ID)
#currTable is passed into the Stored Procedure. All tables names are built by design in code.
You can't, you need to build the entire SQL string and then execute it, like this for example:
DECLARE #sql nvarchar(4000)
SELECT #sql = ' SELECT col1, col2, col3 ' +
' FROM dbo.' + quotename(#tblname) +
' WHERE keycol = #key'
EXEC sp_executesql #sql, N'#key varchar(10)', #key
Got this to work quite easily....
#myTable varchar(150)
/* Comments:
*/
AS
SET NOCOUNT ON;
DECLARE #sql varchar(max);
SET #sql = 'SELECT [ID], [StringID], [GUID] FROM ' + #myTable + ' ORDER BY [GUID]';
print (#sql)
EXECUTE(#sql);
SET #langTable = Null;
FYI, the values available for myTable are stored in another table and are not available to users for edit. Table names are built dynamically in code based on a unique combination of values.

How to use table variable in a dynamic sql statement?

In my stored procedure I declared two table variables on top of my procedure. Now I am trying to use that table variable within a dynamic sql statement but I get this error at the time of execution of that procedure. I am using Sql Server 2008.
This is how my query looks like,
set #col_name = 'Assoc_Item_'
+ Convert(nvarchar(2), #curr_row1);
set #sqlstat = 'update #RelPro set '
+ #col_name
+ ' = (Select relsku From #TSku Where tid = '
+ Convert(nvarchar(2), #curr_row1) + ') Where RowID = '
+ Convert(nvarchar(2), #curr_row);
Exec(#sqlstat);
And I get the following errors,
Must declare the table variable "#RelPro".
Must declare the table variable "#TSku".
I have tried to take the table outside of the string block of dynamic query but to no avail.
On SQL Server 2008+ it is possible to use Table Valued Parameters to pass in a table variable to a dynamic SQL statement as long as you don't need to update the values in the table itself.
So from the code you posted you could use this approach for #TSku but not for #RelPro
Example syntax below.
CREATE TYPE MyTable AS TABLE
(
Foo int,
Bar int
);
GO
DECLARE #T AS MyTable;
INSERT INTO #T VALUES (1,2), (2,3)
SELECT *,
sys.fn_PhysLocFormatter(%%physloc%%) AS [physloc]
FROM #T
EXEC sp_executesql
N'SELECT *,
sys.fn_PhysLocFormatter(%%physloc%%) AS [physloc]
FROM #T',
N'#T MyTable READONLY',
#T=#T
The physloc column is included just to demonstrate that the table variable referenced in the child scope is definitely the same one as the outer scope rather than a copy.
Your EXEC executes in a different context, therefore it is not aware of any variables that have been declared in your original context. You should be able to use a temp table instead of a table variable as shown in the simple demo below.
create table #t (id int)
declare #value nchar(1)
set #value = N'1'
declare #sql nvarchar(max)
set #sql = N'insert into #t (id) values (' + #value + N')'
exec (#sql)
select * from #t
drop table #t
You don't have to use dynamic SQL
update
R
set
Assoc_Item_1 = CASE WHEN #curr_row = 1 THEN foo.relsku ELSE Assoc_Item_1 END,
Assoc_Item_2 = CASE WHEN #curr_row = 2 THEN foo.relsku ELSE Assoc_Item_2 END,
Assoc_Item_3 = CASE WHEN #curr_row = 3 THEN foo.relsku ELSE Assoc_Item_3 END,
Assoc_Item_4 = CASE WHEN #curr_row = 4 THEN foo.relsku ELSE Assoc_Item_4 END,
Assoc_Item_5 = CASE WHEN #curr_row = 5 THEN foo.relsku ELSE Assoc_Item_5 END,
...
from
(Select relsku From #TSku Where tid = #curr_row1) foo
CROSS JOIN
#RelPro R
Where
R.RowID = #curr_row;
You can't do this because the table variables are out of scope.
You would have to declare the table variable inside the dynamic SQL statement or create temporary tables.
I would suggest you read this excellent article on dynamic SQL.
http://www.sommarskog.se/dynamic_sql.html
Well, I figured out the way and thought to share with the people out there who might run into the same problem.
Let me start with the problem I had been facing,
I had been trying to execute a Dynamic Sql Statement that used two temporary tables I declared at the top of my stored procedure, but because that dynamic sql statment created a new scope, I couldn't use the temporary tables.
Solution:
I simply changed them to Global Temporary Variables and they worked.
Find my stored procedure underneath.
CREATE PROCEDURE RAFCustom_Room_GetRelatedProducts
-- Add the parameters for the stored procedure here
#PRODUCT_SKU nvarchar(15) = Null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..##RelPro', 'U') IS NOT NULL
BEGIN
DROP TABLE ##RelPro
END
Create Table ##RelPro
(
RowID int identity(1,1),
ID int,
Item_Name nvarchar(max),
SKU nvarchar(max),
Vendor nvarchar(max),
Product_Img_180 nvarchar(max),
rpGroup int,
Assoc_Item_1 nvarchar(max),
Assoc_Item_2 nvarchar(max),
Assoc_Item_3 nvarchar(max),
Assoc_Item_4 nvarchar(max),
Assoc_Item_5 nvarchar(max),
Assoc_Item_6 nvarchar(max),
Assoc_Item_7 nvarchar(max),
Assoc_Item_8 nvarchar(max),
Assoc_Item_9 nvarchar(max),
Assoc_Item_10 nvarchar(max)
);
Begin
Insert ##RelPro(ID, Item_Name, SKU, Vendor, Product_Img_180, rpGroup)
Select distinct zp.ProductID, zp.Name, zp.SKU,
(Select m.Name From ZNodeManufacturer m(nolock) Where m.ManufacturerID = zp.ManufacturerID),
'http://s0001.server.com/is/sw11/DG/' +
(Select m.Custom1 From ZNodeManufacturer m(nolock) Where m.ManufacturerID = zp.ManufacturerID) +
'_' + zp.SKU + '_3?$SC_3243$', ep.RoomID
From Product zp(nolock) Inner Join RF_ExtendedProduct ep(nolock) On ep.ProductID = zp.ProductID
Where zp.ActiveInd = 1 And SUBSTRING(zp.SKU, 1, 2) <> 'GC' AND zp.Name <> 'PLATINUM' AND zp.SKU = (Case When #PRODUCT_SKU Is Not Null Then #PRODUCT_SKU Else zp.SKU End)
End
declare #curr_row int = 0,
#tot_rows int= 0,
#sku nvarchar(15) = null;
IF OBJECT_ID('tempdb..##TSku', 'U') IS NOT NULL
BEGIN
DROP TABLE ##TSku
END
Create Table ##TSku (tid int identity(1,1), relsku nvarchar(15));
Select #curr_row = (Select MIN(RowId) From ##RelPro);
Select #tot_rows = (Select MAX(RowId) From ##RelPro);
while #curr_row <= #tot_rows
Begin
select #sku = SKU from ##RelPro where RowID = #curr_row;
truncate table ##TSku;
Insert ##TSku(relsku)
Select distinct top(10) tzp.SKU From Product tzp(nolock) INNER JOIN
[INTRANET].raf_FocusAssociatedItem assoc(nolock) ON assoc.associatedItemID = tzp.SKU
Where (assoc.isActive=1) And (tzp.ActiveInd = 1) AND (assoc.productID = #sku)
declare #curr_row1 int = (Select Min(tid) From ##TSku),
#tot_rows1 int = (Select Max(tid) From ##TSku);
If(#tot_rows1 <> 0)
Begin
While #curr_row1 <= #tot_rows1
Begin
declare #col_name nvarchar(15) = null,
#sqlstat nvarchar(500) = null;
set #col_name = 'Assoc_Item_' + Convert(nvarchar(2), #curr_row1);
set #sqlstat = 'update ##RelPro set ' + #col_name + ' = (Select relsku From ##TSku Where tid = ' + Convert(nvarchar(2), #curr_row1) + ') Where RowID = ' + Convert(nvarchar(2), #curr_row);
Exec(#sqlstat);
set #curr_row1 = #curr_row1 + 1;
End
End
set #curr_row = #curr_row + 1;
End
Select * From ##RelPro;
END
GO
I don't think that is possible (though refer to the update below); as far as I know a table variable only exists within the scope that declared it. You can, however, use a temp table (use the create table syntax and prefix your table name with the # symbol), and that will be accessible within both the scope that creates it and the scope of your dynamic statement.
UPDATE: Refer to Martin Smith's answer for how to use a table-valued parameter to pass a table variable in to a dynamic SQL statement. Also note the limitation mentioned: table-valued parameters are read-only.
Here is an example of using a dynamic T-SQL query and then extracting the results should you have more than one column of returned values (notice the dynamic table name):
DECLARE
#strSQLMain nvarchar(1000),
#recAPD_number_key char(10),
#Census_sub_code varchar(1),
#recAPD_field_name char(100),
#recAPD_table_name char(100),
#NUMBER_KEY varchar(10),
if object_id('[Permits].[dbo].[myTempAPD_Txt]') is not null
DROP TABLE [Permits].[dbo].[myTempAPD_Txt]
CREATE TABLE [Permits].[dbo].[myTempAPD_Txt]
(
[MyCol1] char(10) NULL,
[MyCol2] char(1) NULL,
)
-- an example of what #strSQLMain is : #strSQLMain = SELECT #recAPD_number_key = [NUMBER_KEY], #Census_sub_code=TEXT_029 FROM APD_TXT0 WHERE Number_Key = '01-7212'
SET #strSQLMain = ('INSERT INTO myTempAPD_Txt SELECT [NUMBER_KEY], '+ rtrim(#recAPD_field_name) +' FROM '+ rtrim(#recAPD_table_name) + ' WHERE Number_Key = '''+ rtrim(#Number_Key) +'''')
EXEC (#strSQLMain)
SELECT #recAPD_number_key = MyCol1, #Census_sub_code = MyCol2 from [Permits].[dbo].[myTempAPD_Txt]
DROP TABLE [Permits].[dbo].[myTempAPD_Txt]
Using Temp table solves the problem but I ran into issues using Exec so I went with the following solution of using sp_executesql:
Create TABLE #tempJoin ( Old_ID int, New_ID int);
declare #table_name varchar(128);
declare #strSQL nvarchar(3072);
set #table_name = 'Object';
--build sql sting to execute
set #strSQL='INSERT INTO '+#table_name+' SELECT '+#columns+' FROM #tempJoin CJ
Inner Join '+#table_name+' sourceTbl On CJ.Old_ID = sourceTbl.Object_ID'
**exec sp_executesql #strSQL;**