web-dev-qa-db-ja.com

データベーススキーマが存在するかどうかを照会する方法

ビルドプロセスの一環として、4つの異なる環境にコードを展開するときにデータベース更新スクリプトを実行します。さらに、リリースを実稼働環境にドロップするまで同じクエリが追加されるため、特定のデータベースで複数回実行できるようになりますhas。このような:

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

現在、デプロイメント/ビルドスクリプトにcreate schemaステートメントがあります。スキーマの存在をどこで照会しますか?

89
Pulsehead

sys.schemas をお探しですか?

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

CREATE SCHEMAは、独自のバッチで実行する必要があります( 以下の回答 ごと)

145
bdukes

@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
_
149
vfilby

extra "defensive"であるため、次のバージョンでは、型変換エラーが生成され、検証コードが頻繁に意図的にスローされる方法に似たSchemaに1を超える可能性があります。例外は、可能性のあるすべての返品結果を考慮することは「ベストプラクティス」であり、致命的な例外を生成するだけであっても、処理を停止する既知の効果は通常、未知のカスケード効果よりも優れていると信じているためですトラップされていないエラー。ありそうもないので、別のCountチェック+ ThrowまたはTry-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
1
Tom

これは古いので、追加する必要があります。SQLSERVER 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
0