use*_*162 1 mirroring sql-server-2012 if-not-exists
我想使用维护计划缩小多个数据库的事务日志文件。这些数据库是镜像的,因此无法在MIRROR
数据库上执行收缩任务,但必须在两台服务器上都配置维护计划。我正在SQL Server 2012 Standard (SP1)
我们的开发系统上使用,但代码也需要处理2008 R2
。
我试着用下面的脚本,它可以处理一个数据库,称为DR
内的,Execute T-SQL Statement Task
:
IF EXISTS (SELECT NULL FROM sys.databases WHERE [name] = 'DR' AND [state_desc] = 'ONLINE')
BEGIN
PRINT 'test';
USE DR;
DBCC SHRINKFILE (DR_log, 2048);
END
GO
Run Code Online (Sandbox Code Playgroud)
这在 上运行良好PRINCIPLE
,但是会导致在 上出现以下错误消息MIRROR
:
Msg 954, Level 14, State 1, Line 4
The database "DR" cannot be opened. It is acting as a mirror database.
Run Code Online (Sandbox Code Playgroud)
IF
该USE
命令似乎忽略了该块。本Print
如果不执行USE
被注释掉。Shrink Database
SSMS 中可用的维护任务提供了一个选项ignore databases where the state is not online
。但是,日志文件没有显示这是如何完成的。无法使用此任务,因为它还会缩小数据文件,而不仅仅是日志文件。
如何确保USE
只有在数据库处于Online
状态时才执行?我能想到的另一个选择是使用动态 SQL,我想避免这种情况。
注意:此任务不会频繁执行,而是在导致日志文件超出其通常大小的异常大事务之后执行。
解决方案:我们使用动态 sql 来解决此问题,另请参阅@Aaron Bertrand 提供的答案
这是在解析时发生的,您几乎无法改变实际行为。SQL Server 对批处理中的语句进行一些检查,并且出于所有意图和目的,假装您的条件逻辑不存在。
出于同样的原因,您不能使用条件逻辑来确定要创建两个可能的 #temp 表中的哪一个(此问题的最常见症状)。尽管将其视为人类,您会发现只能#t
创建一个版本,但 SQL Server 并不这么认为。无论您选择Parse
( Ctrl+ F5) 还是Execute
(just F5),它都会报告错误消息:
IF (1=1)
BEGIN
CREATE TABLE #t(a INT);
END
ELSE
BEGIN
CREATE TABLE #t(b INT);
END
Run Code Online (Sandbox Code Playgroud)
两种情况下的结果:
消息 2714,级别 16,状态 1,第 7 行
数据库中已经有一个名为“#t”的对象。
当您所做的只是解析批处理时,错误消息就没有什么意义了;显然#t
还不能存在,但它表明 SQL Server 正在评估批处理中的语句,但忽略了那些处理条件逻辑的语句。
为了解决这个问题,你可以使用动态 SQL,它在执行之前不会被解析:
IF EXISTS (SELECT NULL FROM sys.databases WHERE [name] = 'DR' AND [state_desc] = 'ONLINE')
BEGIN
EXEC DR.sys.sp_executesql N'DBCC SHRINKFILE (DR_log, 2048);';
END
Run Code Online (Sandbox Code Playgroud)
然而,这对我来说似乎真的,真的,真的错了。您是否在不断缩小您的日志文件?为什么?这是一个如此自我挫败的过程。请完整阅读这篇文章:
然后,适当地调整日志文件的大小 - 一次 - 并确保您使用正确的恢复模型,这样您就不会不断地进行这种增长-收缩-增长-收缩-增长-收缩循环。如果日志对于镜像来说太大,请获取更大的磁盘。削弱初级以弥补镜子的不足似乎是不对的。
归档时间: |
|
查看次数: |
193 次 |
最近记录: |