【问题标题】:Incorrect Syntax Near GO, T-SQL EXEC()GO 附近的语法不正确,T-SQL EXEC()
【发布时间】:2016-12-14 20:28:47
【问题描述】:

我正在使用以下脚本:

DECLARE @dbName NVARCHAR(20) = 'ABC';
EXEC ( N' USE ' + @dbName + '
GO

-- Create Schema
CREATE SCHEMA meta
GO

-- Create Log Table
CREATE TABLE meta.LogAudit(
[EventDate] [datetime] NOT NULL DEFAULT (getdate()),
[EventType] [nvarchar](64) NULL
)
GO
'
);

但它会引发以下错误。

Msg 111, Level 15, State 1, Line 5
'CREATE SCHEMA' must be the first statement in a query batch.
Msg 102, Level 15, State 1, Line 22
Incorrect syntax near 'GO'.

这是为什么呢?

--

编辑:
这个答案似乎在回答我的问题: dynamic sql error: 'CREATE TRIGGER' must be the first statement in a query batch

因此,在我的情况下,我似乎无法对其进行动态编程。我的整个代码按以下方式工作:

USE DB
GO

CREATE SCHEMA SCH
GO

CREATE TABLE SCH.TABLE
GO

CREATE TRIGGER TRG
GO

所以SCHEMATRIGGER需要是第一个查询语句,所以不能这样写。

【问题讨论】:

  • 可以对其进行动态编程。只需拆分字符串并分别执行它们
  • @Dnac 尝试从下面我更新的答案中创建模式的动态 sql。我确信也可以为触发器创建类似的东西。只需检查架构创建是否适合您。
  • 另一种选择是使用sqlcmd.exe 或SMO 对象来生成as shown in this question
  • @PanagiotisKanavos 同意,我将不得不想出一些不同的方法。此外,我不会为每个数据库运行它,而只是为其中一些数据库运行,但我认为这也不应该是一个严重的问题。

标签: sql-server sql-server-2016 dynamicquery


【解决方案1】:

尝试删除[EventType] [nvarchar](64) NULL,之后的逗号,看看错误信息是否改变。

所以你有两个问题:

  1. 正如@Tanner 所指出的,您不能在动态 SQL 中使用 GO。
  2. meta.LogAudit 表列定义中仍有逗号。

尝试运行此代码:

DECLARE @dbName NVARCHAR(20) = 'ABC';
declare @sql nvarchar(max) = N'exec '+ @DBName + '..sp_executesql N''CREATE SCHEMA meta'''
execute(@sql)
declare @sql2 nvarchar(max) = '
-- Create Log Table
CREATE TABLE '+ @DBName + '.meta.LogAudit(
[EventDate] [datetime] NOT NULL DEFAULT (getdate()),
[EventType] [nvarchar](64) NULL
)'
exec sp_executesql @sql2,N''

它将允许您以编程方式在指定的数据库中创建模式,这与使用当前数据库相反。

【讨论】:

  • 多余的逗号当然是错字,我的真实表格有更多列,我删除了这些以使情况更清楚。不知道我不能在动态 SQL 中使用 GO。但是,当我删除它时,“CREATE SCHEMA”部分仍然会引发错误,因为它需要成为查询批处理中的第一个语句。
  • @DNac 查看更新后的答案。我已经在 SQL Server 2008 R2 中针对我的数据库在本地尝试过它并且它有效。
  • 谢谢。我以这种方式重写了我的代码,它工作正常。很高兴我学到了一些新东西。
  • @DNac 您是否设法将相同的动态 sql 模式应用于随后的触发器创建,您提到过您也需要它?
  • 我生成了 4 个动态 SQL(创建模式、表、触发器和更改触发器以启用它),然后一一运行。
【解决方案2】:

您可以在不受支持的未记录存储过程sp_MSForEachDB的帮助下使用以下脚本来解决您的要求

EXEC sp_MSForEachDB '
Use [?]; 
IF ''[?]'' = ''[ABC]'' 
begin
    -- Create Schema
    exec sp_executesql N''CREATE SCHEMA meta''
end
'
EXEC sp_MSForEachDB '
Use [?]; 
IF ''[?]'' = ''[ABC]'' 
begin 
    -- Create Log Table
    CREATE TABLE meta.LogAudit(
    [EventDate] [datetime] NOT NULL DEFAULT (getdate()),
    [EventType] [nvarchar](64) NULL,
    )
end'

【讨论】:

  • OP 的问题是不是如何在多个数据库上运行查询。这是GO 声明。
  • 我知道。上面的脚本避免了 GO 语句。使用 [?];”有助于消除 GO 相关错误
猜你喜欢
  • 2017-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多