初学者动态 SQL 建筑

Beginner Dynamic SQL Building

我想开始探索使用动态 sql。我知道这个用例并不是展示使用动态 SQL 好处的最佳示例,但我只是想感受一下语法。

在下面的查询中,我想做的就是使用 newid 创建一个 table,这样我就可以得到一个不同的 table 名称,然后只需 select 一些数据到那个table,所以我可以在上面 运行 一些 select 语句。这是我到目前为止的想法:

        SET NOCOUNT ON;

        DECLARE @TableName NVARCHAR(40); 
        DECLARE @sql NVARCHAR(MAX);
        DECLARE @guardvar NVARCHAR(1);

        SET @TableName = 'tmp_' + CONVERT(CHAR(36) , NEWID());
        SET @guardvar = 'y';



        SET @sql = 'SELECT  X.CLIENT_GUARANTOR_ID
,X.NAME
,X.RELATIONSHIP
,X.PHONE_AREA_CODE
,X.PHONE_NUMBER
,X.RECEIVE_STATEMENTS
,X.CONTACT_APPOINTMENTS
,X.sourceclient_id
into workdb.dbo.' + @TableName
            + ' 
FROM    ( SELECT    g.CLIENT_GUARANTOR_ID
,g.PERSON_ID AS sourceclient_id
,g.NAME
,g.PHONE_AREA_CODE
,g.PHONE_NUMBER
,g.RECEIVE_STATEMENTS
,g.CONTACT_APPOINTMENTS
,g.RELATIONSHIP
,ROW_NUMBER() OVER ( PARTITION BY s.SourceClient_ID ORDER BY g.CLIENT_GUARANTOR_ID DESC ) AS rnum
FROM      MDB131.CenternetDB.dbo.CEN_CEN_CLIENT_GUARANTOR
AS g
INNER JOIN ndw3nfdb.dbo.QV_PROD_Service AS s
WITH ( NOLOCK ) ON CAST(s.SourceClient_ID AS VARCHAR(50)) = CAST(g.PERSON_ID AS VARCHAR(50))
INNER JOIN ndw3nfdb.dbo.ClientProgram cp
WITH ( NOLOCK ) ON cp.Client_ID = s.Client_ID
WHERE     LEGAL_GUARDIAN = ' + @guardvar + ' 
AND g.NAME IS NOT NULL
AND cp.PROG_ID = 683
) X
WHERE   X.rnum = 1';

        EXEC sp_executesql @sql , @guardvar;

我知道我在这里遗漏了一些非常明显的东西,但我似乎无法弄清楚它是什么。当我按原样执行时,我收到以下错误消息:

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'y'.
Msg 102, Level 15, State 1, Line 9
Incorrect syntax near '-'.
Msg 102, Level 15, State 1, Line 28
Incorrect syntax near 'X'.

如能提供任何帮助,我们将不胜感激,如果您对动态 sql 有一些一般性建议,我很乐意听取。谢谢。

这是不对的。

WHERE LEGAL_GUARDIAN = ' + @guardvar + '

您正在使用带有 EXEC sp_executesql @sql , @guardvar; 的参数化查询,因此只需照常编写 sql 语句即可。

WHERE LEGAL_GUARDIAN = @guardvar

或者,您可以在值周围连接单引号,例如WHERE LEGAL_GUARDIAN = ' + ''' + @guardvar + ''' + '。我不推荐这种方法。

为了澄清当您打印 sql 声明时您希望看到以下任一内容

有效

  • WHERE LEGAL_GUARDIAN = @guardvar --Works with parameterized Sql proc sp_executesql
  • WHERE LEGAL_GUARDIAN = 'y' --Standard dynamic sql. Potential SQL injection

如果你打印你的 sql 并且它看起来像这样它不会工作。

不起作用

  • WHERE LEGAL_GUARDIAN = '@guardvar' --Filters for a string @guardvar which returns 0 records
  • WHERE LEGAL_GUARDIAN = y --Won't compile

两个音符

  1. 当调试动态 sql 时你应该有 Print @sql 语句允许你静态编译语句来发现这样的错误。

  2. 您似乎正在创建临时表。您可能应该使用 #table##table 临时表并且不要为非临时表、临时表和动态 sql 的头痛而烦恼,即使您提到您正在尝试理解语法