0

我一直试图找出这个错误,绝对没有任何运气。我已经通过了 SO,找到了一些零碎的东西来帮助我解决这个问题。

我需要创建一个计划作业,该作业将在 1 月 1 日复制和重命名数据库,因此没有人需要手动执行此操作。

这是完美运行的代码:

EXEC sp_renamedb 'ugocity', 'ugocity1'
GO

EXEC sp_detach_db @dbname = 'ugocity1'
GO

EXEC sp_configure 'show advanced options' , 1
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell' , 1
RECONFIGURE
GO
EXEC xp_cmdshell
    'md C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\'
GO
EXEC xp_cmdshell
    'RENAME "C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocity2017.mdf", "ugocity1.mdf"'
GO
EXEC xp_cmdshell
    'RENAME "C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocity2017_1.ldf", "ugocity1_log.ldf"'
GO

EXEC sp_configure 'xp_cmdshell' , 0
RECONFIGURE
GO
EXEC sp_configure 'show advanced options' , 0
RECONFIGURE
GO

EXEC sp_attach_db @dbname = 'ugocity1'
, @filename1 = 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocity1.mdf'
, @filename2 = 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocity1_log.ldf'

GO

但是,新的数据库名称需要包含年份。所以,它应该是例如'ugocity2017'。所以,在网上搜索了三个小时后,我想出了这个:

DECLARE @newname varchar(500), @newmdf varchar(500), @newldf varchar (500), @yearnum int, @prevyear int,
    @command1 varchar(max), @command2 varchar(max), @command3 varchar(max), @command4 varchar(max), @command5 varchar(max)

    SET @yearnum = YEAR(GETDATE())
    SET @prevyear = @yearnum - 2000

    SET @newname = 'ugocity' + CONVERT(varchar(4),@prevyear)
    SET @newmdf = 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\' + @newname +'.mdf'
    SET @newldf = 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocitylog.ldf'

    SET @command1 = 'sp_renamedb ''ugocity2017'', ''' + @newname + ''''
    SET @command2 = 'xp_cmdshell ''RENAME "C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocity2017.mdf", "' + @newname + '.mdf"'''
    SET @command3 = 'xp_cmdshell ''RENAME "C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocity1_log.mdf", "ugocitylog.ldf"'''
    SET @command4 = 'sp_detach_db @dbname = ''' + @newname + ''''
    SET @command5 = 'sp_attach_db @dbname = ''' + @newname + ''' , ' + ' @filename1 = ''' + @newmdf + ''' , ' + '@filename2 = ''C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocitylog.ldf'''

    EXECUTE (@command1)

    USE [master]

    EXECUTE (@command4)

    EXECUTE sp_configure 'show advanced options' , 1
    RECONFIGURE

    EXECUTE sp_configure 'xp_cmdshell' , 1
    RECONFIGURE

    EXECUTE (@command2)

    EXECUTE xp_cmdshell 'RENAME "C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocity1_log.mdf", "ugocitylog.ldf"'

    EXECUTE sp_configure 'xp_cmdshell' , 0
    RECONFIGURE

    EXECUTE sp_configure 'show advanced options' , 0
    RECONFIGURE

    EXECUTE (@command5)

当我运行第一个时,数据库及其物理文件被重命名,没有错误。当我运行第二个代码时,数据库和 .mdf 文件被重命名,但 .ldf 保持原样,我得到:

消息 5120,级别 16,状态 101,第 1 行
无法打开物理文件“C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\ugocitylog.ldf”。操作系统错误2:“2(系统找不到指定的文件。)”

从字面上看,权限是完全控制。

有没有其他人遇到过这个错误?我就是想不通。

4

1 回答 1

1

是的 - 问题不可能出在您的代码中,因此请查看其他地方。您有 5 个不同的命令字符串。您实际执行哪些?但是,为什么要为您太不耐烦而无法调试的复杂脚本而烦恼。您可以使用 restore 命令完成所有您需要做的事情。这包括更改数据库名称和重命名物理文件。SSMS 将为您执行此操作,您可以查看/使用它生成的脚本。

在常规页面中,选择“设备”并选择备份文件。为目标中的数据库指定一个新名称。在文件页面中,更改还原为列表中所有实际文件的物理文件名。然后单击对话框顶部的脚本按钮,而不是底部的确定按钮。

于 2017-12-28T16:42:15.740 回答