【问题标题】:Can' Connect to MySql Server on localhost after consecutive open and close of connection连续打开和关闭连接后无法连接到本地主机上的 MySql Server
【发布时间】:2013-01-03 03:49:44
【问题描述】:

我有一些 mysql 问题,我有一个名为“transactionNumber”和“counter”的列。

transactionNumber 值可以是这样的:(不包括字母)

a. 12345, 1234566
b. 9876, 98332, 23423
c. 12347
d. - 

'counter' 列是一个统计一行中有多少个 transactionNumber 的字段。例如上面的字母 'a' 有 2 个 transactionNumber,字母 'b' 有 3 个等等。字母 'd' 算作 1。

但应用程序启动时计数器列是空的。所以我创建了一个方法来计算每行的 transactionNUMer 并更新计数器列。

这是我的方法:

private void TransactionNumberCounter(DataSet dsData)
{
    for (int i = 0; i < dsData.Tables["data"].Rows.Count; i++)
    {
        DataRow dRow = dsData.Tables["data"].Rows[i];

        string tNumber = dRow.ItemArray.GetValue(1).ToString();
        string id = dRow.ItemArray.GetValue(0).ToString();

        string[] numbers = tNumbers.Split(',');

        char[] arr = new char[] { '\t', '\n' };
        int tNumberCounter= 0;

        List<string> listAccNumbers = new List<string>();

        foreach (string number in numbers)
            listAccNumbers.Add(number.TrimStart(arr));

        tNumberCounter = listAccNumbers.Count;

        string query = @"UPDATE bartran SET aNumberCounter = ? WHERE id = ?;";

        OdbcParameter[] parameters = new OdbcParameter[]{
        new OdbcParameter("?", aNumberCounter),
        new OdbcParameter("?", id)
        };

        DBServer.ExecuteQuery(query, "database_name", parameters);
    }
}

此方法有效。但是如果有数千行要计算,我会得到一个错误:

Can't connect to MySQL server on "localhost" (10061)"

所以我在这里尝试为你们寻求帮助。我如何计算 t.Number 并根据页面加载计数更新计数器字段。提前致谢!

还有其他可行的方法吗?

EDIT: 

这是 DBServer 类:

using System;
using System.Data;
using System.Data.Odbc;

