2008-10-22 78 views
73

作为构建过程的一部分,我们运行数据库更新脚本,因为我们将代码部署到4个不同的环境。此外,由于相同的查询将被添加,直到我们将发布放入生产中,它已有能够在给定数据库上运行多次。像这样:如何查询数据库模式是否存在

IF NOT EXISTS (SELECT * FROM sys.tables WHERE object_id = OBJECT_ID(N'[Table]')) 
BEGIN 
    CREATE TABLE [Table] 
    (...) 
END 

目前我在部署/构建脚本中有一个create schema语句。我在哪里查询模式的存在?

+2

请考虑改变接受的答案。您所接受的答案实际上不适合您写作的情况。 – 2014-09-05 00:53:40

回答

108

你是在找sys.schemas

IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'jim') 
BEGIN 
EXEC('CREATE SCHEMA jim') 
END 

注意,CREATE SCHEMA必须在自己的批量运行(每the answer below

+0

Darn ...在我编辑帖子以使其更具可读性的时候......您解决了我的问题。谢谢mucho! – Pulsehead 2008-10-22 15:00:58

+17

这在SQL 2008中不起作用,因为CREATE SCHEMA需要是批处理中的第一条语句,请参阅vfilby文章以了解解决方法 – sergiom 2010-03-30 15:09:00

+3

您可以使用'从sys.schemas中选择1'来提高性能。 – vijaysylvester 2012-11-26 09:17:09

137

@bdukes是正确的金钱用于确定的模式存在,但上面的语句将在SQL工作Server 2005. CREATE SCHEMA <name>需要在其自己的批处理中运行。解决方法是在exec中执行CREATE SCHEMA语句。

以下是我在我的构建脚本使用:

IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = '<name>') 
BEGIN 
    -- The schema must be run in its own batch! 
    EXEC('CREATE SCHEMA <name>'); 
END 
1

只是要额外“防御性”,以下版本生成一个类型转换错误占可能性(但不太可能)的> 1匹配Schema与验证代码经常故意相似抛出异常是因为我相信它是好的,我相信这是''最佳实践'“来说明所有可能的返回结果,但不太可能,并且即使它只是产生致命异常,因为停止处理的已知效果通常优于未捕获错误的未知级联效应。因为这是不太可能的,我不认为这是值得的一个单独的Count支票+ ThrowTry - Catch-Throw的麻烦,以产生更人性化的致命错误,但仍然致命的错误。

SS 2005-:

declare @HasSchemaX bit 
set @HasSchemaX = case (select count(1) from sys.schemas where lower(name) = lower('SchemaX')) when 1 then 1 when 0 then 0 else 'ERROR' end 

SS 2008+:

declare @HasSchemaX bit = case (select count(1) from sys.schemas where lower(name) = lower('SchemaX')) when 1 then 1 when 0 then 0 else 'ERROR' end 

然后:

if @HasSchemaX = 1 
begin 
    ... 
end -- if @HasSchemaX = 1 
相关问题