2010-08-23 17 views
18

इस SQL ​​सर्वर स्निपेट के समतुल्य PLSQL (ओरेकल) क्या है?पीएलएसक्यूएल जेडीबीसी: अंतिम पंक्ति आईडी कैसे प्राप्त करें?

BEGIN TRAN 
INSERT INTO mytable(content) VALUES ("test") -- assume there's an ID column that is autoincrement 
SELECT @@IDENTITY 
COMMIT TRAN 

सी # में, आप myCommand.ExecuteScalar() फोन नई पंक्ति की आईडी पुनः प्राप्त कर सकते हैं।

मैं ओरेकल में एक नई पंक्ति कैसे डाल सकता हूं, और जेडीबीसी को नई आईडी की एक प्रति प्राप्त हो सकती है?

संपादित करें: बलुससी ने एक बहुत अच्छा प्रारंभिक बिंदु प्रदान किया। किसी कारण से जेडीबीसी नामित पैरामीटर बाध्यकारी पसंद नहीं है। यह "गलत सेट या पंजीकृत पैरामीटर" SQLException देता है। ये क्यों हो रहा है?

 OracleConnection conn = getAppConnection(); 
     String q = "BEGIN INSERT INTO tb (id) values (claim_seq.nextval) returning id into :newId; end;" ; 
     CallableStatement cs = (OracleCallableStatement) conn.prepareCall(q); 
     cs.registerOutParameter("newId", OracleTypes.NUMBER); 
     cs.execute(); 
     int newId = cs.getInt("newId"); 
+0

आईडी फ़ील्ड + 1 के अधिकतम का चयन करें यहाँ एक टुकड़ा है? – Aren

+4

@Aren - 'max (n) + 1' स्केल नहीं करता है और बहु-उपयोगकर्ता वातावरण में काम नहीं करता है। – APC

उत्तर

33

आम तौर पर आप इस के लिए Statement#getGeneratedKeys() (यह भी देखें एक उदाहरण के लिए this answer) का प्रयोग करेंगे, लेकिन यह जहाँ तक (अभी भी) ओरेकल JDBC ड्राइवर के द्वारा समर्थित नहीं है।

String sql = "BEGIN INSERT INTO mytable(id, content) VALUES (seq_mytable.NEXTVAL(), ?) RETURNING id INTO ?; END;"; 

Connection connection = null; 
CallableStatement statement = null; 

try { 
    connection = database.getConnection(); 
    statement = connection.prepareCall(sql); 
    statement.setString(1, "test"); 
    statement.registerOutParameter(2, Types.NUMERIC); 
    statement.execute(); 
    int id = statement.getInt(2); 
    // ... 

या आग SELECT sequencename.CURRVALINSERT के बाद ही लेन-देन में:

String sql_insert = "INSERT INTO mytable(content) VALUES (?)"; 
String sql_currval = "SELECT seq_mytable.CURRVAL FROM dual"; 

Connection connection = null; 
PreparedStatement statement = null; 
Statement currvalStatement = null; 
ResultSet currvalResultSet = null; 

try { 
    connection = database.getConnection(); 
    connection.setAutoCommit(false); 
    statement = connection.prepareStatement(sql_insert); 
    statement.setString(1, "test"); 
    statement.executeUpdate(); 
    currvalStatement = connection.createStatement(); 
    currvalResultSet = currvalStatement.executeQuery(sql_currval); 
    if (currvalResultSet.next()) { 
     int id = currvalResultSet.getInt(1); 
    } 
    connection.commit(); 
    // ... 
+0

क्या आपका मतलब है "चयन CURRVAL (seq_mytable)" के बजाय "दोहरी से seq_mytable.CURRVAL चुनें"? –

+0

@ पैट्रिक: ओह ड्रैट, मेरे पास पोस्टग्रेएसक्यूएल एसक्यूएल सिंटैक्स दिमाग में था, मैं अपडेट करूंगा (पहले, पोस्टग्रेएसक्यूएल का समर्थन करने की एक ही समस्या नहीं थी ['स्टेटमेंट # getGeneratedKeys() '] (http://stackoverflow.com/ प्रश्न/1 915166/जेडीबीसी-कैसे-कर-हम-प्राप्त-सम्मिलित-रिकॉर्ड-आईडी-इन-जावा/1 915197 # 1 915197) ताकि एक ही "वर्कअराउंड" आवश्यक हो, लेकिन लगभग एक साल पहले उन्होंने अंततः अपने जेडीबीसी चालक को तय किया इसका समर्थन करने के लिए)। – BalusC

+0

हाय बलससी, मदद के लिए धन्यवाद। क्या आप मेरे संपादन को देख सकते हैं कि क्या आप उस दूसरे रहस्य को हल कर सकते हैं? – Haoest

8

आप ओरेकल के returning खंड का उपयोग कर सकते हैं।

insert into mytable(content) values ('test') returning your_id into :var; 

कोड नमूना के लिए this link देखें। आपको ओरेकल 10 जी या बाद में, और जेडीबीसी ड्राइवर का एक नया संस्करण चाहिए।

1

आप उपयोग कर सकते हैं

आपका सबसे अच्छा शर्त एक RETURNING खंड के साथ या तोCallableStatement का मेकअप उपयोग करने के लिए है getGeneratedKeys(), स्पष्ट रूप से कुंजी फ़ील्ड का चयन करके।

// change the string to your connection string 
    Connection connection = DriverManager.getConnection("connection string"); 

    // assume that the field "id" is PK, and PK-trigger exists 
    String sql = "insert into my_table(id) values (default)"; 
    // you can select key field by field index 
    int[] colIdxes = { 1 }; 
    // or by field name 
    String[] colNames = { "id" }; 

    // Java 1.7 syntax; try-finally for older versions 
    try (PreparedStatement preparedStatement = connection.prepareStatement(sql, colNames)) 
    { 
     // note: oracle JDBC driver do not support auto-generated key feature with batch update 
     //   // insert 5 rows 
     //   for (int i = 0; i < 5; i++) 
     //   { 
     //    preparedStatement.addBatch(); 
     //   } 
     //   
     //   int[] batch = preparedStatement.executeBatch(); 
     preparedStatement.executeUpdate(); 

     // get generated keys 
     try (ResultSet resultSet = preparedStatement.getGeneratedKeys()) 
     { 
      while (resultSet.next()) 
      { 
       // assume that the key's type is BIGINT 
       long id = resultSet.getLong(1); 
       assertTrue(id != 0); 

       System.out.println(id); 
      } 
     } 
    } 

जानकारी के लिए देखें:: http://docs.oracle.com/cd/E16655_01/java.121/e17657/jdbcvers.htm#CHDEGDHJ

+1

यह तब तक काम करता है जब तक सम्मिलन कथन 7 पैरामीटर तक होता है, जब 7 से अधिक पैरामीटर होते हैं तो ArrayIndexOutofBound अपवाद फेंक दिया जाता है। ओरेकल jdbc ड्राइवर के साथ एक गलती की तरह लग रहा है। # Oracle_11g_R2। इस कारण से बलुससी से उत्तर बेहतर है। –

संबंधित मुद्दे