【问题标题】:Should I use ExecuteNonQuery for this db backup command我应该为此数据库备份命令使用 ExecuteNonQuery
【发布时间】:2026-01-17 17:55:02
【问题描述】:

我有一个方法可以让我开始备份数据库。我想知道的是我是否应该在这种情况下使用 ExecuteNonQuery() 或者是否有更好的使用方法。这是我目前的代码:

    public static void RunBackup(string dbName, string filePath, string backupName, string connString)
    {
        using(SqlConnection objConnection = new SqlConnection(connString))
        {

            string commmandText = "BACKUP DATABASE @DBName TO  DISK = @FilePath WITH NOFORMAT, NOINIT, NAME = @BackUpName, SKIP, NOREWIND, NOUNLOAD,  STATS = 10";
            SqlCommand objCommand = new SqlCommand(commmandText,objConnection);
            objCommand.Parameters.AddWithValue("@dbName", dbName);
            objCommand.Parameters.AddWithValue("@FilePath", filePath);
            objCommand.Parameters.AddWithValue("@BackUpName", backupName);

            objConnection.Open();
            objCommand.ExecuteNonQuery();
            objConnection.Close();
        }
    }

我担心的一件事是能够验证备份是否完整且成功,同时处理需要和延长时间才能完成的备份的超时问题。

【问题讨论】:

    标签: c# ado.net


    【解决方案1】:

    ExecuteNonQuery 表示该命令不返回任何数据。这并不意味着它异步执行或您不会收到错误信息。它将阻塞直到命令完成并返回任何可能发生的错误

    【讨论】:

      【解决方案2】:

      为了处理长时间运行的查询问题,我最终选择了这个:

          public static void RunBackup(string dbName, string filePath, string backupName, string connString)
          {
              string commmandText = "BACKUP DATABASE @DBName TO  DISK = @FilePath WITH NOFORMAT, NOINIT, NAME = @BackUpName, SKIP, NOREWIND, NOUNLOAD,  STATS = 10";
              SqlConnection objConnection = new SqlConnection(connString);
              try
              {
                  SqlCommand objCommand = new SqlCommand(commmandText, objConnection);
                  objCommand.Parameters.AddWithValue("@dbName", dbName);
                  objCommand.Parameters.AddWithValue("@FilePath", filePath);
                  objCommand.Parameters.AddWithValue("@BackUpName", backupName);
      
                  objConnection.Open();
      
                  IAsyncResult result = objCommand.BeginExecuteNonQuery();
                  while (!result.IsCompleted)
                  {
                      System.Threading.Thread.Sleep(100);
                  }
      
      
                  int count = objCommand.EndExecuteNonQuery(result);
               }
              catch (SqlException e)
              {
                  throw e;
              }
              finally
              {
                  objConnection.Close();
      
              }
      
          }
      

      这将允许我在没有超时问题的情况下异步执行命令。我将在我的最终代码集中添加一些额外的错误处理等。我可能会做一些额外的工作,看看是否可以在脚本末尾返回更好的状态,我可以通过 EndExecuteNonQuery 或通过 AsyncCallBack 获得。

      【讨论】:

        【解决方案3】:
        ExecuteNonQuery() 
        

        在这里使用应该没问题。我要做的是在 using 周围运行一个 try catch 以捕获可能发生的任何错误并适当地处理它们。

        【讨论】:

          【解决方案4】:

          当您因调用而无法从数据库中接收任何信息时,您应该使用ExecuteNonQuery。如果在命令执行过程中发生任何错误,您将得到相应的异常。

          【讨论】:

            【解决方案5】:

            这看起来确实像您应该放入存储过程中以进行错误处理的类型。

            另外,看看here 看看它是在代码中完成的。

            【讨论】:

              【解决方案6】:

              我认为 ExecuteNonQuery 很好,但您应该考虑让用户使用您的查询超时。

              objCommand.CommandTimeout = 60*60; // 一个小时或更长时间

              如果您使用的是桌面应用程序,那么您肯定应该在异步调用中执行此查询。

              【讨论】:

                【解决方案7】:

                ExecuteNonQuery 是正确的命令。

                如果您希望收到有关恢复过程的更多信息,您应该订阅 SqlConnection 对象的InfoMessage 事件。那就是您也可以捕获所有“非错误”消息。

                【讨论】:

                  【解决方案8】:

                  试试看。它解决了大型数据库时超时过期的问题。

                  私有子命令1_Click() 出错时继续下一步 暗淡作为新的连接 将 tm 调暗为字符串 con.CommandTimeout = 500'''命令超时时间应该是500

                  与 con .ConnectionString = "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=dbiBMS;Data Source=192.168.103.4" 。打开 结束于 tm = CStr(时间)

                  con.Execute " 备份数据库 dbiBMS 到磁盘='E:\Database_Backup\Test1.bak' with format "

                  con.关闭 消息框 退出子 X: MsgBox Err.Description

                  结束子

                  【讨论】: