次のステートメントで始まる長いストアドプロシージャがあります。
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の外で実行すると、完全に機能するため、アクセス許可に関連する問題になる可能性があります。
使用してみてください
If(db_id(N'DBNAME') IS NULL)
それがうまくいかない場合、それは許可である可能性があります。これは、エラーメッセージが表示されない理由を説明します。
...対応する行を表示するために必要な最小限の権限は、ALTER ANY DATABASEまたはVIEW ANY DATABASEサーバーレベルの権限、またはmasterデータベースのCREATE DATABASE権限です。呼び出し元が接続されているデータベースは、sys.databasesで常に表示できます。
実行中のユーザーにはどのような権限がありますか?
Sys.databasesの内容が返されるようにコードを変更してみてください。
私が似たような問題を抱えていたので、中に声をかけました。データベースが存在しない場合は作成し、そのデータベースで操作を実行したかったからです。
問題は、スクリプトが1つのバッチで実行しようとしたため、SQLサーバーがUSE
コマンドを受信する前にデータベースをCREATE
しようとしたことだと思います。これにより、スクリプト全体が元に戻され、問題の根本はデータベースが作成されなかったことにあるように思われました。
私の場合、解決策は GO
コマンドを追加 スクリプトがテーブルを作成する最初の部分の後で、作業を始める前(例:テーブルの作成)でした。