I want to use Dynamic SQL within a stored procedure to create a table.
Here is the call to the stored procedure:
EXEC [spCreateAColDiffTable] 'hq193.dbo.arch_con_col_s193_s202'
Here are the relevant parts of the stored procedure:
CREATE PROCEDURE sp_createAColDiffTable (@table_name nvarchar(128))
...
SET @sSQL = 'CREATE TABLE ' + @table_name + ' ( ' +
' [table_name] VARCHAR (128) NOT NULL, ' +
' [column_name] VARCHAR (128) NULL, ' +
' [what_changed] VARCHAR (128) NULL, ' +
' [sr_data_type] VARCHAR (128) NOT NULL, ' +
' [tr_data_type] VARCHAR (128) NOT NULL, ' +
' [sr_max_length] SMALLINT NOT NULL, ' +
' [tr_max_length] SMALLINT NOT NULL, ' +
' [sr_is_nullable] CHAR NULL, ' +
' [tr_is_nullable] CHAR NULL, ' +
' [sr_precision] SMALLINT NULL, ' +
' [tr_precision] SMALLINT NULL, ' +
' [sr_scale] SMALLINT NULL, ' +
' [tr_scale] SMALLINT NULL ) ' +
' ON [PRIMARY] WITH (DATA_COMPRESSION = NONE)'
PRINT @sSQL
Exec @sSQL
GO
When I run the stored procedure I receive the error:
SQL Server Database Error: The name 'CREATE TABLE hq193.dbo.arch_con_col_s193_s202 ( [table_name] VARCHAR (128) NOT NULL, [column_name] VARCHAR (128) NULL, [what_changed] VARCHAR (128) NULL, [sr_data_type] VARCHAR (128) NOT NULL, [tr_data_type] VARCHAR (128) NOT NULL, [sr_max_length] SMALLINT NOT NULL, [tr_max_length] SMALLINT NOT NULL, [sr_is_nullable] CHAR NULL, [tr_is_nullable] CHAR NULL, [sr_precision] SMALLINT NULL, [tr_precision] SMALLINT NULL, [sr_scale] SMALLINT NULL, [tr_scale] SMALLINT NULL ) ON [PRIMARY] WITH (DATA_COMPRESSION = NONE)'
is not a valid identifier.
Notice in the stored procedure I printed out the SQL before I executed it. If I cut and paste the SQL that gets printed into a query editor window it works fine.
What am I missing?
Try it like this:
EXEC(@sSQL)
This is a very common error. Without the parenthesis, EXEC @sSQL
means "execute a stored procedure whose name is in the @sSQL variable", rather than what you want which is probably "Execute the command string in the variable @sSQL."
I see this is an old post, but I've had a similar issue where I need to read a text file where the columns may of changed by having more and less depending on how the file was pulled. So I wrote a program to read the text file and put it into a dynamically created temp table where I can work with the output.
Perhaps this can help someone else..
DECLARE @NUM_COL AS INT
DECLARE @I AS INT
DECLARE @CREATE_TBL AS NVARCHAR(MAX)
DECLARE @DATA AS NVARCHAR (MAX)
DECLARE @XML_ROW AS XML
DECLARE @MAX_CHAR AS INT
--Sets the column max characters for temp table ##FILE_TABLE
SET @MAX_CHAR = 1000
--File import of data as single rows, no columns
IF OBJECT_ID('tempdb..#FILE_ROWS') IS NOT NULL
DROP TABLE #FILE_ROWS
CREATE TABLE #FILE_ROWS
( [Row_data] NVARCHAR(MAX) NULL )
--Global temp table used because the table is being built dynamically.
IF OBJECT_ID('tempdb..##FILE_TABLE') IS NOT NULL
DROP TABLE ##FILE_TABLE
--This is only so the debugger thinks the table is created when referenced in later SQL code.
IF 1 <> 1 CREATE TABLE ##FILE_TABLE (X INT)
BULK INSERT #FILE_ROWS
FROM 'C:\Users\Wayne\Desktop\777434633016764.txt'
WITH
(
FIELDTERMINATOR = '\t' --Tab Delimited
,ROWTERMINATOR = '\n'
)
--Figures out how many columns were in the file.
SET @NUM_COL = (SELECT MAX(LEN(Row_data) - LEN(REPLACE(Row_data, CHAR(9), ''))) + 1 AS [NO_COL] FROM #FILE_ROWS)
SET @CREATE_TBL = 'CREATE TABLE ##FILE_TABLE ( ID INT IDENTITY(1,1),'
SET @I = 1
Declare COUNTER Cursor for
SELECT
CAST('<A>' + REPLACE(Row_data, CHAR(9), '</A><A>') + '</A>' AS XML)
FROM #FILE_ROWS
open COUNTER
fetch next from COUNTER into @XML_ROW
while @@fetch_Status != -1
begin
IF @I = 1
BEGIN
SELECT @CREATE_TBL = @CREATE_TBL
+ '[' + REPLACE(dbo.Trim(DATA.value('.','char(30)')), N'''', '`')
+ ']' + ' NVARCHAR(' + CAST(@MAX_CHAR AS NVARCHAR(5)) + ') NULL,'
FROM @XML_ROW.nodes('/A') AS x(DATA)
SET @CREATE_TBL = LEFT(@CREATE_TBL, LEN(@CREATE_TBL) - 1) + ')'
EXEC(@CREATE_TBL)
SET @I = 2
END
--ELSE --If you do not want the column names in the first row, remove the ELSE
BEGIN
SET @DATA = 'INSERT INTO ##FILE_TABLE SELECT '
SELECT @DATA = @DATA
+ '''' + REPLACE(dbo.Trim(DATA.value('.','char(30)')), N'''', '`')
+ '''' + ','
FROM @XML_ROW.nodes('/A') AS x(DATA)
SET @DATA = LEFT(@DATA, LEN(@DATA) -1)
EXEC(@DATA)
END
FETCH NEXT FROM COUNTER INTO @XML_ROW
END
CLOSE COUNTER
DEALLOCATE COUNTER
SELECT * from ##FILE_TABLE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With