简体   繁体   中英

MySQL Error In C# - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near

I try to use two SQLDataReader at the same time in C#. But there is an error. The error in line:

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

The code:

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

Is it means I cannot use two SQLDataReader together with 1 connection string? I did try set MultipleActiveResultSets=true in web.config aslo but still error remained the same.

Error Image:

错误图像

1.0 ISSUE(S)

Your query was close the bracket wrongly for COUNT()

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

1.1 Solution: Fix incorrect syntax for COUNT()

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

2.0 CONCERN(S)

2.1 Concern: Apply DISTINCT in COUNT() might lead to miscalculation

Assume that SN is the column in uat.station table, to calculate the number of records that appeared in the queried records, you don't need to use DISTINCT in your query.

DISTINCT

removes the duplicate values in the column from the result set

Applying DISTINCT(SN) in COUNT may possibly lead to miscalculation when SN column IS NOT UNIQUE .

COUNT(DISTINCT(SN))

If SN column IS NOT UNIQUE : Return COUNT = M for non-duplicate SN value record(s)

If SN column IS UNIQUE : Return COUNT = N for ALL record(s)

COUNT(SN)

Return COUNT = N for ALL record(s)

2.1 Solution: Remove DISTINCT() from query

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

2.2 Concern: Is it necessary to pass the value into @Station with the loop? And WHERE StationNumber = @Station is not correct

Loop to add the value into @Station might lead your result output incorrect. Further your @Station in WHERE part should use IN when comparing multiple values.

2.2.1 (1st Optional) Solution: Remove @Station params if try to query all Stations & apply 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 (2nd Optional) Solution: USE IN to compare each value for @Station params (needed) & apply GROUP BY . [Not recommended but depends on needs]

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 RECOMMENDATIONS

3.1 Combine cmdd3 & cmdd4 into 1 query for calculation

Both cmd3 & cmd4 queries can be combined into 1 query, as both MySqlCommand & MySqlDataReader are sharing the same query with different @Status .

Note: I use 2.2.1 solution for extending 3.1 recommendation

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 Stop Using AddWithValue()

Using AddWithValue() may possibly lead to datatypes mismatched for your Command Parameter(s) and Table column(s). Instead, you need to pass the exact datatype in your Command Parameter as the respective database table column.

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

Reference: Can we stop using AddWithValue() already?


3.3 Apply using block/declaration for MySqlConnection , MySqlCommand & MySqlDataReader

These (implemented with IDisposable interface) will automatically dispose the resources once the process is ended or an exception is triggered.

Using statement

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
        }
    }
}

Using declaration for 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM