毎晩実行するストアド プロシージャがあります。リンク サーバーから一部のデータを取得し、SQL エージェント ジョブが実行されるサーバー上のテーブルに挿入します。INSERT ステートメントを実行する前に、プロシージャは、リンク サーバー上のデータベースがオンライン (STATE = 0) かどうかをチェックします。そうでない場合、INSERT ステートメントは実行されません。
IF EXISTS(
SELECT *
FROM OPENQUERY(_LINKEDSERVER,'
SELECT name, state FROM sys.databases
WHERE name = ''_DATABASENAME'' AND state = 0')
)
BEGIN
INSERT INTO _LOCALTABLE (A, B)
SELECT A, B FROM _LINKEDSERVER._DATABASENAME.dbo._REMOTETABLE
END
ただし、リモート データベースが復元モードの場合、この手順ではエラーが発生します (遅延準備を完了できませんでした)。これは、スクリプト全体が実行される前に、BEGIN と END の間のステートメントが評価されるためです。また、IF 評価が真でない場合。_DATABASENAME は復元モードであるため、これはすでにエラーを発生させます。
回避策として、実行関数に INSERT ステートメントを配置しました。
EXECUTE('INSERT INTO _LOCALTABLE (A, B)
SELECT A, B FROM _LINKEDSERVER._DATABASENAME.dbo._REMOTETABLE')
しかし、SQL のこの部分が使用される前に、このステートメントの評価を防ぐ別のより洗練された解決策はありますか?
私のシナリオには、リンク サーバーが含まれます。もちろん、同じ問題は、データベースが同じサーバー上にある場合です。
IF 内の評価構文を防止する、まだ認識していないコマンドを期待していました。
IF(Evaluation)
BEGIN
PREPARE THIS PART ONLY IF Evaluation IS TRUE.
END
回答に関する編集:
私はテストしました:
IF(EXISTS
(
SELECT *
FROM sys.master_files F WHERE F.name = 'Database'
AND state = 0
))
BEGIN
SELECT * FROM Database.dbo.Table
END
ELSE
BEGIN
SELECT 'ErrorMessage'
END
それでもこのエラーが生成されます: Msg 942, Level 14, State 4, Line 8 Database 'Database' cannot be open because it is offline.