MySQL Как мне получить идентификатор LAST_INSERT_ID при использовании INSERT IGNORE INTO? - PullRequest
9 голосов
/ 30 марта 2012

Scenerio:

  1. Я вставляю файл CSV в свою базу данных.
  2. Я использую драйвер jdbc для итерации по файлу и выполняю мои вставки
  3. A name столбец сделан unique, поэтому вставки не изменяют таблицу, когда приходит то же значение
  4. Я использую INSERT INTO IGNORE, чтобы не допустить прерывания итерации при возникновении события
  5. Я использую LAST_INSERT_ID () для добавления в качестве FK в следующую таблицу вставки
  6. Iполучить 0, когда INSERT_IGNORE произойдет

Как мне это исправить?

 Connection con = null;

    try
    {
      Class.forName("com.mysql.jdbc.Driver");
      con = DriverManager.getConnection(URL, USERNAME, PASSWORD);
      con.setAutoCommit(false);

      Statement s1 = (Statement) con.createStatement();
      s1.executeUpdate("INSERT IGNORE INTO ORIGIN (ORI_NAME) VALUES(\""
          + d.getOriginName() + "\")");

      Statement s2 = (Statement) con.createStatement();
      s2.executeUpdate("INSERT IGNORE INTO STOCK (ORI_ID,S_TITLE) VALUES ("
          + "(SELECT ORI_ID FROM ORIGIN WHERE ORI_ID =LAST_INSERT_ID()),\""
          + d.getStockTitle() + "\")");

     }

      con.commit();

    }
    catch (Exception e)
    {
      if (con != null)
        try
        {
          con.rollback();
        }
        catch (SQLException e1)
        {
          e1.printStackTrace();
        }

      e.printStackTrace();
    }
    finally
    {
      if (con != null)
        try
        {
          con.close();
        }
        catch (SQLException e)
        {
          e.printStackTrace();
        }
    }

Пример файла CSV, который нужно вставить вбаза данных

US, P1, M, 200, 344
US, P1, L, 233, 344
US, P2, M, 444, 556
MX, Q4, L, 656, 777

Таблицы: http://sqlfiddle.com/#!2/b5752

Ответы [ 2 ]

5 голосов
/ 13 мая 2012

Вы знакомы с синтаксисом ON DUPLICATE KEY UPDATE MySQL?

http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

 // Results are the same as doing an update.
 // Note the way the PK can be used to avoid an IGNORE.
 s1.executeUpdate("INSERT INTO ORIGIN (ORI_NAME) VALUES(\""
          + d.getOriginName() + "\" ON DUPLICATE KEY UPDATE ORI_ID=ORI_ID)");

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

http://blog.developpez.com/james-poulson/p10016/sql/ne-rien-modifier-en-cas-de-duplicate-key/

Что касается извлечения последнего вставленного идентификатора, то по приведенной выше ссылке на mysql.com взято следующее:

Suppose that id is the AUTO_INCREMENT column. To make LAST_INSERT_ID() meaningful for updates, insert rows as follows:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
2 голосов
/ 30 марта 2012

Если вы хотите получить идентификатор для последующей вставки, ваш код должен проверить значение LAST_INSERT_ID, равное 0, и, если он его получит, выполните SELECT для таблицы, чтобы найти правильное значение для FK для вашей вставки.

В псевдокоде это будет выглядеть так:

$err = mysql("insert ignore into mytable values ($x, $y)")
if($err){
    do something for an error
}
$id = mysql("select last_insert_id()");
if($id == 0){
    $id = mysql("select id from othertable where condition is true for the record I want to reference in my insert");
    if($id == 0){
        do something for error
    }
}
mysql("insert into othertable VALUES ($id, other stuff)")

Вам нужно будет перевести это на собственное приложение и язык.

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