初学者动态SQL构建

时间:2017-12-15 18:04:44

标签: sql-server tsql dynamic-sql

我想开始使用动态sql进行探索。我知道这个用例并不是展示使用动态SQL的好处的最好例子,但我只想了解语法。

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

Sub splitByColB()
    Dim r As Range, i As Long, ar
    Set r = Worksheets("Sheet1").Range("B999999").End(xlUp)
    Do While r.row > 1
        ar = Split(r.value, "/")
        If UBound(ar) >= 0 Then r.value = ar(0)
        For i = UBound(ar) To 1 Step -1
            r.EntireRow.Copy
            r.Offset(1).EntireRow.Insert
            r.Offset(1).value = ar(i)
        Next
        Set r = r.Offset(-1)
    Loop
End Sub

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

        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;

任何帮助都会受到赞赏,如果你对动态sql有一些一般的建议,我很乐意听到它们。谢谢。

1 个答案:

答案 0 :(得分:0)

这不对。

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的麻烦,即使您提到您正在尝试理解语法