2012-03-30 39 views
9

Scenerio:MySQL Làm cách nào để truy xuất ID của LAST_INSERT_ID khi sử dụng INSERT IGNORE INTO?

  1. Tôi đang chèn tệp CSV vào cơ sở dữ liệu của mình.
  2. Tôi đang sử dụng trình điều khiển JDBC để lặp qua các tập tin và thực hiện chèn của tôi
  3. Một cột name được làm unique để chèn không thay đổi bảng khi cùng giá trị đến
  4. Tôi đang sử dụng INSERT INTO IGNORE để giữ lặp từ phá vỡ khi sự kiện xảy ra
  5. tôi đang sử dụng LAST_INSERT_ID() để thêm như FK trong bảng tiếp theo của chèn
  6. tôi nhận được 0 khi INSERT_IGNORE xảy ra

Làm cách nào để khắc phục sự cố này?

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

Ví dụ về tập tin CSV để được chèn vào cơ sở dữ liệu

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

Bàn: http://sqlfiddle.com/#!2/b5752

+0

Wha t là vấn đề bạn đang cố khắc phục? Nếu bạn đang làm "INSERT IGNORE" và bỏ qua xảy ra, không có một chèn để không có một Last_insert_id cho giao dịch đó. Nếu bạn muốn id chèn cuối cùng trước đó, bạn cần chụp nó ngay sau khi chèn. Nhưng đối với nỗ lực chèn gần đây nhất, nếu nó không xảy ra, last_insert_id sẽ là 0. –

+0

@DMac thì làm thế nào để tôi chèn một chèn vào cơ sở dữ liệu khi bạn không muốn thay thế cột hiện tại khi nó đã tồn tại? – stackoverflow

+0

@stackoverflow Tôi đã đăng một câu trả lời dưới đây phù hợp với mysql. –

Trả lời

2

Nếu bạn muốn nhận được một ID cho một chèn tiếp theo, mã của bạn phải thử nghiệm cho một giá trị 0 của LAST_INSERT_ID và nếu nó nhận được nó, làm một SELECT trên bảng để tìm giá trị phù hợp cho FK cho chèn của bạn.

Trong pseudo-code, điều này sẽ trông giống như:

$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)") 

Bạn sẽ phải dịch đó để ứng dụng và ngôn ngữ của riêng bạn.

+0

heres cấu trúc bảng của tôi http://sqlfiddle.com/#!2/b5752 và tôi sẽ cung cấp một ví dụ về tệp csv trong chỉnh sửa ở trên – stackoverflow

5

Bạn có quen thuộc với cú pháp của ON DUPLICATE KEY UPDATE của MySQL không?

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)"); 

Một ví dụ thiết thực ở đây liên quan đến việc duy trì các địa chỉ email không cho một trang web:

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

Như để lấy id chèn vào cuối những điều sau đây được lấy từ mysql .com liên kết ở trên:

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

Đây phải là câu trả lời được chấp nhận chắc chắn. Hoạt động hoàn hảo và tiết kiệm rất nhiều logic yêu cầu khác, ví dụ như được cung cấp trong câu trả lời được chấp nhận. – teh1

Các vấn đề liên quan