MySql и вставка последней проблемы ID остается - PullRequest
1 голос
/ 04 апреля 2011

Хорошо, после долгих чтений и попыток я все еще не могу заставить это работать:

      OdbcCommand cmd = new OdbcCommand("INSERT INTO User (Email) VALUES ('rusty@msn.com'); 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

РЕДАКТИРОВАТЬ: Метод Джастина:

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

Ответы [ 3 ]

4 голосов
/ 04 апреля 2011

Пояснение: драйвер 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 голосов
/ 05 апреля 2011

Обходной путь:

  1. Добавьте параметр out к вашему запросу:
  2. внутри запроса используйте SET @OpParam = SELECT LAST_INSERT_ID ();
  3. В вашем коде получите его как будто ((int) @ OpParam.Value> 0) {вытащить}.
  4. Кроме того, если выбрано run, то вместо NonQuery используйте ExecuteScalar ().

Надеюсь, это поможет вам.

0 голосов
/ 04 апреля 2011

Если ваша электронная почта уникальна, вы можете использовать

Select ID From User where Email='rusty@msn.com'

Вы уверены, что всегда получаете правильный ответ.

Если ваша электронная почта не уникальна, вы должны использовать блокировку, чтобы убедиться, что только в потоке выполняется запрос, а затем использовать этот запрос после вставки

Select Max(ID) From User
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...