2008-10-27 16 views
49

क्या अंतिम डाली गई पंक्ति से मूल्य प्राप्त करने का कोई तरीका है?अंतिम डाली गई पंक्ति से मूल्य कैसे प्राप्त करें?

मैं एक पंक्ति डाल रहा हूं जहां पीके स्वचालित रूप से बढ़ेगा, और मैं यह पीके प्राप्त करना चाहता हूं। केवल पीके तालिका में अद्वितीय होने की गारंटी है।

मैं जावा का उपयोग जेडीबीसी और पोस्टग्रेएसक्यूएल के साथ कर रहा हूं।

+0

मैं जेडीबीसी 4 का उपयोग कर रहा हूं, इसलिए स्टेटमेंट.RETURN_GENERATED_KEYS काम नहीं किया। मुझे यह त्रुटि संदेश मिला है: "org.postgresql.util.PSQLException: स्वत: जेनरेट की गई कुंजी लौटाना समर्थित नहीं है।" लेकिन PostgresSQL - वापसी काम किया था। – eflles

उत्तर

49
PostgreSQL के साथ

तुम लौट कीवर्ड के माध्यम से यह कर सकते हैं:

PostgresSQL - RETURNING

INSERT INTO mytable(field_1, field_2,...) 
VALUES (value_1, value_2) RETURNING anyfield 

यह वापस आ जाएगी "anyfield" का मूल्य। "कोई भी क्षेत्र" अनुक्रम हो सकता है या नहीं।

JDBC के साथ उपयोग करने के लिए

, कार्य करें:

ResultSet rs = statement.executeQuery("INSERT ... RETURNING ID"); 
rs.next(); 
rs.getInt(1); 
+0

अपने पीके का नाम आईडी मानते हुए "आईडी" रिटर्निंग का उपयोग करें। – JVerstry

+5

यह निश्चित रूप से सही SQL विधि है, लेकिन सवाल पूछा गया कि जेडीबीसी के साथ ऐसा कैसे करें, और समस्या का दूसरा भाग यह है कि कथन को कैसे कार्यान्वित किया जाए। जैसा कि अन्य उत्तरों में उल्लिखित है, आपको या तो 'executeQuery()' (निष्पादित पंक्तियों की रिटर्न संख्या) की बजाय 'executeQuery() '(परिणाम परिणाम देता है) का उपयोग करने की आवश्यकता है, या' RETURN_GENERATED_KEYS' विकल्प 'को कॉल करने की क्षमता को सक्रिय करने के लिए' 'executeUpdate()' को कॉल करने के बाद getGeneratedKeys() 'विधि। – beldaz

8

पोस्टग्रेस्क्ल में अनुक्रम लेनदेन सुरक्षित हैं। तो तुम सबसे हाल ही में इस क्रम वर्तमान सत्र में के लिए nextval द्वारा प्राप्त

currval(sequence) 

Quote:

currval

वापसी मान का उपयोग कर सकते हैं। ऐसा इसलिए है क्योंकि इस सत्र-स्थानीय मूल्य लौटने है, यह एक उम्मीद के मुताबिक जवाब भले ही अन्य सत्र nextval को क्रियान्वित कर रहे हैं देता है (कोई त्रुटि सूचना दी अगर nextval इस दृश्य के लिए कहा जाता है इस सत्र में कभी नहीं रहा है।) सूचना इस दौरान। आईडी कॉलम के लिए postgres में

+0

क्या यह संभव नहीं है कि कोई अन्य लेनदेन उसके आईएनएसईआरटी और उसके चयन currval() के बीच अनुक्रम के मूल्य को बदल सकता है? मुझे लगता है कि उनमें से प्रत्येक ऑपरेशन अलग-अलग लेन-देन में होगा। –

+3

नहीं कि वास्तव में currval फ़ंक्शन क्या है। – svrist

1

दृश्यों का उपयोग करें:

INSERT mytable(myid) VALUES (nextval('MySequence')); 

SELECT currval('MySequence'); 

currval एक ही सत्र में अनुक्रम के वर्तमान मूल्य वापस आ जाएगी।

(एमएस एसक्यूएल में, आप @@ पहचान या SCOPE_IDENTITY() का प्रयोग करेंगे)

28

java.sql.Statement के लिए एपीआई डॉक्स देखें।

