如何在 SQL Server 备份磁盘路径中使用变量?

dan*_*317 1 sql-server sql-server-2008

下面的 SQL 语句工作正常:

DECLARE @database VARCHAR(30) = 'DEMO';

BACKUP LOG @database
TO DISK = N'C:\zbackups\DEMO.trn' 
WITH NOFORMAT, NOINIT,  
NAME = N'MyDatabase Log Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10;

DBCC SHRINKFILE ('DEMO_log', 500);
Run Code Online (Sandbox Code Playgroud)

然而,这并没有:

DECLARE @database VARCHAR(30) = 'DEMO';

BACKUP LOG @database
TO DISK = 'C:\zbackups\' + @database + '.trn' 
WITH NOFORMAT, NOINIT,  
NAME = 'MyDatabase Log Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10;

DBCC SHRINKFILE (@database + '_log', 500);
Run Code Online (Sandbox Code Playgroud)

当我尝试连接时,指令TO DISKDBCC SHRINKFILE参数都会抛出错误。

如何在这些位置使用变量?还想将一些日期时间参数附加到文件路径,但尚未开始研究。

Aar*_*and 6

问题很简单,你不能在那里传递表达式。代替:

TO  DISK = 'C:\zbackups\' + @database + '.trn' 
Run Code Online (Sandbox Code Playgroud)

你需要:

DECLARE @fullpath nvarchar(1024);
SET @fullpath = 'C:\zbackups\' + @database + '.trn';

...

TO DISK = @fullpath

...
Run Code Online (Sandbox Code Playgroud)

您还可以以类似的方式参数化备份名称和日志文件名(而不是硬编码NAME = 'MyDatabase Log Backup')。但是为了让收缩操作在正确的上下文中运行(如果你真的真的真的真的需要它,也就是说),并且你可以依赖以相同方式配置的每个数据库,你将拥有将数据库名称硬编码在某处(例如在USE语句中),或使用动态 SQL 将上下文设置为正确的数据库,例如

DECLARE @database sysname = N'DEMO';

DECLARE @fullpath    nvarchar(1024) = N'C:\zbackups\' + @database + '.trn',
        @backup_name nvarchar(500)  = @database + N' log backup',
        @log_name    nvarchar(500)  = @database _ N'_log';

DECLARE @sql nvarchar(max) = N'BACKUP LOG @db
  TO DISK = @fullpath
  WITH NOFORMAT, NOINIT, NAME = @backup_name, 
  SKIP, NOREWIND, NOUNLOAD,  STATS = 10;

DBCC SHRINKFILE(@log, 500);';

DECLARE @context nvarchar(1024) = QUOTENAME(@database)
  + N'.sys.sp_executesql';

EXECUTE @context @sql, -- run @sql but in the context of @database
  N'@db sysname, @log nvarchar(500), 
    @fullpath nvarchar(1024), @backup_name nvarchar(500)',
    @database, @log_name, @fullpath, @backup_name;
Run Code Online (Sandbox Code Playgroud)