使用 MySqlCommand 在一个查询中进行多个 INSERT

Posted

技术标签:

【中文标题】使用 MySqlCommand 在一个查询中进行多个 INSERT【英文标题】:Multiple INSERT in one query using MySqlCommand 【发布时间】:2015-09-17 03:44:46 【问题描述】:

我正在使用以下代码:

        string cmd = "INSERT INTO " + Tables.Lux() + " VALUES(NULL, @Position, @Mode, @Timer)";
        try
        
            using (var MyConnection = new mysqlConnection(ConfigurationManager.ConnectionStrings["DataFormConnection"].ConnectionString))
            
                using (MySqlCommand command = new MySqlCommand(cmd, MyConnection))
                
                    MyConnection.Open();
                    command.Parameters.Add(new MySqlParameter("Position", Element.Position));
                    command.Parameters.Add(new MySqlParameter("Mode", Element.Mode));
                    command.Parameters.Add(new MySqlParameter("Timer", Element.Timer));
                    command.ExecuteNonQuery();
                
            
        

我正在使用上面的代码从包含 100 个项目的 Element 列表中插入数据。我只想在一个查询中添加 100 个值,并且我知道 SQL 语句如下所示:

INSERT INTO table (a,b) VALUES (1,2), (2,3), (3,4);

但我不知道如何使用 MySqlCommand.Parameters 方法应用该结构。

我的目标是传递这个函数 List<Element> 而不仅仅是 Element 并创建一个 INSERT 语句,其中列表中的所有项目仅在一个查询中执行。请问有什么帮助吗?

谢谢。

【问题讨论】:

这些值是否来自另一个 SQL 表? 您可以创建一个存储过程调用一次,然后在这里执行您的插入语句,如果您是从另一个表插入,您可以使用该表生成将要插入的数据。跨度> 您的问题的答案在您的帖子/代码中。您只需要添加参数而不是值。稍后您可以在调用 ExecuteNonQuery() 方法之前替换参数值。 @DavidBeaumont:这些值存储在一个列表中,它们是我想要保存的简单日志。 @AVD:这正是我想做的,但我在这个领域没有经验,我找不到如何去做。我发现的所有关于多个查询的信息都是从 SQL 语句的角度来看的,而不是从程序员的角度来看的应用程序。 【参考方案1】:

试试这样:

string cmd = "INSERT INTO " + Tables.Lux() + " VALUES ";
int counter = 0;

foreach (Element e in list) 

    sql += "(NULL, @Position" + counter + ", @Mode" + counter + ", @Timer" + counter + "),";
    command.Parameters.Add(new MySqlParameter("Position" + counter, e.Position));
    command.Parameters.Add(new MySqlParameter("Mode" + counter, e.Mode));
    command.Parameters.Add(new MySqlParameter("Timer" + counter, e.Timer));
    counter++;


command.CommandText = sql.Substring(0, sql.Length-1); //Remove ',' at the end

这样,您可以在查询中使用可变数量的参数,并且您只需针对数据库触发一次,而不是 n 次

这是未经测试的,只是我的想法!

【讨论】:

@Hamma 请在 cmets 中讨论,而不是通过编辑帖子 A 和 B 是您的参数名称的占位符,对不起,我没有用前面的 @ 写它们 好的,现在说得通了。抱歉编辑,我试图发表评论,但编写代码看起来很乱,以至于我认为以另一种方式阅读会容易得多。我会试试这个,谢谢! 没问题,希望对你有帮助 @Hamma 如果这篇文章对您有帮助,请标记为答案 是的,我试过了,它工作正常。我现在在一个查询中添加 100 行。非常感谢!【参考方案2】:

我使用@xenogenesis 的答案来解决我的问题,也许可以帮助其他人

List<EntregadorRPC.Address> addresstoinsert = eoSendAddressList.addresses;

int      batteryLvl = eoSendAddressList.batteryLevel;
DateTime dtHoraLocal;
int      size = addresstoinsert.Count;

const string insertHeader = "Insert into historicolocalizacao (Provedor, CodUsuario, Latitude, Longitude, Precisao, Logradouro, " +
                            "Complemento, Setor, Cidade, UF, Cep, DataHoraLocal, bateria) Values";

StringBuilder insertValues = new StringBuilder("");

using (MySqlCommand cmd = new MySqlCommand()) 

    for (int i = 0; i < size; i++) 
        EntregadorRPC.Address address = addresstoinsert[i];

        dtHoraLocal = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        dtHoraLocal = dtHoraLocal.AddMilliseconds(address.dataHoraLocal).ToLocalTime();
        /*address.logradouro       = WSUtils.RemoveSpecialCharacters(address.logradouro);
        address.formattedAddress = WSUtils.RemoveSpecialCharacters(address.formattedAddress);*/

        cmd.Parameters.AddWithValue($"@provedori",      address.provedor);
        cmd.Parameters.AddWithValue($"@user_idi",       user.user_id);
        cmd.Parameters.AddWithValue($"@latitudei",      address.latitude);
        cmd.Parameters.AddWithValue($"@longitudei",     address.longitude);
        cmd.Parameters.AddWithValue($"@precisaoi",      address.precisao);
        cmd.Parameters.AddWithValue($"@logradouroi",    address.logradouro);
        cmd.Parameters.AddWithValue($"@complementoi",   address.complemento);
        cmd.Parameters.AddWithValue($"@setori",         address.setor);
        cmd.Parameters.AddWithValue($"@cidadei",        address.cidade);
        cmd.Parameters.AddWithValue($"@ufi",            address.uf);
        cmd.Parameters.AddWithValue($"@cepi",           address.cep);
        cmd.Parameters.AddWithValue($"@datahoralocali", dtHoraLocal.ToString("yyyy-MM-dd HH:mm:ss"));
        cmd.Parameters.AddWithValue($"@bateriai",       batteryLvl);

        insertValues.Append($"(@provedori, @user_idi, @latitudei, @longitudei, @precisaoi, @logradouroi, @complementoi, @setori, @cidadei, @ufi, @cepi, @datahoralocali, @bateriai)");

        if (i < size - 1) 
            insertValues.Append(",");
        
    

    cmd.Connection  = conn;
    cmd.CommandText = $"insertHeaderinsertValues";
    await cmd.ExecuteNonQueryAsync();

【讨论】:

以上是关于使用 MySqlCommand 在一个查询中进行多个 INSERT的主要内容,如果未能解决你的问题,请参考以下文章

使用 MySqlCommand 执行存储过程时出现 SqlNullValueException

是否可以在 .NET MySqlCommand 中使用 MySql 用户定义变量?

C#:使用 CancellationToken 取消 MySqlCommand,给出 NULLReferenceException

MySQL 连接器/NET 的 MySqlCommand 不使用参数

MySqlCommand Command.Parameters.Add 已过时

如何设置两个连接字符串 MySqlCommand 对象参数?