118

作为构建过程的一部分,我们在将代码部署到 4 个不同的环境时运行数据库更新脚本。此外,由于将添加相同的查询,直到我们将发布版本投入生产,它必须能够在给定的数据库上运行多次。像这样:

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

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

4

5 回答 5

191

你在寻找sys.schemas吗?

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

请注意,CREATE SCHEMA必须在自己的批次中运行(根据下面的答案

于 2008-10-22T14:44:32.420 回答
165

@bdukes 在确定架构是否存在方面是正确的,但上面的语句在 SQL Server 2005 中不起作用。CREATE SCHEMA <name>需要在自己的批处理中运行。一种解决方法是CREATE SCHEMA在 exec 中执行语句。

这是我在构建脚本中使用的内容:

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
于 2009-02-06T17:32:02.917 回答
3

这是旧的,所以我不得不添加:对于 SQL SERVER 2008+ 这些都有效(对于选择部分),然后用于EXECUTE('CREATE SCHEMA <name>')在负面结果上实际创建它。

DECLARE @schemaName sysname = 'myfunschema';
-- shortest
If EXISTS (SELECT 1 WHERE SCHEMA_ID(@schemaName) IS NOT NULL)
PRINT 'YEA'
ELSE
PRINT 'NOPE'

SELECT DB_NAME() AS dbname WHERE SCHEMA_ID(@schemaName) IS NOT NULL -- nothing returned if not there

IF NOT EXISTS ( SELECT  top 1 *
                FROM    sys.schemas
                WHERE   name = @schemaName )
PRINT 'WOOPS MISSING'
ELSE
PRINT 'Has Schema'

SELECT SCHEMA_NAME(SCHEMA_ID(@schemaName)) AS SchemaName1 -- null if not there otherwise schema name returned

SELECT SCHEMA_ID(@schemaName) AS SchemaID1-- null if not there otherwise schema id returned


IF EXISTS (
    SELECT sd.SchemaExists 
    FROM (
        SELECT 
            CASE 
                WHEN SCHEMA_ID(@schemaName) IS NULL THEN 0
                WHEN SCHEMA_ID(@schemaName) IS NOT NULL THEN 1
                ELSE 0 
            END AS SchemaExists
    ) AS sd
    WHERE sd.SchemaExists = 1
)
BEGIN
    SELECT 'Got it';
END
ELSE
BEGIN
    SELECT 'Schema Missing';
END
于 2019-03-15T20:20:56.827 回答
2

如果组件的布局允许,这也可以。

IF EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'myschema') SET NOEXEC ON
去
CREATE SCHEMA myschema
去
SET NOEXEC OFF -- 如果需要进一步处理。
去
于 2020-01-09T20:41:11.423 回答
1

只是为了更加“防御”,以下版本会生成一个类型转换错误,以解释 > 1 匹配的可能性(但不太可能),Schema类似于验证代码经常故意抛出异常的方式,因为我相信它是好的,我相信它是“'最佳实践'”来解释所有可能的返回结果,但不太可能,即使它只是产生一个致命的异常,因为停止处理的已知效果通常比未捕获错误的未知级联效果更好。因为这极不可能,所以我认为不值得单独Count检查 +ThrowTry-来生成更用户友好的致命错误CatchThrow但仍然是致命错误。

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
于 2017-06-22T19:36:02.903 回答