SQL Server:使用变量创建表

Posted

技术标签:

【中文标题】SQL Server:使用变量创建表【英文标题】:SQL Server : create table using variables 【发布时间】: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 模板是您可以获得的最接近的模板。 【参考方案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]
';

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

【讨论】:

以上是关于SQL Server:使用变量创建表的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 表变量和临时表的区别

SQL Server讲课笔记05:创建并管理数据表

SQL Server 从表变量更新

将表定义克隆到 SQL Server 中的表变量

如何利用SQLserver创建表

SQL Server 中的临时表和表变量有啥区别?