首页 > 解决方案 > C# 中的 MySQL 错误 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册以获取正确的语法

问题描述

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在附近使用的正确语法

我尝试在 C# 中同时使用两个 SQLDataReader。但是有一个错误。行中的错误:

 MySqlDataReader dr3 = cmdd3.ExecuteReader();
 MySqlDataReader dr4 = cmdd4.ExecuteReader();

编码:

MySqlConnection con1 = new MySqlConnection("Data Source =123.456.78.910; user id = root; password=12345;persistsecurityinfo=True; database=trydata");

con1.Open();

MySqlCommand cmdd3 = new MySqlCommand("Select Count(Distinct(SN) from uat.station where StationNumber = @Station and Status = @status and Date_Time between @DateFrom and @DateTo)", con1);

MySqlCommand cmdd4 = new MySqlCommand("Select Count(Distinct(SN) from uat.station where StationNumber = @Station and Status = @status and Date_Time between @DateFrom and @DateTo)", con1);

for (int i = 0; i < 11; i++) //for loop to run query simultaneously 11times and store data in array
{
     if (i == 0)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 1");
      cmdd4.Parameters.AddWithValue("@Station", "Station 1");
     }
     else if (i == 1)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 2");
      cmdd4.Parameters.AddWithValue("@Station", "Station 2");
     }
     else if (i == 2)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 3");
      cmdd4.Parameters.AddWithValue("@Station", "Station 3");
     }
     else if (i == 3)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 4");
      cmdd4.Parameters.AddWithValue("@Station", "Station 4");
     }
     else if (i == 4)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 5");
      cmdd4.Parameters.AddWithValue("@Station", "Station 5");
     }
     else if (i == 5)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 6");
      cmdd4.Parameters.AddWithValue("@Station", "Station 6");
     }
     else if (i == 6)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 7");
      cmdd4.Parameters.AddWithValue("@Station", "Station 7");
     }
     else if (i == 7)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 8");
      cmdd4.Parameters.AddWithValue("@Station", "Station 8");
     }
     else if (i == 8)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 9");
      cmdd4.Parameters.AddWithValue("@Station", "Station 9");
     }
     else if (i == 9)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 10");
      cmdd4.Parameters.AddWithValue("@Station", "Station 10");
     }
     else if (i == 10)
     {
      cmdd3.Parameters.AddWithValue("@Station", "Station 11");
      cmdd4.Parameters.AddWithValue("@Station", "Station 11");
     }

    cmdd3.Parameters.AddWithValue("@status", "PASS");
    cmdd3.Parameters.AddWithValue("@workorder", TextBox3.Text);
    cmdd3.Parameters.AddWithValue("@DateFrom", dateTimeFrom);
    cmdd3.Parameters.AddWithValue("@DateTo", dateTimeTo);
                    
    cmdd4.Parameters.AddWithValue("@status", "FAIL");
    cmdd4.Parameters.AddWithValue("@workorder", TextBox3.Text);
    cmdd4.Parameters.AddWithValue("@DateFrom", dateTimeFrom);
    cmdd4.Parameters.AddWithValue("@DateTo", dateTimeTo);

    MySqlDataReader dr3 = cmdd3.ExecuteReader();
    MySqlDataReader dr4 = cmdd4.ExecuteReader();
    if (dr3.HasRows && dr4.HasRows)
      {
       while (dr3.Read() && dr4.Read())
       {
         string firstColum = (i + 1).ToString();
         string secondColum = stationName[i]; //pass stations name
         string thirdColum = dr3.GetValue(0).ToString(); //pass data SN PASS to thirdColum
         string fourthColum = dr4.GetValue(0).ToString(); //pass data SN FAIL to fourthColum
         string fifthColum = (Convert.ToInt32(thirdColum) + Convert.ToInt32(fourthColum)).ToString(); //count the total of PASS & FAIL
         string sixthColum = ((Convert.ToInt32(thirdColum) / Convert.ToInt32(fifthColum)) * 100).ToString("F"); //Calculate yield of PASS (pass/total)*100 ..

         DataTable dtable = new DataTable();
         dtable.Columns.Add(new DataColumn("No."));
         dtable.Columns.Add(new DataColumn("Station Name"));
         dtable.Columns.Add(new DataColumn("Pass SN"));
         dtable.Columns.Add(new DataColumn("Fail SN"));
         dtable.Columns.Add(new DataColumn("Total"));
         dtable.Columns.Add(new DataColumn("Yield Pass"));

         RowValues[0] = firstColum;
         RowValues[1] = secondColum;
         RowValues[2] = thirdColum;
         RowValues[3] = fourthColum;
         RowValues[4] = fifthColum;
         RowValues[5] = sixthColum;

         DataRow dRow;
         dRow = dtable.Rows.Add(RowValues);
         dtable.AcceptChanges();
 
         dataGridView1.DataSource = dtable;
         dataGridView1.DataBind();

         con1.Close();
         }
}

