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
命令理解为批处理分隔符的代码(就像isql
和osql
工具一样),语法会很好。当您使用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:使用变量创建表的主要内容,如果未能解决你的问题,请参考以下文章