当在 .net 上调用恢复存储过程但在 SQL Server 上运行时数据库卡在恢复状态

Posted

技术标签:

【中文标题】当在 .net 上调用恢复存储过程但在 SQL Server 上运行时数据库卡在恢复状态【英文标题】:Database stuck on restoring state when the restore stored procedure is call on .net but ok when running on SQL Server 【发布时间】:2021-11-06 16:16:53 【问题描述】:

我有一个存储过程,它将备份一个数据库并根据备份恢复一个新的数据库。

CREATE PROCEDURE [dbo].[CloneBaseAQSDB]
-- Add the parameters for the stored procedure here
@destDb NVARCHAR(50) AS
BEGIN


-- Insert statements for procedure here
DECLARE @backupPath nvarchar(400);
DECLARE @sourceDb nvarchar(50);
DECLARE @sourceDb_log nvarchar(50);

DECLARE @destMdf nvarchar(100);
DECLARE @destLdf nvarchar(100);
DECLARE @sqlServerDbFolder nvarchar(100);

SET @sourceDb = 'based_db'
SET @sourceDb_log = @sourceDb + '_log'


SET @backupPath = 'C:\MSSQL\Backup\' + @sourceDb + '.bak'   
SET @sqlServerDbFolder = 'C:\MSSQL\DATA\'

SET @destMdf = @sqlServerDbFolder + @destDb + '.mdf'
SET @destLdf = @sqlServerDbFolder + @destDb + '_log' + '.ldf'

BACKUP DATABASE @sourceDb TO DISK = @backupPath

RESTORE DATABASE @destDb FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDb     TO @destMdf,
   MOVE @sourceDb_log TO @destLdf   
END

当我尝试在 SQL 上运行存储过程时,它将成功运行并且可以访问数据库。 就会有这个结果。

 Processed 4520 pages for database 'based_db', file 'based_db' on file 18.
 Processed 2 pages for database 'based_db', file 'based_db_log' on file 18.
 BACKUP DATABASE successfully processed 4522 pages in 1.516 seconds (23.303 MB/sec).
 Processed 4520 pages for database 'AQS_NEW', file 'based_db' on file 1.
 Processed 2 pages for database 'AQS_NEW', file 'based_db_log' on file 1.
 RESTORE DATABASE successfully processed 4522 pages in 44.801 seconds (0.788 MB/sec).

但是当我尝试使用 sqlCommand 在 .net 上调用存储过程时。该命令将完成执行,但数据库在恢复状态时卡住了。

    public void clonedBaseDatabase() 
        string connString = Common.setConnstring(Common.master_user, Common.master_pass, "master");
        string query = "CloneBaseAQSDB";
        SqlConnection con = new SqlConnection(connString);
        using (SqlConnection conn = new SqlConnection(connString)) 
            con.Open();
            SqlCommand cmd = new SqlCommand(query, con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@destDb", DB_NAME);
            try
            
                cmd.ExecuteNonQuery();

            
            catch (Exception ex)
            
                Common.addErrorMessage(ex.Message);
            
              
    

【问题讨论】:

我已经尝试使用一种方法在关闭连接之前检查数据库是否可访问,因为我认为问题是 .net 已经在恢复脚本完成之前立即关闭连接。但是即使连接没有关闭,数据库仍然处于恢复状态。 问题最好edit补充更多信息。 根据 SSMS 的日志输出,RESTORE DATABASE 操作耗时 44 秒。 SqlCommand 有一个 default CommandTimeout of 30 seconds。它可能会在超时时尝试取消操作。 旁注:@destDb 应该是 sysnamenvarchar(128) 的别名),其他变量应该是 nvarchar(255) 不要使用addwithvalue。您还对数据库进行了许多假设 - 逻辑名称和物理名称。当心! 【参考方案1】:

根据 AlwaysLearning 评论,我只是添加了

cmd.CommandTimeout = 0; 

它有效!

【讨论】:

以上是关于当在 .net 上调用恢复存储过程但在 SQL Server 上运行时数据库卡在恢复状态的主要内容,如果未能解决你的问题,请参考以下文章

从 sql 调用和执行存储过程到 vb.net 文本框

存储过程如何在从 BIDS 调用时不返回行,但在使用相同参数时从 SSMS 调用时返回行?

ADO.NET 调用 T-SQL 存储过程会导致 SqlTimeoutException

怎么破解sqlserver加密的存储过程

在Net下调用SqlServer2k中存储过程

Oracle SQL 存储过程调用与执行