簡體   English   中英

在將blob更新為mysql時,在執行命令期間遇到致命錯誤

[英]Fatal error encountered during command execution while updating blob to mysql

String query = "";
        string constr = ConfigurationSettings.AppSettings["MySQLConnectionStringForIMS"];
        using (MySqlConnection con = new MySqlConnection(constr))
        {
            //string query = "INSERT INTO user(name, files,contentType) VALUES (@name,@files,@contentType)";
            if (update == "mainSec")
            {
                query = "update main_section set contentType=@contentType,fileData=@fileData,fileNameAfterUploading=@fname,haveDir=@dir where id=@id";
            }
            else
            {
                query = "update sub_section set subContentType=@contentType,subFileData=@fileData,fileNameAfterUploading=@fname,haveDir=@dir where MainSecId=@id and id=@subId";
            }
            using (MySqlCommand cmd = new MySqlCommand(query))
            {
                cmd.Connection = con;
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.AddWithValue("@contentType", contentType);
                cmd.Parameters.AddWithValue("@fileData", data);
                cmd.Parameters.AddWithValue("@fname", filename);
                cmd.Parameters.AddWithValue("@dir", 1);
                cmd.Parameters.AddWithValue("@id", mainId);
                if (update == "subSec")
                {
                    cmd.Parameters.AddWithValue("@subId", subId);
                }
                con.Open();
                int st = cmd.ExecuteNonQuery();
                if (st == 1)
                {
                    //Uri uri = new Uri(url, UriKind.Absolute);
                    //System.IO.File.Delete(uri.LocalPath);
                }
                con.Close();
            }
        }

我們使用的是MySql.Data.dll版本6.9.5.0。

這失敗並出現錯誤:mysql在命令執行期間遇到致命錯誤。 關於為什么會失敗的任何想法?

TL; DR

由於不匹配的分支比較,您正在執行具有6個未綁定變量的查詢,但您只綁定了5個參數。

詳情

堆棧跟蹤/異常中沒有提供足夠的信息來明確回答,但似乎對上述分支中的不良做法的猜測是根本原因,即在這兩個分支中:

if (update == "mainSec")
{
    query = ... Query has 5 unbound variables
}
else
{
    query = ... Query has 6 unbound variables
}

if (update == "subSec")
{
     ... bind the 6th parameter here
}

..因為update類型/模式字符串mainSecmainSecsubSec的范圍,所以有一個分支使用帶有6個參數標記的sub_section查詢,但是沒有綁定第6個標記,導致錯誤。

在這種情況下,我建議您不要使用弱約束字符串,而是嚴格限制update的輸入范圍,例如使用enum

enum UpdateMode
{
    Invalid = 0, // This will be the default, and can be used to ensure assignment
    MainSection,
    SubSection
}

由於只有兩種可能的模式,您可以避免使用條件賦值的第一個查詢賦值分支,即

Contract.Assert(updateMode != UpdateMode.Invalid);
var query = updateMode == UpdateMode.MainSection
      ? "update main_section set contentType=@contentType ... "
      : "update sub_section set subContentType=@contentType ... ";

這樣做的好處是query的聲明和賦值可以綁定在一起(並提供額外的編譯器保證,必須分配query )。

(如果有兩個以上的查詢(以及兩個以上的枚舉狀態),那么static IReadOnlyDictionary<enum, string>將允許擴展此模式。)

綁定也會變為

if (updateMode == UpdateMode.SubSection)
{
    cmd.Parameters.AddWithValue("@subId", subId);
}

一些筆記

  • con.Close(); 不需要,因為你已經在new Connection周圍using - 如果它打開, Dispose將調用.Close
  • 我知道這已被注釋掉,但我強烈建議不要在此時執行文件IO

 if (st == 1)
 {
     // File.IO
 }

以來

  • 從關注點分離的角度來看,刪除文件屬於其他地方。 如果刪除僅依賴於正在更新的一行,則可以從此Blob更新方法返回。
  • I / O將在using塊的范圍內,這可能會阻止MySql Connection的發布(到連接池)
  • IO可能會失敗,並且根據任何事務控制,這可能會使您的系統處於有問題的狀態,其中記錄被刪除但文件卻沒有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM