【问题标题】:SQL Server : create table using variablesSQL Server:使用变量创建表
【发布时间】:2015-07-26 13:41:48
【问题描述】:

尝试执行以下操作时,出现错误

消息 102,第 15 级,状态 1,第 9 行
'GO' 附近的语法不正确。

消息 102,第 15 级,状态 1,第 11 行
'GO' 附近的语法不正确。

消息 102,第 15 级,状态 1,第 13 行
'GO' 附近的语法不正确。

谁能告诉我哪里出错了?我不明白语法是怎么错的

DECLARE @table nvarchar(100);
DECLARE @sql nvarchar(max);

SET @table = 'FooTable';

SET @sql = N'CREATE TABLE [dbo].[' + @table + '](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [AddedBy] [int] NOT NULL,
    [AddedDate] [datetime2](7) NOT NULL,
CONSTRAINT [PK_' + @table + '] PRIMARY KEY CLUSTERED 
( [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[' + @table + '] ADD  CONSTRAINT [DF_' + @table + '_AddedBy]  DEFAULT ((-1)) FOR [AddedBy]
GO
ALTER TABLE [dbo].[' + @table + '] ADD  CONSTRAINT [DF_' + @table + '_AddedDate]  DEFAULT (getutcdate()) FOR [AddedDate]
GO';

exec (@sql)

感谢您的帮助。

【问题讨论】:

  • 从你的脚本中删除所有GO并运行它
  • GO 只是被客户端工具理解为批处理分隔符而不是 SQL Server 本身。
  • 有什么方法我不能提示输入这个值吗? SET @table = 'FooTable';
  • 不幸的是 - 没有。 TSQL 无法做到这一点。使用 osql 可能会有黑客攻击,但我从来没有做过这样的事情。 SSMS 模板是您可以获得的最接近的模板。

标签: sql-server


【解决方案1】:

SQL 服务器不喜欢使用exec() 在动态上下文中发送批处理。所以忘记GO。只需将您的查询分割成GO 应该在的位置,然后将exec() 逐一分割:

DECLARE @table nvarchar(100);
DECLARE @sql nvarchar(max);

SET @table = 'FooTable';

SET @sql = N'CREATE TABLE [dbo].[' + @table + '](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [AddedBy] [int] NOT NULL,
    [AddedDate] [datetime2](7) NOT NULL,
CONSTRAINT [PK_' + @table + '] PRIMARY KEY CLUSTERED 
( [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]'
exec (@sql)

SET @sql = 'ALTER TABLE [dbo].[' + @table + '] ADD  CONSTRAINT [DF_' + @table + '_AddedBy]  DEFAULT ((-1)) FOR [AddedBy]'
exec (@sql)

SET @sql = 'ALTER TABLE [dbo].[' + @table + '] ADD  CONSTRAINT [DF_' + @table + '_AddedDate]  DEFAULT (getutcdate()) FOR [AddedDate]'
exec (@sql)

【讨论】:

    【解决方案2】:

    如果您在管理工具中执行将GO 命令理解为批处理分隔符的代码(就像isqlosql 工具一样),语法会很好。当您使用exec() 执行代码时,无法理解GO 命令,这就是您收到错误消息的原因。

    解决方案是要么删除GO 语句(或将它们替换为结束语句的;),它会正常执行,或者内联约束并完全跳过alter table 语句(看起来更干净我的意见):

    SET @sql = 
    N'CREATE TABLE [dbo].[' + @table + '](
        [id] int IDENTITY(1,1) NOT NULL,
        [AddedBy] int NOT NULL CONSTRAINT [DF_' + @table + '_AddedBy]  DEFAULT ((-1)),
        [AddedDate] datetime2(7) NOT NULL CONSTRAINT [DF_' + @table + '_AddedDate]  DEFAULT (getutcdate()) ,
        CONSTRAINT [PK_' + @table + '] PRIMARY KEY CLUSTERED ( [id] ASC ) 
           WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON
           ) ON [PRIMARY]
    ) ON [PRIMARY]
    ';
    

    此外,实际上没有必要在类型(甚至列名)中使用带引号的标识符,因此您不妨删除括号 []

    【讨论】:

      猜你喜欢
      • 2012-03-29
      • 1970-01-01
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 2013-05-24
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多