简体   繁体   中英

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

  1. I am having a problem with my C# code, I put the query in C# code it returns the error as below:
Additional information: 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 ':= (0 + 1) as numA, ID, UID, File, StartDate, EndDate FROM OEE_PROD.thermalValue' at line 1.
  1. I run the query in MySql database it work and can get the data.

  2. This is my code:

public void exportCSVBtn_Click(object sender, EventArgs e)
{
    string conn = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (MySqlConnection con = new MySqlConnection(conn))
    {
        string a = (string)Session["Userid"];
        using (MySqlCommand cmd = new MySqlCommand("select A.*, timediff(B.StartDate, A.EndDate) from (select @rownumA:= (@rownumA + 1) as numA, ID, UID, File, StartDate, EndDate FROM OEE_PROD.thermalValue where File = '" + ddrKdf.SelectedItem.Text + "'AND UserID='" + a + "' order by ID) A LEFT JOIN(select @rownumB:= (@rownumB + 1) as numB, ID as BID, StartDate, EndDate FROM OEE_PROD.thermalValue where File = '" + ddrKdf.SelectedItem.Text + "'AND UserID='" + a + "'order by ID) B ON B.numB = (A.numA + 1)"))
        {
            using (MySqlDataAdapter sda = new MySqlDataAdapter())
            {
                cmd.Connection = con;
                sda.SelectCommand = cmd;
                    
                cmd.Parameters.AddWithValue("@rownumB", 0);
                cmd.Parameters.AddWithValue("@rownumA", 0);
                    
                using (DataTable dt = new DataTable())
                {  
                    sda.Fill(dt);
                        
                    //Build the CSV file data as a Comma separated string.
                    string csv = string.Empty;
                        
                    foreach (DataColumn column in dt.Columns)
                    {
                        //Add the Header row for CSV file.
                        csv += column.ColumnName + ',';
                    }
                        
                        //Add new line.
                        csv += "\r\n";
                        
                        foreach (DataRow row in dt.Rows)
                        {
                            foreach (DataColumn column in dt.Columns)
                            {
                                //Add the Data rows.
                                csv += row[column.ColumnName].ToString().Replace(",", ";") + ',';
                            }
                        
                            //Add new line.
                            csv += "\r\n";
                        }
                    
                    //Download the CSV file.
                    Response.Clear();
                    Response.Buffer = true;
                    Response.AddHeader("content-disposition", "attachment;filename=KDFExport_" + DateTime.Now + ".csv");
                    Response.Charset = "";
                    Response.ContentType = "application/text";
                    Response.Output.Write(csv);
                    Response.Flush();
                    Response.End();
                }
            }
        }
    }
}

The error message is caused by you treating @rownumA and @rownumB mysql user defined variables as a C# query parameter and provide 0 as its value with the following lines:

cmd.Parameters.AddWithValue("@rownumB", 0);
cmd.Parameters.AddWithValue("@rownumA", 0);

This means that @rownumA:= (@rownumA + 1) mysql expression becomes 0:= (0 + 1) , which is obviously not correct.

If you want to use sql user defined variables, then add the following parameter to the connection string of your.Net connector connection:

Allow User Variables=True

or

AllowUserVariables=True

This option was added to connector v5.2.2

This way you can remove the parameter assignment lines from your C# code and the mysql variables do not get substituted.

However, the file and userid field values in the where clause indeed should be supplied via parameters and not through string concatenation!

Let's structure this an alternative way: run the two queries separately, download their data in order, then write the CSV using both results. This in contrast to getting mysql to join the data on a fake number created by row order.

using (MySqlDataAdapter daA = new MySqlDataAdapter ("
  SELECT ID, UID, File, StartDate, EndDate
  FROM OEE_PROD.thermalValue 
  WHERE File = @file
  ORDER BY ID", connstr
))
using (MySqlDataAdapter daB = new MySqlDataAdapter ("
  SELECT StartDate 
  FROM OEE_PROD.thermalValue 
  WHERE File = @file AND UserID = @userID 
  ORDER BY ID", connstr
))
{
  DataTable dtA = new DataTable();
  DataTable dtB = new DataTable();

  daA.SelectCommand.Parameters.AddWithValue("@file", ddrKdf.SelectedItem.Text);
  daB.SelectCommand.Parameters.AddWithValue("@file", ddrKdf.SelectedItem.Text);
  daB.SelectCommand.Parameters.AddWithValue("@userID", a);

  
  daA.Fill(dtA);
  daB.Fill(dtB);

  for(int i = 0; i < dtA.Rows.Count; i++)
  {
    string csvTimeDiffCol = "";

    if(i+1 < dtB.Rows.Count){

      DateTime st = (DateTime)dtA.Rows[i]["StartDate"];
      DateTime ed = (DateTime)dtB.Rows[i+1]["EndDate"];

      //now you can choose how do you want to represent this timespan?
      csvTimeDiffCol = (ed - st).ToString();

    }

    //now write the row to CSV, including the csvTimeDiffCol string
  }
}

Notes:

  • I've effectively rewritten your code here from what I could guess at your algorithm from what I saw in your code: "get db to prepare a superset and a subset of records, ordered by their ID, join them together on row position with an off-by-one offset" - I personally think this is wonky but I can't fault the logic because it's not mine
  • We download the two result sets then step over them in order, taking relevant rows
  • I've no idea what your timediff or dates looks like; I've assumed that they're Dates and you're looking for the difference in hours minutes etc between them, hence I cast them to DateTime in the c# and then used xy to turn them into a TimeSpan; you'll probably need to format this
  • I haven't written your csv code in, because that part is unchanged. There are libraries to help with that though; you don't need to roll your own

This algorithm may not be perfect/may need debugging. I don't present it as a "paste this and I did your work for you" - I'm presenting it as something to get you to think about the problem another way

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