【问题标题】:C# - How To Loop Through A Table To Update Each Row MySQLC# - 如何遍历表以更新每一行 MySQL
【发布时间】:2018-05-17 12:38:19
【问题描述】:

我正在做一个项目,我必须通过循环更新 MySql 中的表并更新 C# 中的每一行(一个接一个)。 注意:我必须更新表中只有一列的值。

现在,我知道这个问题已经被问过(很多次),但是在花了很多时间在互联网上搜索之后,我还没有找到解决我问题的方法。

更多解释:

所以我已经知道了完成这项工作所必需的一些事情:

  • 我知道如何建立(有效的)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 连接的所有登录数据的地方。

如果你们想知道,我自己已经尝试了一些关于循环的事情,但是(正如我已经提到的)这些尝试没有成功。

我对阅读器的尝试:

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

编辑:

如果你们想知道,this 就是我的桌子的样子。 该表包含大约 5600 行,因此这些只是最上面的行。

【问题讨论】:

  • 如果你想得到帮助,至少告诉我们错误信息是什么。
  • @Steve 我没有收到错误,我只是不知道如何循环遍历我的表。有或没有Reader
  • @Steve 所以我不是要你们解决我收到的错误消息,而是要问你们如何循环遍历我的表格。 :)
  • 你的意思是这样循环? stackoverflow.com/a/1774515/9055793
  • 认为解决方案是一个循环。但是什么会更好呢?提交 3 个(或 3000 个)更新声明?或者改为运行UPDATE catalog_product_entity_decimal SET value= 1222 WHERE entity_id IN (759 , 839 , 881)

标签: c# mysql


【解决方案1】:

就像 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。在此示例中,您仅从一列(您想要的)更新值。

您可以扩展查询以获得不同的结果。

【讨论】:

  • 感谢您的回答!一定会调查的!
  • 这就像一个魅力!非常感谢您的回答! :D
  • @LinkerKnieSchijf 没问题! :)
【解决方案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 已关闭,我可能把它在/错误的地方),所以多一点帮助会很好哈哈
  • 您可以使用两个单独的连接。使用积木将它们堆叠起来,您无需担心关闭它们。
  • 我仍然看不出您为什么要一次读取一行或一次更新一行。为什么不在一个更新命令中执行此操作?
【解决方案3】:

SQL 是基于集合的,这意味着几乎总是有比遍历表更好的方法。 你的问题也是这样。您希望避免遍历整个表来逐条更新,因为这非常慢。

对我来说,你想要实现的目标并不明显,因为你的代码示例在一个表上循环,然后在你的循环内,你一遍又一遍地执行相同的语句,但你总是更新确切的相同的记录?

如果您想使用来自另一个表的信息更新表中的记录,您可能需要查看 UPDATE 语句以及 JOIN 子句,如 here 所述。

【讨论】:

  • 感谢您的回答!用来自另一个表的值更新一个表中的值确实很有趣,一定会研究这个!
【解决方案4】:

您可以通过计算行数然后更新记录来尝试此更改。

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();
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2016-06-21
    相关资源
    最近更新 更多