मैं MERGE
कथन का उपयोग UPSERT
के रूप में या तो एक नया रिकॉर्ड जोड़ने या वर्तमान अद्यतन को अद्यतन करने के लिए कर रहा हूं। मेरे पास एकाधिक कनेक्शन और एकाधिक कथन (एक कनेक्शन और प्रति थ्रेड प्रति स्टेटमेंट) के माध्यम से डेटाबेस चलाते हुए कई धागे हैं। मैं एक समय में बयान 50 बैच कर रहा हूं।क्या SQL2008 में एक परमाणु बयान है?
मैं अपने परीक्षणों के दौरान duplicate key
उल्लंघन प्राप्त करने के लिए बहुत हैरान था। मुझे उम्मीद थी कि असंभव होना क्योंकि MERGE
एक लेनदेन के रूप में किया जाएगा, या है ना?
मेरे जावा कोड लगता है:
MERGE INTO CustomerSpend AS T
USING (SELECT ? AS ID, ? AS NetValue, ? AS VoidValue) AS V
ON T.ID = V.ID
WHEN MATCHED THEN
UPDATE SET T.ID = V.ID, T.NetValue = T.NetValue + V.NetValue, T.VoidValue = T.VoidValue + V.VoidValue
WHEN NOT MATCHED THEN
INSERT (ID,NetValue,VoidValue) VALUES (V.ID, V.NetValue, V.VoidValue);
त्रुटि पढ़ता है::
java.sql.BatchUpdateException: Violation of PRIMARY KEY constraint 'PK_CustomerSpend'. Cannot insert duplicate key in object 'dbo.CustomerSpend'. The duplicate key value is (498288 ).
at net.sourceforge.jtds.jdbc.JtdsStatement.executeBatch(JtdsStatement.java:944)
at x.db.Db$BatchedStatement.addBatch(Db.java:299)
...
मेज पर कुंजी एक PRIMARY
कुंजी है क्वेरी
private void addBatch(Columns columns) throws SQLException {
try {
// Set parameters.
for (int i = 0; i < columns.size(); i++) {
Column c = columns.get(i);
// Column type is an `enum` with a `set` method appropriate to its type, e.g. setLong, setString etc.
c.getColumnType().set(statement, i + 1, c.getValue());
}
// Add the insert as a batch.
statement.addBatch();
// Ready to execute?
if (++batched >= MaxBatched) {
statement.executeBatch();
batched = 0;
}
} catch (SQLException e) {
log.warning("addBatch failed " + sql + " thread " + Thread.currentThread().getName(), e);
throw e;
}
}
इस तरह दिखता है ID
फ़ील्ड पर।
आप प्राथमिक कुंजी (वी.आईडी) कैसे बना रहे हैं? – Paolo
@ पाओलो 'अल्टर टेबल ग्राहकस्पेन्ड कंसस्ट्रेंट जोड़ें [पीके_CustomerSpend] प्राथमिक कुंजी क्लस्टर (आईडी) '। क्या कोई बेहतर तरीका है? – OldCurmudgeon
क्षमा करें, मेरा मतलब है कि आप क्वेरी में गुजर रहे आईडी के वास्तविक मूल्य का मतलब है। मिकाएल को यह नीचे मिला - लेनदेन परमाणु है, लेकिन एक ही कुंजी – Paolo