簡體   English   中英

如何在C#中創建一個方法,使我可以准備任何插入/更新語句?

[英]How to create a Method in C# that will allow me to prepare any insert/update statement?

我正在嘗試編寫一個小類,該類將幫助我使用C#和winforms連接到MySQL服務器。 我編寫了將啟動和關閉連接的連接。

我在這里要做的是在此類中創建一個方法,以允許我傳遞查詢和“數組中的值”,該方法將自動為我准備查詢。

因此,不必像這樣為每個INSERT / UPDATE查詢編寫方法或代碼。

    MySqlCommand command = connection.CreateCommand();
    command.CommandText = "INSERT INTO mytable(a,b,c,d)VALUES (?, ?, ?, ?)";
    command.Parameters.AddWithValue("?", array_val1);
    command.Parameters.AddWithValue("?", array_val2);
    command.Parameters.AddWithValue("?", array_val3);
    command.Parameters.AddWithValue("?", array_val4);
    connection.Open();
    command.ExecuteNonQuery();

我想有一個方法,我可以傳遞查詢和值,它將為我自動准備該語句。

像這樣的東西

//Call the Method
    processQuery("INSERT INTO mytable(a,b,c,d)VALUES (?, ?, ?, ?)", array(1,2,3,4));
//The new Method
    public processQuery(string sqlStr, array values){

        MySqlCommand command = connection.CreateCommand();
        command.CommandText = sqlStr;
        command.Parameters.AddWithValue("?", array_val1);
        command.Parameters.AddWithValue("?", array_val2);
        command.Parameters.AddWithValue("?", array_val3);
....
....
....
....
        command.Parameters.AddWithValue("?", array_val_SIZE_OF_ARRAY);
        connection.Open();
        command.ExecuteNonQuery();

    }

您可以讓您的方法接受一個表名和一個MySqlParameter列表,然后根據所傳遞的內容來編寫SQL。

public void ProcessQuery(string tableName, MySqlParameter keyParam, params MySqlParameter[] sqlParams)
{
    using(MySqlConnection cn = new MySqlConnection(this.ConnectionString))
    using(MySqlCommand cmd = cn.CreateCommand())
    {
        /*Update Statement*/

        //Param1 = @Param1, Param2 = @Param2, @Param3 = @Param3, etc.
        string updateParamStr = string.Join(
            ", ", 
            sqlParams.Select(sqlParam => string.Format("{0} = {1}", sqlParam.ParameterName.Substring(1), sqlParam.ParameterName)));

        //param = @param
        string keyMatchStr = string.Format("{0} = {1}", 
            keyParam.ParameterName.Substring(1),
            keyParam.ParameterName);

        string updateSql = string.Format("UPDATE {0} SET {1} WHERE {2}",
            tableName,
            updateParamStr,
            keyMatchStr);   


        /*Insert Statement*/

        //produce comma delimited list of param names with leading @ stripped eg. Param1, Param2, Param3
        string columnNameStr = string.Join(", ", sqlParams.Select(sqlParam => sqlParam.ParameterName.Substring(1)));

        //produce comma delimited list of param eg. @Param1, @Param2, @Param3
        string valueParamStr = string.Join(", ", sqlParams.Select(sqlParam => sqlParam.ParameterName));

        string insertSql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})",
            tableName,
            columnNameStr,
            valueParamStr);


        /*Combined Update and Insert*/

        string combinedSql = string.Format("{0} {1} WHERE ROW_COUNT() = 0", updateSql, insertSql);

        cmd.CommandText = combinedSql;
        cmd.Parameters.Add(keyParam);
        cmd.Parameters.AddRange(sqlParams);

        cn.Open();
        cmd.ExecuteNonQuery();
    }
}

生成的SQL創建一個組合的UPDATE和INSERT語句,看起來像這樣:

UPDATE MyTable SET Col1 = @Col1, Col2 = @Col2 WHERE KeyCol = @KeyCol
INSERT INTO MyTable (Col1, Col2) VALUES (@Col1, @Col2) WHERE ROW_COUNT() = 0

這將有效地運行一個UPDATE,它要么更新匹配的行,要么不做任何更改。 在后一種情況下,ROW_COUNT()= 0,這將使INSERT語句執行其工作。 我們只是在每個語句中利用WHERE子句使事物相互排斥。

然后,您將調用為唯一鍵傳遞MySqlParameter的方法,然后調用任意數量的MySqlParameter對象。

ProcessQuery(
    "MyTable",
    new MySqlParameter("@MyKeyColumn", 5)/*unique key column*/,
    new MySqlParameter("@SomeColumn", 1),
    new MySqlParameter("@SomeOtherColumn", "Some string"));

這樣的好處是,如果您選擇這樣做,則可以在MySqlParameter中提供數據類型信息,也可以使用名稱+值對使其保持簡單。 這確實需要使用@ParamName語法而不是“?”。 並且參數名稱與目標列相匹配,這在IMO中仍然更加清晰。

暫無
暫無

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

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