public static class DBServer
{
//Test
private const string Server = "localhost";
private const string Uid = "root";
private const string Pwd = "defaultpass";

//LIVE
//private const string Server = "ipaddress";
//private const string Uid = "root";
//private const string Pwd = "password";

public static DataTable GetTable(string query, string database)
{
    using (OdbcConnection cn = new OdbcConnection(
        string.Format("Driver={{MySQL ODBC 5.1 Driver}};Server={0};dataBase={1};User={2};Password={3};Option=3;",
        Server, database, Uid, Pwd)))
    {

        using (OdbcCommand cmd = new OdbcCommand(query, cn))
        {
            DataTable dt = new DataTable();

            cn.Open();

            using (OdbcDataReader rdr = cmd.ExecuteReader())
            {
                dt.Load(rdr);

                return dt;
            }
        }
    }
}

public static DataTable GetTable(string query, string database, OdbcParameter[] parameters)
{
    using (OdbcConnection cn = new OdbcConnection(
        string.Format("Driver={{MySQL ODBC 5.1 Driver}};Server={0};database={1};User={2};Password={3};Option=3;",
        Server, database, Uid, Pwd)))
    {
        using (OdbcCommand cmd = new OdbcCommand(query, cn))
        {
            if (parameters != null)
                cmd.Parameters.AddRange(parameters);

            DataTable dt = new DataTable();

            cn.Open();

            using (OdbcDataReader rdr = cmd.ExecuteReader())
            {
                dt.Load(rdr);

                return dt;
            }
        }
    }
}

/// <summary>
/// Executes query to the database (Parameterized)
/// </summary>
/// <param name="query">Query String</param>
/// <param name="database">Target Database</param>
/// <param name="parameters">Collection of parameters</param>
/// <returns>Number of affected records</returns>
public static int ExecuteQuery(string query, string database, OdbcParameter[] parameters)
{
    using (OdbcConnection cn = new OdbcConnection( string.Format("Driver={{MySQL ODBC 5.1 Driver}};Server={0};database={1};User={2};Password={3};Option=3;",
        Server, database, Uid, Pwd)))
    {
        using (OdbcCommand cmd = new OdbcCommand(query,cn))
        {
            if (parameters != null)
                cmd.Parameters.AddRange(parameters);

            cn.Open();

            return cmd.ExecuteNonQuery();
        }
    }
}

/// <summary>
/// Check if the query has record (Parameterized)
/// </summary>
/// <param name="query">Query string</param>
/// <param name="database">Target database</param>
/// <param name="parameters">Collection of parameters</param>
/// <returns>true if has record else false</returns>
public static bool HasRecord(string query, string database, OdbcParameter[] parameters)
{
    using (OdbcConnection cn = new OdbcConnection( string.Format("Driver={{MySQL ODBC 5.1 Driver}};Server={0};database={1};User={2};Password={3};Option=3;",
        Server, database, Uid, Pwd)))
    {
        using (OdbcCommand cmd = new OdbcCommand(query,cn))
        {
            if (parameters != null)
                cmd.Parameters.AddRange(parameters);               

            cn.Open();

            using (OdbcDataReader reader = cmd.ExecuteReader())
            {
                return reader.HasRows;
            }
        }
    }
}

/// <summary>
/// Check if the query has record
/// </summary>
/// <param name="query">Query string</param>
/// <param name="database">Target database</param>
/// <returns>true if has record else false</returns>
public static bool HasRecord(string query, string database)
{
    using (OdbcConnection cn = new OdbcConnection(string.Format("Driver={{MySQL ODBC 5.1 Driver}};Server={0};database={1};User={2};Password={3};Option=3;",
        Server, database, Uid, Pwd)))
    {
        using (OdbcCommand cmd = new OdbcCommand(query, cn))
        {
            cn.Open();

            using (OdbcDataReader reader = cmd.ExecuteReader())
            {
                return reader.HasRows;
            }
        }
    }
}

public static DataTable CallStoredProcedure(string query, string database, OdbcParameter[] parameters)
{
    using (OdbcConnection cn = new OdbcConnection(
        string.Format("Driver={{MySQL ODBC 5.1 Driver}};Server={0};database={1};User={2};Password={3};Option=3;",
        Server, database, Uid, Pwd)))
    {
        cn.Open();
        using (OdbcCommand cmd = new OdbcCommand(query, cn))
        {
            cmd.CommandType = CommandType.StoredProcedure;

            if (parameters != null)
                cmd.Parameters.AddRange(parameters);

            OdbcDataReader rdr = cmd.ExecuteReader();

            DataTable dt = new DataTable();

            dt.Load(rdr);

            return dt;
        }
    }
}

}

【问题讨论】:

  • 我建议进行批量更新,而不是逐行更新。在某一时刻,我认为您超出了允许的最大连接数。
  • 您打开/关闭连接的代码在哪里......?您是否也在执行 UPDATE 时打开和关闭每个事务的连接是 DBServer.ExecuteQuery 您自己的方法..?
  • @DJ KRAZE 请查看我对 DBServer 类的编辑,谢谢
  • 我同意 dpp,您对数据库的往返次数太多,打开数据库连接的次数也太多..
  • 谢谢大家!你所有的cmets都有帮助!干杯!

标签: c# asp.net mysql sql


【解决方案1】:

