web-dev-qa-db-ja.com

SQLが存在しない場合のデータベースの作成、予期しない動作

次のステートメントで始まる長いストアドプロシージャがあります。

IF  NOT EXISTS (SELECT * FROM sys.databases WHERE name = N'DBNAME')
    BEGIN
        CREATE DATABASE [DBNAME]
    END;

DBが存在しない場合、ローカルサーバーに作成することが期待されています。問題は、ほとんどの場合、ストアドプロシージャのこの部分を徹底的に処理し、作成しないため、同じプロシージャの他のコードと干渉することです。一方、非常にまれなケースでは、DBが作成されます。私の質問は、少なくとも10を試したことがあるので、DBが存在するかどうかを確認するより良い方法はありますか。

私が試した他の方法:

IF  NOT EXISTS (SELECT 1 FROM sys.databases WHERE name = N'DBNAME')
    BEGIN
        CREATE DATABASE [DBNAME]
    END;

IF  NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'DBNAME')
        BEGIN
            CREATE DATABASE [DBNAME]
        END;

IF  NOT EXISTS (SELECT name FROM master.dbo.sys.databases WHERE name = N'DBNAME')
            BEGIN
                CREATE DATABASE [DBNAME]
        END;

しかし、spの外で実行すると、完全に機能するため、アクセス許可に関連する問題になる可能性があります。

12
StefanL19

使用してみてください

 If(db_id(N'DBNAME') IS NULL)

それがうまくいかない場合、それは許可である可能性があります。これは、エラーメッセージが表示されない理由を説明します。

...対応する行を表示するために必要な最小限の権限は、ALTER ANY DATABASEまたはVIEW ANY DATABASEサーバーレベルの権限、またはmasterデータベースのCREATE DATABASE権限です。呼び出し元が接続されているデータベースは、sys.databasesで常に表示できます。

MSドキュメントのsys.databasesから

実行中のユーザーにはどのような権限がありますか?

Sys.databasesの内容が返されるようにコードを変更してみてください。

19
under

私が似たような問題を抱えていたので、中に声をかけました。データベースが存在しない場合は作成し、そのデータベースで操作を実行したかったからです。

問題は、スクリプトが1つのバッチで実行しようとしたため、SQLサーバーがUSEコマンドを受信する前にデータベースをCREATEしようとしたことだと思います。これにより、スクリプト全体が元に戻され、問題の根本はデータベースが作成されなかったことにあるように思われました。

私の場合、解決策は GOコマンドを追加 スクリプトがテーブルを作成する最初の部分の後で、作業を始める前(例:テーブルの作成)でした。

1
martonbognar