为什么我不能在SQL Management Studio的begin/end块中使用"create schema"?

86

我生成了一个脚本来为这个数据库创建所有用户和模式,在将CREATE语句包装在IF EXISTS检查中时,我发现它不允许在BEGIN/END块中运行CREATE SCHEMA调用。它抱怨它是无效的语法。但是我可以单独运行该命令。下面是代码示例。我正在使用SQL Server 2008和Management Studio R2。为什么会出现无效语法?

--DROP SCHEMA [acme]

IF (NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'acme')) 
BEGIN
    CREATE SCHEMA [acme] AUTHORIZATION [dbo]
END

我已经明确了,可以使用EXECUTE将CREATE SCHEMA语句包装起来,以使该语句正常工作。请参阅EXECUTE('CREATE SCHEMA [acme] AUTHORIZATION [dbo]') http://msdn.microsoft.com/en-us/library/ms189462.aspx - Brennan
3
这是胡说八道... 我们肯定不会用无意义的EXEC语句堆积我们的代码吧? - Chris B. Behrens
如果 create schema 支持 if exists 谓词就好了... ;_; - Ian Kemp
5个回答

135

模式创建必须是批处理中唯一的语句。解决方法之一如下:

IF (NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'acme')) 
BEGIN
    EXEC ('CREATE SCHEMA [acme] AUTHORIZATION [dbo]')
END

50

这里有一个更简单的解决方案(更简单的检查):

IF (SCHEMA_ID('acme') IS NULL) 
BEGIN
    EXEC ('CREATE SCHEMA [acme] AUTHORIZATION [dbo]')
END

11

这段代码需要独立成一个批处理任务。你可以用EXEC('')将其包裹起来。

EXEC('CREATE SCHEMA [acme] AUTHORIZATION [dbo]')

我相信对于这个要求的原因与版本6.5中引入的旧版CREATE SCHEMA语法有关(至少在此处是这样说的)。


6
有时候(事实上一直如此),你无法使用动态SQL,因此使用EXEC并不是最佳选择。使用GO语句可以更好地完成这项工作:
USE [MyDB]
GO

IF (SCHEMA_ID('MySchema') IS NOT NULL)
BEGIN
    DROP SCHEMA [MySchema];
END

GO

CREATE SCHEMA [MySchema] AUTHORIZATION [dbo]

GO

1
如果您已经有该模式的表,则无法在不删除这些表(或其他对象)的情况下删除它。 - marko982

5

CREATE SCHEMA 必须单独成批处理,所以将其嵌入 EXEC 中即可。

IF (NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'acme')) 
BEGIN
    EXEC ('CREATE SCHEMA [acme] AUTHORIZATION [dbo]')
END

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接