我有一个每晚运行的存储过程。它从链接服务器中提取一些数据并将其插入到运行 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
仍然会产生此错误:消息 942,级别 14,状态 4,第 8 行数据库“数据库”无法打开,因为它处于脱机状态。