C# - 如何循环遍历表格以更新每一行MySQL

3
我正在一个项目上工作,需要通过在C#中循环遍历并逐行更新MySql表格来更新表格(逐个更新)。 注意:我只需要更新表格中的一列值。
现在,我知道这个问题已经被问过很多次,但是在花费了很多时间在互联网上搜索后,我没有找到解决我的问题的方法。 更多解释: 所以我已经知道了一些必要的事情来使这个工作:
  • 我知道如何建立一个(工作)SSH连接。
  • 我知道如何建立一个(工作)MySql连接到我的数据库。
  • 我知道如何在C#中运行/执行SELECTUPDATE查询/命令。
因此,使整个事情工作所需要的唯一一件事就是循环本身。
现在,在我的研究中,我看到了一些回答建议使用Reader。我不知道这是否是我需要的,如果是,我该如何正确使用它。
以下是我迄今为止的代码(用于建立连接和执行查询):
class ReaderDemo1
{
    public static void Update()
    {
        Console.WriteLine("[Core] Opening Connection To Database...");
        Database.openStockConn(Settings.databaseName, Settings.databaseUsername, Settings.databasePassword, Settings.sshHost, Settings.sshUsername, Settings.sshPassword);

        if (Database.stockConn.State != ConnectionState.Open)
        {
            Database.openStockConn(Settings.databaseName, Settings.databaseUsername, Settings.databasePassword, Settings.sshHost, Settings.sshUsername, Settings.sshPassword);
        }
        Console.WriteLine("[Core] database connection is now open!\n");

        MySqlCommand cmd = new MySqlCommand("SELECT value FROM catalog_product_entity_decimal", Database.stockConn);
        try
        {
            Console.WriteLine("[Price] Updating Prices...");

            MySqlCommand command = new MySqlCommand("UPDATE catalog_product_entity_decimal SET value= 1112 WHERE value_id= 4063", Database.stockConn);
            command.ExecuteNonQuery();

            Console.WriteLine("[Price] Prices Have Been Updated!");                
        }
        catch
        {
            Console.WriteLine("Updating Failed!");
        }
        finally
        {
            if (Database.stockConn != null)
            {
                Database.stockConn.Close();
            }
        }
    } 
}

为了提供额外的背景信息:

  • Database.cs 是我创建连接 (SSHMySql) 的地方。
  • Settings.cs 是我存储 SSHMySql 连接的所有登录数据的地方。

如果你们想知道,我已经尝试过一些关于循环的事情,但是(如我已经提到的)这些尝试并不成功。

我的 Reader 尝试:

using (var reader = command.ExecuteReader())
{
     var indexOfValue = reader.GetOrdinal("value");

     while (reader.Read())
     {
          var price1 = reader.GetValue(indexOfValue);

           Console.WriteLine("Executing Update Command...");

           MySqlCommand cmd = new MySqlCommand("UPDATE catalog_product_entity_decimal SET value= 1222 WHERE entity_id= 759 AND entity_id= 839 AND entity_id= 881", con);
           cmd.ExecuteNonQuery();

           Console.WriteLine("Update Command Executed!"); 
    }
} 

以上代码并没有按照我期望的那样工作(可能是因为它现在实际上什么也没做)。只是想让大家知道,我卡住了,不是遇到了错误,而是不知道该怎么做。

希望你们中有人能帮助我或指引我正确的方向。如果你认为我的问题是重复的,请告诉我,我会查看它!:) 非常感谢。

顺祝商祺,

LKS

编辑:

如果你们想知道,这里 是我的表格样式。 表格包含大约 5600 行,所以这些只是前面的行。


@Steve,我没有收到错误提示,只是不知道如何循环遍历我的表格,无论使用还是不使用Reader - LinkerKnieSchijf
@Steve,我不是在请你们帮我解决一个错误信息,而是在问你们如何循环遍历我的表格。 :) - LinkerKnieSchijf
你的意思是像这样循环吗?https://dev59.com/43I-5IYBdhLWcg3wm5hG#1774515 - Raizzen
ORM是不是不好? - Drag and Drop
@LinkerKnieSchijf - Object-Relation-Mapper,在C#中将成为EntityFramework。但是,逐行执行此操作将比批量更新更慢且不太可靠;理想情况下,您应该将所有行上传到暂存表(假设每行的值都不同),然后运行单个“UPDATE”语句。 - Clockwork-Muse
显示剩余3条评论
4个回答

3

像Frederiks的答案一样,您现在要做的是循环遍历表格并执行相同的查询。

即使您设法让代码工作,它也会非常慢(因为您需要更新约5600行)。

因此,我的建议是创建一个新表格,并在其中放置新值(即您想在循环之后拥有的值)。然后只需运行单个更新命令即可使用新表格中的值更新旧表格。