这是否意味着我不能将两个 SQLDataReader 与 1 个连接字符串一起使用?我确实尝试在 web.config 中设置 MultipleActiveResultSets=true 但仍然错误保持不变。

错误图片:

错误图像

标签: c#mysqlasp.net

解决方案


1.0 问题

您的查询错误地关闭了括号COUNT()

Select Count(Distinct(SN) from uat.station where StationNumber = @Station and Status = @status and Date_Time between @DateFrom and @DateTo)

1.1 解决方案:修复不正确的语法COUNT()

Select Count(Distinct(SN)) from uat.station where StationNumber = @Station and Status = @status and Date_Time between @DateFrom and @DateTo

2.0 关注

2.1 关注点:在 COUNT() 中应用 DISTINCT 可能会导致计算错误

假设它SN是表中的列uat.station,计算查询记录中出现的记录数,您不需要DISTINCT在查询中使用。

清楚的

从结果集中删除列中的重复值

当SN 列 IS NOT UNIQUE时,应用DISTINCT(SN)inCOUNT可能会导致计算错误。

COUNT(DISTINCT(SN))

如果 SN 列不是唯一的:对于非重复的 SN 值记录,返回 COUNT = M

如果 SN 列是唯一的:为所有记录返回 COUNT = N

COUNT(SN)

为所有记录返回 COUNT = N

2.1 解决方案:DISTINCT()从查询中删除

SELECT StationNumber,
    Count(SN) 
FROM uat.station 
WHERE StationNumber = @Station 
  AND Status = @status 
  AND Date_Time between @DateFrom and @DateTo

2.2 关注点:是否需要通过循环将值传递给@Station?而且WHERE StationNumber = @Station不正确

循环添加值@Station可能会导致结果输出不正确。此外,在比较多个值@Station时应使用 in WHERE 部分。IN

2.2.1(第一个可选)解决方案:如果尝试查询所有站并应用,请删除@Station 参数GROUP BY

SELECT StationNumber,
    Count(StationNumber) 
FROM uat.station 
WHERE Status = @status 
  AND Date_Time between @DateFrom and @DateTo
GROUP BY StationNumber

2.2.2(第二个可选)解决方案: USE比较params (needed) & applyIN的每个值。[不推荐,但取决于需要]@StationGROUP BY

SELECT StationNumber,
    Count(StationNumber) 
FROM uat.station 
WHERE StationNumber IN @StationNumber
  AND Status = @status 
  AND Date_Time between @DateFrom and @DateTo
GROUP BY StationNumber

3.0 建议

3.1将cmdd3&合并cmdd4为1个查询进行计算

两个cmd3&cmd4查询可以合并为 1 个查询,因为两个MySqlCommand&MySqlDataReader与不同的 共享相同的查询@Status

注意:我使用 2.2.1 解决方案来扩展 3.1 推荐

SELECT
    StationNumber
    , PassCount
    , FailCount
    , TotalCount
    , CAST((PassCount * 100 / TotalCount) AS DECIMAL(5,2)) AS PassPercentage
FROM 
(
    SELECT 
        StationNumber,
        SUM(CASE WHEN [Status] = 'PASS' THEN 1 ELSE 0 END) AS PassCount,
        SUM(CASE WHEN [Status] = 'FAIL' THEN 1 ELSE 0 END) AS FailCount,
        COUNT([Status]) AS TotalCount
    FROM uat.station
    WHERE Date_Time between @DateFrom and @DateTo
    GROUP BY StationNumber
) a

3.2 停止使用AddWithValue()

使用AddWithValue()可能会导致您的命令参数和表列的数据类型不匹配。相反,您需要将命令参数中的确切数据类型作为相应的数据库表列传递。

cmdd3.Parameters.Add("@Station", SqlDbType.NVarchar, 50).Value = "Station 1";
cmdd3.Parameters.Add("@Status", SqlDbType.Varchar, 10).Value = "PASS";  

参考:我们可以停止使用 AddWithValue() 了吗?


3.3 使用块/声明为MySqlConnection, MySqlCommand&应用MySqlDataReader

一旦进程结束或触发异常,这些(使用 IDisposable 接口实现)将自动释放资源。

使用语句

using (MySqlConnection con1 = new MySqlConnection(/* Connection string */))
{
    con1.Open();
    using (MySqlCommand cmd = new MySqlCommand(/* query */, con1))
    {
        // Add Parameter

        using (MySqlDataReader dr = cmd.ExecuteReader())
        {
             // Retrieve value from Data Reader
        }
    }
}

使用 C#8.0 的声明

using MySqlConnection con1 = new MySqlConnection(/* Connection string */);
con1.Open();

using MySqlCommand cmd = new MySqlCommand(/* query */, con1);
// Add Parameter

using MySqlDataReader dr = cmd.ExecuteReader();
// Retrieve value from Data Reader

推荐阅读