मूल रूप से, जब आप executeUpdate() या executeQuery() फोन, Statement.RETURN_GENERATED_KEYS निरंतर का उपयोग करें। इसके बाद आप उस निष्पादन द्वारा बनाई गई सभी पंक्तियों की स्वत: जेनरेट की गई कुंजी प्राप्त करने के लिए getGeneratedKeys पर कॉल कर सकते हैं। (अपने JDBC- ड्राइवर मान लिया जाये कि यह प्रदान करता है।)

यह इस की तर्ज पर कुछ चला जाता है:

Statement stmt = conn.createStatement(); 
stmt.execute(sql, Statement.RETURN_GENERATED_KEYS); 
ResultSet keyset = stmt.getGeneratedKeys(); 
+0

अच्छी तरह से डेटाबेस अज्ञेयवादी। –

+7

ओह अगर यह इतना आसान था।दुर्भाग्यवश यह तब तक काम नहीं करता जब तक कि आपके पास सही पोस्टग्रेस ड्राइवर संस्करण न हो और फिर भी परिणामसेट में फ़ील्ड के * सभी * न हों और न केवल जेनरेट किए गए आईडी वाले हों। – Gray

+0

ऐ, पोस्टग्रेएसक्यूएल –

16

आप JDBC 3.0 का उपयोग कर रहे हैं, तो आप पी के मूल्य के रूप में जल्द ही आप के रूप में प्राप्त कर सकते हैं इसे डालाhttps://www.ibm.com/developerworks/java/library/j-jdbcnew/

Statement stmt = conn.createStatement(); 
// Obtain the generated key that results from the query. 
stmt.executeUpdate("INSERT INTO authors " + 
        "(first_name, last_name) " + 
        "VALUES ('George', 'Orwell')", 
        Statement.RETURN_GENERATED_KEYS); 
ResultSet rs = stmt.getGeneratedKeys(); 
if (rs.next()) { 
    // Retrieve the auto generated key(s). 
    int key = rs.getInt(1); 
} 
+4

नोट करें कि यह ओरेकल (मैं 10 जी का उपयोग कर रहा हूं) http://stackoverflow.com/questions/1976625 के लिए काम नहीं करेगा/value-from-last-inserted-row-in-db –

+1

postgresql-9.2-1002.jdbc4.jar –

+0

के साथ अच्छा काम करें – gmustudent

7

यहाँ है मैं इसे कैसे जवाब यहां के आधार पर हल किया,:

यहाँ एक लेख है कि कैसे बारे में बात करती है

Connection conn = ConnectToDB(); //ConnectToDB establishes a connection to the database. 
String sql = "INSERT INTO \"TableName\"" + 
     "(\"Column1\", \"Column2\",\"Column3\",\"Column4\")" + 
     "VALUES ('value1',value2, 'value3', 'value4') RETURNING 
     \"TableName\".\"TableId\""; 
PreparedStatement prpState = conn.prepareStatement(sql); 
ResultSet rs = prpState.executeQuery(); 
if(rs.next()){ 
     System.out.println(rs.getInt(1)); 
     } 
0

चयन currval ('MySequence' का उपयोग न करें) - मूल्य विफल होने पर आवेषण पर वृद्धि बढ़ जाती है।

+0

लिंक के लिए धन्यवाद तो क्या? उन्होंने सिर्फ अद्वितीय मूल्यों के लिए कहा, न कि संगत मूल्य (जो समांतर निरस्त लेनदेन वाले सिस्टम में एक असंभव लक्ष्य है)। – bortzmeyer

+2

मूल प्रश्न: "क्या अंतिम डाली गई पंक्ति से मूल्य प्राप्त करने का कोई तरीका है?" कोड जो अंतिम डाली गई पंक्ति प्राप्त करने के लिए चयन विवरण बनाने के लिए currval (seq) का उपयोग करता है, अपेक्षित परिणाम उत्पन्न करने में विफल हो सकता है। – smilek

10

पोस्टग्रेएसक्यूएल जेडीबीसी ड्राइवर संस्करण 8.4-701PreparedStatement#getGeneratedKeys() अंततः पूरी तरह कार्यात्मक है। हम इसे पूर्ण संतुष्टि के लिए उत्पादन में लगभग एक वर्ष का उपयोग करते हैं।