不要实例化Command 对象,也不要在每次迭代时定义参数。您应该尝试编写如下代码:

   string query = @"UPDATE bartran SET aNumberCounter = ? WHERE id = ?;";
   string cnstr=@"Driver={{MySQL ODBC 5.1 Driver}};Server=localhost;dataBase=database_name;User=root;Password=;Option=3;";
   using(OdbcConnection connection=new OdbcConnection(cnstr))
   {
    using(OdbcCommand cmd=new OdbcCommand(query,connection))
    {
    cmd.Parameters.Add("?",OdbcType.Int);
    cmd.Parameters.Add("?",OdbcType.Int);
    connection.Open();
    for (int i = 0; i < dsData.Tables["data"].Rows.Count; i++)
     {
      ...
      cmd.Parameters[0].Value=aNumberCounter;
      cmd.Parameters[1].Value=id;
      cmd.ExecuteNonQuery();
      }
    connection.Close();
    }
   }

PS:您应该使用MySql Provider API 而不是Odbc API

【讨论】:

  • 这是一个很好的建议!我得到它!但是我得到一个错误,初始化字符串的格式不符合从索引 0 开始的规范。
  • 在我初始化 OdbcConnection 的那一行
  • 您遇到了String.Format 方法的问题。请验证方法参数和索引。
  • 现在已修复!感谢大师的帮助!你拯救了我的一天! XD
【解决方案2】:

如果我是你,我将首先在循环内准备我的查询,并在循环后执行一次。这样,您将避免在数据库上进行多次往返。我这里有一个例子,想法相同,但使用的是 VB.NET 和其他数据库类,而不是 ODBC。

Dim Command As New SqlCommand(_
        "insert into hilmarc_cem_items " & _
        "(CEMID, " & _
        "ItemCode, " & _
        "UnitPrice, " & _
        "Quantity, " & _
        "UOM) ", Connection)     


Dim ItemCodes() As String = Request.Form.GetValues("ItemCode")
Dim UnitPrices() As String = Request.Form.GetValues("UnitPrice")
Dim Quantities() As String = Request.Form.GetValues("Quantity")
Dim UOMs() As String = Request.Form.GetValues("UOM")

'Prepare query, do not execute yet!'
For Counter = 0 To ItemCodes.Length - 1
    Command.CommandText &= "select @CEMID, @ItemCode" & Counter & ", @UnitPrice" & Counter & ", @Quantity" & Counter & ", @UOM" & Counter & " "
    Command.Parameters.Add("@ItemCode" & Counter, Data.SqlDbType.NVarChar).Value = ItemCodes(Counter)
    Command.Parameters.Add("@Quantity" & Counter, Data.SqlDbType.Decimal).Value = Quantities(Counter)
    Command.Parameters.Add("@UOM" & Counter, Data.SqlDbType.NVarChar).Value = UOMs(Counter)
    Command.Parameters.Add("@UnitPrice" & Counter, Data.SqlDbType.Decimal).Value = UnitPrices(Counter)
    If Not Counter = ItemCodes.Length - 1 Then
        Command.CommandText &= "union all "
    Else
        Command.CommandText &= ";"
    End If
Next

'After the preparation, execute the query'
Connection.Open()
Command.ExecuteNonQuery()

这个想法是有一个单一的查询,从数组中获取所有数据并将它们作为参数添加到 sqlCommand 中。在循环之后,您将执行命令 ONCE。查询如下所示:

insert into myTable 
    (CEMID, 
    ItemCode,
    UnitPrice,
    Quantity, 
    UOM) 
select @CEMID, @ItemCode0, @UnitPrice0, @Quantity0, @UOM0
union all
select @CEMID, @ItemCode1, @UnitPrice1, @Quantity1, @UOM1
union all
select @CEMID, @ItemCode1, @UnitPrice1, @Quantity1, @UOM1
union all

以上代码,做批量插入,可以改成更新。

【讨论】:

  • 感谢您的想法!尽管我标记了 AVD 的答案,但这非常有帮助,因为他展示了一个例子!但是你的回答也给了我提示谢谢!
  • @JRC 不客气!实际上,如果您愿意,可以优化标记的答案,看看我的编辑,我添加了我以前的工作,虽然它不是 c# 也不是 ODBC。它会帮助你。
猜你喜欢
  • 2013-08-07
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 2011-10-16
  • 2011-09-08
  • 2014-02-09
  • 2021-03-20
相关资源
最近更新 更多