动态 SQL 错误地寻找 table 变量

Dynamic SQL mistakenly looks for table variable

我的代码接受 table 名称参数,我的动态代码应该查询 table。我一直收到错误消息:必须声明@sourcetbl 变量。经过大量故障排除后,我意识到为什么会出错。 SQL 一直假设我必须传递 table 参数。但是我没有 need/want table 参数。我有 table 的字符串,我希望它查询 table.

我的代码:

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; 

我经常收到未定义变量 (@dynamicTblName) 的错误。所以这是我尝试过的:

  1. 我尝试在它旁边添加 QUOTENAME。
  2. 我尝试使用 EXEC 如下
    SET @SQLCodes= N'
    ; WITH CTE AS (
            SELECT *
                FROM QUOTENAME(@Tblnamestring) S
                WHERE 
    S.Loaddate > '@Loaddate'
            ) 
            SELECT * FROM CTE'
    
    EXEC (@SQLCodes) 
  1. 然后我去掉了SP_EXECUTESQL的其他参数。我只是 运行 没有那些。
  2. I 运行 SP_EXECUTESQL with @Tblnamestring 在外部定义。

None 这些作品。 SQL 需要一个 table 变量。但我只是给出了一个字符串,我需要它来查询。

这个:

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'

应该是这样的:

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;';

使用动态 SQL 的全部要点是将 table 名称插入 SQL,给出一个可以是 运行 作为静态 [=27] 的字符串=] :)

还有这个:

EXEC SP_EXECUTESQL 
    @STMT = @SQLCodes,
    @PARAMS = N'@dynamicTblName AS VARCHAR(100)',
    @dynamicTblName = @Tblnamestring; 

应该是:

EXEC SP_EXECUTESQL 
    @STMT = @SQLCodes,
    @PARAMS = N'@Loaddate AS INT',
    @Loaddate = @Loaddate;

注意分号是语句终止符。许多人把它放在 WITH 之前,因为他们没有正确终止他们的语句,因为 SQL 服务器有时是宽容的。