"सादे JDBC" PreparedStatement जरूरतों के रूप में यह कुंजी वापस जाने के लिए बनाने के लिए इस प्रकार बनाया जा करने के लिए:

statement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS); 

आप वर्तमान JDBC ड्राइवर को संस्करण here (जो अभी भी 8.4- पल में है डाउनलोड कर सकते हैं 701)।

+0

क्या इससे कोई फर्क पड़ता है कि क्या मैं 'PreparedStatement.RETURN_GENERATED_KEYS' बनाम' स्टेटमेंट.RETURN_GENERATED_KEYS' का उपयोग करता हूं? – csharpfolk

+0

@csharpfolk: नहीं। इसे 'स्टेटमेंट' में परिभाषित किया गया है और 'प्रीपेडस्टेटमेंट स्टेटमेंट बढ़ाता है'। इसके स्रोत कोड और जावाडोक भी देखें। – BalusC

1
PreparedStatement stmt = getConnection(PROJECTDB + 2) 
    .prepareStatement("INSERT INTO fonts (font_size) VALUES(?) RETURNING fonts.*"); 
stmt.setString(1, "986"); 
ResultSet res = stmt.executeQuery(); 
while (res.next()) { 
    System.out.println("Generated key: " + res.getLong(1)); 
    System.out.println("Generated key: " + res.getInt(2)); 
    System.out.println("Generated key: " + res.getInt(3)); 
} 
stmt.close(); 
0
टिप्पणियां और Postgresql ड्राइवर 9.0-801.jdbc4 आपको लगता है कि @Select @Insert के बजाय प्रयोग किया जाता है की तरह

public interface ObjectiveMapper { 

@Select("insert into objectives" + 
     " (code,title,description) values" + 
     " (#{code}, #{title}, #{description}) returning id") 
int insert(Objective anObjective); 

नोट अपने मैपर में एक अंतरफलक विधि को परिभाषित साथ MyBatis 3.0.4 के लिए

0
उदाहरण के लिए

:

 
Connection conn = null; 
      PreparedStatement sth = null; 
      ResultSet rs =null; 
      try { 
       conn = delegate.getConnection(); 
       sth = conn.prepareStatement(INSERT_SQL); 
       sth.setString(1, pais.getNombre()); 
       sth.executeUpdate(); 
       rs=sth.getGeneratedKeys(); 
       if(rs.next()){ 
        Integer id = (Integer) rs.getInt(1); 
        pais.setId(id); 
       } 
      } 

,Statement.RETURN_GENERATED_KEYS);" नहीं मिला है। इतना आसान कोड

0

उपयोग:

// Do your insert code 

myDataBase.execSQL("INSERT INTO TABLE_NAME (FIELD_NAME1,FIELD_NAME2,...)VALUES (VALUE1,VALUE2,...)"); 

// Use the sqlite function "last_insert_rowid" 

Cursor last_id_inserted = yourBD.rawQuery("SELECT last_insert_rowid()", null); 

// Retrieve data from cursor. 

last_id_inserted.moveToFirst(); // Don't forget that! 

ultimo_id = last_id_inserted.getLong(0); // For Java, the result is returned on Long type (64) 
3

आप Statement का उपयोग कर रहे हैं, तो आप PreparedStatement उपयोग कर रहे हैं निम्नलिखित

//MY_NUMBER is the column name in the database 
String generatedColumns[] = {"MY_NUMBER"}; 
Statement stmt = conn.createStatement(); 

//String sql holds the insert query 
stmt.executeUpdate(sql, generatedColumns); 

ResultSet rs = stmt.getGeneratedKeys(); 

// The generated id 

if(rs.next()) 
long key = rs.getLong(1); 

के लिए जाते हैं, तो निम्न

String generatedColumns[] = {"MY_NUMBER"}; 
PreparedStatement pstmt = conn.prepareStatement(sql,generatedColumns); 
pstmt.setString(1, "qwerty"); 

pstmt.execute(); 
ResultSet rs = pstmt.getGeneratedKeys(); 
if(rs.next()) 
long key = rs.getLong(1); 
0

के लिए जाना यदि आप एक लेनदेन में हैं तो आप SELECT lastval() का उपयोग कर सकते हैं I आखिरी जेनरेट आईडी प्राप्त करने के लिए nsert।

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

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