这个选项可能需要几秒钟就能完成,所以速度更快! :)

您需要的查询应该看起来像这样:

    UPDATE old_table
    INNER JOIN  new_table 
    USING (column) --> // if you want to update a specific column

编辑:

除了我之前的回答外,以下是如何更准确地更新您的表格:

UPDATE old_table
   INNER JOIN new_table ON old_table.value_id = new_table.value_id  // Use this to set your columns with unique values's
   SET old_table.value = new_table.value // For the column with the value's you want to update

所以,在上述代码中,你使用new_table的值更新old_table。在这个例子中,你只更新了一个列的值(你想要的那个)。你可以扩展查询以获得不同的结果。

谢谢回答!我一定会研究一下的! - LinkerKnieSchijf
这个代码完美运行!非常感谢你的回答! :D - LinkerKnieSchijf
1
@LinkerKnieSchijf 没问题! :) - MedMekss

2

我想不出为什么您要在循环中一次读取一行并写入一行,但是这确实是您可以实现的方法。

使用一个SqlCommand来读取,另一个SqlCommand用于更新。在循环中更改每个更新的参数。

public static void Update()
{
    Database.openStockConn(Settings.databaseName, Settings.databaseUsername, Settings.databasePassword, Settings.sshHost, Settings.sshUsername, Settings.sshPassword);

    if (Database.stockConn.State != ConnectionState.Open)
    {
        Database.openStockConn(Settings.databaseName, Settings.databaseUsername, Settings.databasePassword, Settings.sshHost, Settings.sshUsername, Settings.sshPassword);
    }
    Console.WriteLine("[Core] database connection is now open!\n");

    MySqlCommand cmd1 = new MySqlCommand("SELECT value FROM catalog_product_entity_decimal", Database.stockConn);
    MySqlCommand cmd2 = new MySqlCommand("UPDATE catalog_product_entity_decimal SET value= 1112 WHERE value_id= 4063", Database.stockConn);


    try
        {
            Console.WriteLine("[Price] Updating Prices...");

        using (var reader = cmd1.ExecuteReader())
        {
            var indexOfValue = reader.GetOrdinal("value");

            while (reader.Read())
            {
                var price1 = reader.GetValue(indexOfValue);

                Console.WriteLine("Executing Update Command...");

                cmd2.ExecuteNonQuery();

                Console.WriteLine("Update Command Executed!");
            }
        }
    }
    catch
    {
        Console.WriteLine("Updating Failed!");
    }
    finally
    {
        if (Database.stockConn != null)
        {
            Database.stockConn.Close();
        }
    }
}

嗨,谢谢你的回答!我尝试了你的代码,但现在它一直显示 "There is already an open DataReader associated with this Connection which must be closed first"。可能只是需要在某个地方加上 .Close();,但我不知道该放在哪里(我已经尝试过,但然后它说 Reader 已关闭,我可能把它放在了错误的位置),所以再多一点帮助会很好哈哈。 - LinkerKnieSchijf
你可以使用两个独立的连接。将它们放在堆叠的块中,你就不需要担心关闭它们了。 - llessurt
1
我仍然看不出你为什么想要一次读取一行或一次更新一行。为什么不使用一个更新命令来完成呢? - llessurt

2
SQL是基于集合的,这意味着通常有比遍历整个表格更好的方法。对于你的问题也是如此。你想避免遍历整个表格逐条更新记录,因为这样非常缓慢。
我不确定你想要实现什么,因为你的代码示例遍历一个表格,然后在循环内部,你一遍又一遍地执行相同的语句,但你总是更新完全相同的记录?
如果你想用来自另一个表格的信息更新表格中的记录,你可能需要查看UPDATE语句和JOIN子句,如这里所解释的那样。

谢谢回答!从另一个表中获取值来更新表中的值确实非常有趣,我一定会研究一下! - LinkerKnieSchijf

0
你可以尝试这个更改,通过获取行数并更新记录。
MySqlCommand cmd = new MySqlCommand("SELECT count(*) FROM catalog_product_entity_decimal", Database.stockConn);
    try
    {
        var reader = cmd .ExecuteReader();
        if(reader.Read()){
            var totalRows=reader.GetInt32(0);
            Console.WriteLine("[Price] Updating Prices...");

              while(totalRows-->0){
                    MySqlCommand command = new MySqlCommand("UPDATE catalog_product_entity_decimal SET value= 1112 WHERE value_id= 4063", Database.stockConn);
                    command.ExecuteNonQuery();

               }
            Console.WriteLine("[Price] Prices Have Been Updated!");   
        }             
    }
    catch
    {
        Console.WriteLine("Updating Failed!");
    }
    finally
    {
        if (Database.stockConn != null)
        {
            Database.stockConn.Close();
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接