my code accepts table name parameters and my dynamic code is supposed to query a table. I consistently get the error: @sourcetbl variable must be declared. After a lot of troubleshooting, I realized why I get error. SQL keeps assuming that I must pass on a table parameter. But I don’t need/want table param. I have string for a table and I want it to query the table.
My code:
DECLARE @DBname AS VARCHAR(30), @TblSchema AS VARCHAR(4) , @TblName AS VARCHAR(30), @LoadDate as INT SET @DBname='Test' SET @TblName='myTable' SET @TblSchema='dbo' DECLARE @Tblnamestring AS VARCHAR(100) SET @Tblnamestring =' ' + @DBname + '.' + @TblSchema+ '.' + @TblName SET @SQLCodes= N' ; WITH CTE AS ( SELECT * FROM QUOTENAME(@dynamicTblName) S WHERE S.Loaddate > ''@Loaddate'' ) SELECT * FROM CTE' EXEC SP_EXECUTESQL @STMT=@SQLCodes, @PARAMS=N'@dynamicTblName AS VARCHAR(100)', @dynamicTblName=@Tblnamestring;
I constantly get the error that my variable (@dynamicTblName) is not defined. So here is what I tried:
- I tried adding QUOTENAME beside it.
- I tried using EXEC as follow
SET @SQLCodes= N' ; WITH CTE AS ( SELECT * FROM QUOTENAME(@Tblnamestring) S WHERE S.Loaddate > '@Loaddate' ) SELECT * FROM CTE' EXEC (@SQLCodes)
- Then I just got rid of
SP_EXECUTESQL
‘s other params. And I just ran it without those. - I ran
SP_EXECUTESQL
with@Tblnamestring
being defined outside.
None of these work. SQL Expects a table variable. But I am just giving a string that I need it to query.
Advertisement
Answer
This:
DECLARE @Tblnamestring AS VARCHAR(100) SET @Tblnamestring =' ' + @DBname + '.' + @TblSchema+ '.' + @TblName SET @SQLCodes = N' ; WITH CTE AS ( SELECT * FROM QUOTENAME(@dynamicTblName) S WHERE S.Loaddate > @Loaddate ) SELECT * FROM CTE'
Should be this:
DECLARE @Tblnamestring AS VARCHAR(100); SET @Tblnamestring = QUOTENAME(@DBname) + '.' + QUOTENAME(@TblSchema) + '.' + QUOTENAME(@TblName); SET @SQLCodes = N' WITH CTE AS ( SELECT * FROM ' + @dynamicTblName + ' S WHERE S.Loaddate > @Loaddate ) SELECT * FROM CTE;';
The entire point of using dynamic SQL is to insert the table name into the SQL, giving a string which can be run as static SQL 🙂
And this:
EXEC SP_EXECUTESQL @STMT = @SQLCodes, @PARAMS = N'@dynamicTblName AS VARCHAR(100)', @dynamicTblName = @Tblnamestring;
Should be:
EXEC SP_EXECUTESQL @STMT = @SQLCodes, @PARAMS = N'@Loaddate AS INT', @Loaddate = @Loaddate;
Note the semi-colon is a statement terminator. Many people put it before WITH
because they aren’t terminating their statements correctly since SQL Server is sometimes forgiving.