动态SQL是正确的,但SP_EXECUTESQL不会执行它?

时间:2014-03-14 18:17:43

标签: sql-server sql-server-2008 tsql

以下代码执行SQL n次。

PRINT 'X'
GO 10

我尝试使用以下查询将其设为动态代码 -

DECLARE @rows int 
DECLARE @sql nvarchar(max)
SET @rows = 10
SET @sql =
'INSERT INTO MultiInsert(Name)
VALUES(NULL)
GO ' + CAST(@rows as NVARCHAR(50))
PRINT @sql
EXEC SP_EXECUTESQL @sql

SQL是正确的,但SP_EXECUTESQL给出了一个错误,如下所示 -

INSERT INTO MultiInsert(Name)
VALUES(NULL)
GO 10
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'GO'.

如何解决此错误?

3 个答案:

答案 0 :(得分:6)

您不能在动态SQL表达式中使用GOGO是管理工作室或其他客户端工具的关键字。

以下是有关GO的MSDN文档,该文档解释了它仅仅是一个客户关键字:http://technet.microsoft.com/en-us/library/ms188037.aspx。特别注意这一行:“基于ODBC或OLE DB API的应用程序在尝试执行GO命令时会收到语法错误.SQL Server实用程序从不向服务器发送GO命令。”

答案 1 :(得分:3)

嗯,@ siride的答案显示为什么它失败了,这是 你可以修复它:

DECLARE @rows int 
DECLARE @sql nvarchar(max)
SET @rows = 10
SET @sql =
'DECLARE @I INT = 0
WHILE @I <= ' + CAST(@rows as NVARCHAR(50)) + '
BEGIN
    INSERT INTO MultiInsert(Name)
    VALUES(NULL)
    SET @I = @I + 1
END'

PRINT @sql

EXEC SP_EXECUTESQL @sql

答案 2 :(得分:2)

您可以使用此类查询在一次运行中生成10个NULL:

WITH mycte AS
(
   SELECT NULL as VAL
   UNION ALL
   SELECT NULL FROM mycte  
)
SELECT TOP 10 Val from mycte

所以你会做类似

的事情
DECLARE @rows int 
DECLARE @sql nvarchar(max)
SET @rows = 10
SET @sql =

'WITH mycte AS
    (
       SELECT NULL as VAL
       UNION ALL
       SELECT NULL FROM mycte  
    )
    INSERT INTO MultiInsert(Name)
    SELECT TOP ' + CAST(@rows as NVARCHAR(50)) + ' Val from mycte'

EXEC SP_EXECUTESQL @sql

在这种情况下,使用带有单个插入的recursive CTE而不是循环。