我想开始使用动态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有一些一般的建议,我很乐意听到它们。谢谢。
答案 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
两个笔记
调试动态sql时,你应该有Print @sql
语句,允许你静态编译语句,以发现这样的错误。
看起来您正在创建临时表。您应该使用#table
或##table
临时表,而不必担心非临时表,临时表和动态SQL的麻烦,即使您提到您正在尝试理解语法