2011-04-04 54 views
1

确定后,大量的阅读,并试图我仍然不能似乎得到这个工作:MySQL和插入最后一个ID问题仍然

 OdbcCommand cmd = new OdbcCommand("INSERT INTO User (Email) VALUES ('[email protected]'); SELECT LAST_INSERT_ID();", cn); 

cmd.ExecuteNonQuery(); 
       using (OdbcDataReader reader = cmd.ExecuteReader()) 
       { 

       string theUserId = String.Format("{0}", reader.GetString(0)); 
       Label10.Text = theUserId; 

表:

User 
-------- 
UserID (auto increment, pk) 
Email 

运行在调试模式下我上得到错误这条线,

  using (OdbcDataReader reader = cmd.ExecuteReader()) 

,并

cmd.ExecuteNonQuery(); 

Mysql在这一行上说它的语法错误SELECT LAST_INSERT_ID();",cn);但从什么是阅读这是合法的。

确切的错误:

ERROR [42000] [MySQL][ODBC 3.51 Driver][mysqld-5.5.9]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 'SELECT LAST_INSERT_ID()' at line 1 

编辑:Justins方法:

using (OdbcConnection connection = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=root; Password=commando;")) 
{ 
    // ODBC command and transaction objects 
    OdbcCommand command = new OdbcCommand(); 
    OdbcTransaction transaction = null; 

    // tell the command to use our connection 
    command.Connection = connection; 

    try 
    { 
     // open the connection 
     connection.Open(); 

     // start the transaction 
     transaction = connection.BeginTransaction(); 

     // Assign transaction object for a pending local transaction. 
     command.Connection = connection; 
     command.Transaction = transaction; 

     // TODO: Build a SQL INSERT statement 
     OdbcCommand cmd = new OdbcCommand("INSERT INTO User (Email, FirstName, SecondName, DOB, Location, Aboutme, username, password) VALUES ('" + TextBox1.Text + "', '" + TextBox2.Text + "', '" + TextBox3.Text + "', '" + TextBox4.Text + "', '" + TextBox5.Text + "', '" + TextBox6.Text + "', '" + TextBox7.Text + "', '" + TextBox8.Text + "')", connection); 

     // run the insert using a non query call 
     command.CommandText = cmd.ToString(); 
     command.ExecuteNonQuery(); 

     /* now we want to make a second call to MYSQL to get the new index 
      value it created for the primary key. This is called using scalar so it will 
      return the value of the SQL statement. We convert that to an int for later use.*/ 
     command.CommandText = "select last_insert_id();"; 
     id = Convert.ToInt32(command.ExecuteScalar()); 

     // the name id doesnt not exist in the current context 

     // Commit the transaction. 
     transaction.Commit(); 
    } 
    catch (Exception ex) 
    { 
     Label10.Text = ": " + ex.Message; 

     try 
     { 
      // Attempt to roll back the transaction. 
      transaction.Rollback(); 
     } 
     catch 
     { 
      // Do nothing here; transaction is not active. 
     } 
    } 
} 
+1

您是否允许在1'OdbcCommand'中执行2个查询/语句?如果你在两个单独的项目中完成,会发生什么? – Wrikken 2011-04-04 19:05:06

+0

@Wrikken,就是这个问题.net mySQL ODBC驱动程序不允许在该上下文中使用多个命令。你必须拨打两个不同的电话。我之前遇到过这个问题;) – Justin 2011-04-04 19:24:49

+0

尝试使用字符串,而不是使用字符串和连接参数创建另一个OdbcCommand对象。然后将command.CommandText设置为该String。我想在创建第二个OdbcCommand对象时会发生一些奇怪的事情。 – Justin 2011-04-05 15:32:25

回答

4

澄清,MySQL的.NET ODBC驱动程序不允许多个命令,就像你所描述的运行。您必须进行两个独立的呼叫并将其包装在交易中。

// open a new connection using a default connection string I have defined elsewhere 
using(OdbcConnection connection = new OdbcConnection(s_connectionString)) 
{ 
     // ODBC command and transaction objects 
     OdbcCommand command = new OdbcCommand(); 
     OdbcTransaction transaction = null; 

     // tell the command to use our connection 
     command.Connection = connection; 

     try 
     { 
      // open the connection 
      connection.Open(); 

      // start the transaction 
      transaction = connection.BeginTransaction(); 

      // Assign transaction object for a pending local transaction. 
      command.Connection = connection; 
      command.Transaction = transaction; 

      // TODO: Build a SQL INSERT statement 
      StringBuilder SQL = new StringBuilder(); 

      // run the insert using a non query call 
      command.CommandText = SQL.ToString(); 
      command.ExecuteNonQuery(); 

      /* now we want to make a second call to MYSQL to get the new index 
       value it created for the primary key. This is called using scalar so it will 
       return the value of the SQL statement. We convert that to an int for later use.*/ 
      command.CommandText = "select last_insert_id();"; 
      id = Convert.ToInt32(command.ExecuteScalar()); 

      // Commit the transaction. 
      transaction.Commit(); 
    } 
    catch(Exception ex) 
    { 
      Debug.WriteLine(ex.Message); 

      try 
      { 
       // Attempt to roll back the transaction. 
       transaction.Rollback(); 
      } 
      catch 
      { 
       // Do nothing here; transaction is not active. 
       } 
     } 
} 
+0

我收到一个错误:错误[42000] [MySQL] [ODBC 3.51驱动程序] [mysqld-5.5.9]你的SQL语法错误;查看与您的MySQL服务器版本相对应的手册,以找到在“System.Data.Odbc”附近使用的正确语法。OdbcCommand'在行1 – 2011-04-04 20:58:53

0

如果你的电子邮件是唯一可以使用

Select ID From User where Email='[email protected]' 

你确信你总是得到正确的答案。

如果你的电子邮件是不是唯一的,你应该使用锁,以确保只有线程执行查询,然后将您的插入后,使用此查询

Select Max(ID) From User 
+0

ahh对不起,电子邮件只是一个例子我不知道电子邮件直到它插入到数据库因此,为什么我需要上次交易 – 2011-04-04 19:28:02

0

一种解决方法:

  1. 添加out param to your query:
  2. 查询内部使用SET @OpParam = SELECT LAST_INSERT_ID();
  3. 在你的代码中,如果((int)@ OpParam.Value> 0){pull out}。
  4. 此外,如果运行选择,则改为NonQuery,使用ExecuteScalar()。

希望它可以帮助你。

+0

executablecalar用于选择。尝试设置出参数仍然没有喜悦 – 2011-04-05 19:18:54

+0

如果您需要检索第一个单元格的值,您还可以使用插入,更新删除或多个语句 – 2011-04-06 09:40:20

+0

如果您要返回标识并在代码上需要它,则需要ExecuteScalar ,而不是NonQuery,因为Non Query将为您提供受查询影响的行数。 – 2011-04-06 09:41:31