SQLite में ON CONFLICT
है क्लॉज जो आपको यह निर्दिष्ट करने की अनुमति देता है कि बाधा संघर्षों को कैसे संभालना है। यह UNIQUE
. पर लागू होता है , NOT NULL
, CHECK
, और PRIMARY KEY
बाधाएं (लेकिन FOREIGN KEY
बाधाएं)।
आप इस खंड के साथ पांच संभावित विकल्पों का उपयोग कर सकते हैं:
ABORT
FAIL
IGNORE
REPLACE
ROLLBACK
यह लेख इनमें से प्रत्येक विकल्प के उदाहरण और स्पष्टीकरण प्रदान करता है।
ON CONFLICT
क्लॉज का प्रयोग CREATE TABLE
. में किया जाता है स्टेटमेंट, लेकिन इसका उपयोग ON CONFLICT
. को बदलकर डेटा डालने या अपडेट करते समय भी किया जा सकता है OR
. के साथ ।
तालिका बनाते समय
जैसा कि बताया गया है, आप ON CONFLICT
. का उपयोग कर सकते हैं जब आप टेबल बनाते हैं या जब आप डेटा डालते/अपडेट करते हैं।
यहां ON CONFLICT
using का उपयोग करने का एक उदाहरण दिया गया है तालिका बनाते समय।
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL ON CONFLICT IGNORE,
Price
);
जब आप ON CONFLICT
. का उपयोग करते हैं खंड, आप इसे उस विशिष्ट बाधा पर लागू करते हैं जिसे आप संभालना चाहते हैं। इस मामले में, मैंने क्लॉज को NOT NULL
. में जोड़ा है बाधा।
इस मामले में मैंने IGNORE
. निर्दिष्ट किया है , जिसका अर्थ है कि, यदि कोई बाधा उल्लंघन है तो SQLite उस पंक्ति को छोड़ देगा और फिर प्रसंस्करण जारी रखेगा।
अब अगर मैं NULL
insert डालने का प्रयास करता हूं उत्पादनाम . में कॉलम कि पंक्ति छोड़ दी गई है।
INSERT INTO Products VALUES
(1, 'Hammer', 9.99),
(2, NULL, 1.49),
(3, 'Saw', 11.34),
(4, 'Wrench', 37.00),
(5, 'Chisel', 23.00),
(6, 'Bandage', 120.00);
SELECT * FROM Products;
परिणाम:
ProductId ProductName Price ---------- ----------- ---------- 1 Hammer 9.99 3 Saw 11.34 4 Wrench 37.0 5 Chisel 23.0 6 Bandage 120.0
डेटा डालते समय
डेटा डालने और अपडेट करते समय आप इस क्लॉज का भी उपयोग कर सकते हैं। अंतर यह है कि, आप ON CONFLICT
. को प्रतिस्थापित करते हैं OR
. के साथ .
प्रदर्शित करने के लिए, मैं पिछली तालिका को छोड़ दूंगा और इसे फिर से बनाऊंगा, लेकिन बिना ON CONFLICT
के खंड:
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price
);
अब मैं वही डेटा डालूंगा और OR IGNORE
. का इस्तेमाल करूंगा उस पंक्ति को छोड़ने के लिए जो बाधा का उल्लंघन करती है।
INSERT OR IGNORE INTO Products VALUES
(1, 'Hammer', 9.99),
(2, NULL, 1.49),
(3, 'Saw', 11.34),
(4, 'Wrench', 37.00),
(5, 'Chisel', 23.00),
(6, 'Bandage', 120.00);
SELECT * FROM Products;
परिणाम:
ProductId ProductName Price ---------- ----------- ---------- 1 Hammer 9.99 3 Saw 11.34 4 Wrench 37.0 5 Chisel 23.0 6 Bandage 120.0
तो हमें वही परिणाम मिलता है जो पिछले उदाहरण में था।
इन उदाहरणों में मैंने IGNORE
. का इस्तेमाल किया है विकल्प। यह इस खंड के लिए केवल पांच संभावित विकल्पों में से एक है।
नीचे पांच विकल्पों में से प्रत्येक का उपयोग करने वाले उदाहरण दिए गए हैं।
निरस्त करें
यह विकल्प SQLITE_CONSTRAINT त्रुटि के साथ वर्तमान SQL कथन को निरस्त करता है और वर्तमान SQL कथन द्वारा किए गए किसी भी परिवर्तन का बैक आउट करता है; लेकिन उसी लेन-देन में पूर्व SQL कथनों के कारण हुए परिवर्तन संरक्षित हैं और लेन-देन सक्रिय रहता है।
यह डिफ़ॉल्ट व्यवहार है। दूसरे शब्दों में, जब आप ON CONFLICT
का उपयोग नहीं करते हैं, तो यह बाधा उल्लंघन के दौरान होता है। खंड।
जब आप ABORT
निर्दिष्ट करते हैं तो क्या होता है इसका एक उदाहरण यहां दिया गया है ।
DELETE FROM Products;
INSERT OR ABORT INTO Products VALUES
(1, 'Hammer', 9.99),
(2, NULL, 1.49),
(3, 'Saw', 11.34),
(4, 'Wrench', 37.00),
(5, 'Chisel', 23.00),
(6, 'Bandage', 120.00);
SELECT * FROM Products;
परिणाम:
कोई परिणाम नहीं लौटाया गया क्योंकि INSERT
ऑपरेशन निरस्त कर दिया गया था, और इसलिए तालिका खाली है।
यदि मैं प्रत्येक पंक्ति को उसके अपने INSERT
. में रखूं तो क्या होगा लेन-देन के भीतर बयान।
BEGIN TRANSACTION;
INSERT OR ABORT INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR ABORT INTO Products VALUES (2, NULL, 1.49);
INSERT OR ABORT INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR ABORT INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR ABORT INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR ABORT INTO Products VALUES (6, 'Bandage', 120.00);
COMMIT;
SELECT * FROM Products;
परिणाम:
ProductId ProductName Price ---------- ----------- ---------- 1 Hammer 9.99 3 Saw 11.34 4 Wrench 37.0 5 Chisel 23.0 6 Bandage 120.0
विफल
FAIL
विकल्प SQLITE_CONSTRAINT त्रुटि के साथ वर्तमान SQL कथन को निरस्त करता है। लेकिन यह SQL कथन के पूर्व परिवर्तनों को वापस नहीं लेता है जो विफल हो गया और न ही यह लेनदेन को समाप्त करता है।
यहां एक उदाहरण दिया गया है।
DELETE FROM Products;
INSERT OR FAIL INTO Products VALUES
(1, 'Hammer', 9.99),
(2, NULL, 1.49),
(3, 'Saw', 11.34),
(4, 'Wrench', 37.00),
(5, 'Chisel', 23.00),
(6, 'Bandage', 120.00);
SELECT * FROM Products;
परिणाम:
ProductId ProductName Price ---------- ----------- ---------- 1 Hammer 9.99
यहाँ यह अलग INSERT
. के साथ है लेन-देन के भीतर बयान।
DELETE FROM Products;
BEGIN TRANSACTION;
INSERT OR FAIL INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR FAIL INTO Products VALUES (2, NULL, 1.49);
INSERT OR FAIL INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR FAIL INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR FAIL INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR FAIL INTO Products VALUES (6, 'Bandage', 120.00);
COMMIT;
SELECT * FROM Products;
परिणाम:
ProductId ProductName Price ---------- ----------- ---------- 1 Hammer 9.99 3 Saw 11.34 4 Wrench 37.0 5 Chisel 23.0 6 Bandage 120.0
अनदेखा करें
IGNORE
विकल्प एक पंक्ति को छोड़ देता है जिसमें बाधा उल्लंघन होता है और SQL कथन की बाद की पंक्तियों को संसाधित करना जारी रखता है जैसे कि कुछ भी गलत नहीं हुआ। उस पंक्ति से पहले और बाद की अन्य पंक्तियाँ जिनमें बाधा उल्लंघन था, सामान्य रूप से डाली या अपडेट की जाती हैं। विशिष्टता के लिए कोई त्रुटि नहीं लौटाई गई, NOT NULL
, और UNIQUE
बाधा त्रुटियाँ जब इस विकल्प का उपयोग किया जाता है। हालांकि, यह विकल्प ABORT
. की तरह काम करता है विदेशी कुंजी बाधा त्रुटियों के लिए।
इस पृष्ठ पर पहले उदाहरण IGNORE
. का उपयोग करते हैं , लेकिन यहाँ यह फिर से है।
DELETE FROM Products;
INSERT OR IGNORE INTO Products VALUES
(1, 'Hammer', 9.99),
(2, NULL, 1.49),
(3, 'Saw', 11.34),
(4, 'Wrench', 37.00),
(5, 'Chisel', 23.00),
(6, 'Bandage', 120.00);
SELECT * FROM Products;
परिणाम:
ProductId ProductName Price ---------- ----------- ---------- 1 Hammer 9.99 3 Saw 11.34 4 Wrench 37.0 5 Chisel 23.0 6 Bandage 120.0
बदलें
REPLACE
विकल्प उल्लंघन के आधार पर अलग तरह से काम करता है:
- जब एक
UNIQUE
याPRIMARY KEY
बाधा उल्लंघन होता है,REPLACE
विकल्प पूर्व-मौजूदा पंक्तियों को हटा देता है जो वर्तमान पंक्ति को सम्मिलित करने या अद्यतन करने से पहले बाधा उल्लंघन का कारण बन रहे हैं और आदेश सामान्य रूप से निष्पादित होता रहता है। - यदि एक
NOT NULL
बाधा उल्लंघन होता है, यहNULL
. को बदल देता है उस कॉलम के लिए डिफ़ॉल्ट मान के साथ मान, या यदि कॉलम में कोई डिफ़ॉल्ट मान नहीं है, तोABORT
एल्गोरिथम का उपयोग किया जाता है। - यदि कोई
CHECK
बाधा या विदेशी कुंजी बाधा उल्लंघन होता है, तबREPLACE
ABORT
. की तरह काम करता है ।
साथ ही, यदि यह किसी बाधा को पूरा करने के लिए पंक्तियों को हटाता है, तो ट्रिगर्स को हटा दें यदि और केवल तभी जब पुनरावर्ती ट्रिगर सक्षम हों।
यहां एक उदाहरण दिया गया है जो REPLACE
. का उपयोग करता है विकल्प।
DELETE FROM Products;
INSERT OR REPLACE INTO Products VALUES
(1, 'Hammer', 9.99),
(2, 'Nails', 1.49),
(3, 'Saw', 11.34),
(1, 'Wrench', 37.00),
(5, 'Chisel', 23.00),
(6, 'Bandage', 120.00);
SELECT * FROM Products;
परिणाम:
ProductId ProductName Price ---------- ----------- ---------- 1 Wrench 37.0 2 Nails 1.49 3 Saw 11.34 5 Chisel 23.0 6 Bandage 120.0
इस उदाहरण में, प्राथमिक कुंजी के साथ विरोध था (मैंने एक ही ProductId के साथ दो पंक्तियों को सम्मिलित करने का प्रयास किया ) REPLACE
विकल्प ने दूसरे को पहले की जगह ले लिया।
रोलबैक
एक अन्य विकल्प ROLLBACK
. का उपयोग करना है ।
यह विकल्प SQLITE_CONSTRAINT त्रुटि के साथ वर्तमान SQL कथन को निरस्त करता है और वर्तमान लेनदेन को वापस रोल करता है। यदि कोई लेन-देन सक्रिय नहीं है (प्रत्येक आदेश पर बनाए गए निहित लेनदेन के अलावा) तो यह ABORT
के समान कार्य करता है एल्गोरिथम।
यहां एक उदाहरण दिया गया है जो कई INSERT OR ROLLBACK
का उपयोग करता है लेन-देन के भीतर बयान।
DELETE FROM Products;
BEGIN TRANSACTION;
INSERT OR ROLLBACK INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR ROLLBACK INTO Products VALUES (2, NULL, 1.49);
INSERT OR ROLLBACK INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR ROLLBACK INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR ROLLBACK INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR ROLLBACK INTO Products VALUES (6, 'Bandage', 120.00);
COMMIT;
SELECT * FROM Products;
जब मैं इसे चलाता हूं तो मेरे टर्मिनल से पूरा आउटपुट होता है:
sqlite> DELETE FROM Products; sqlite> sqlite> BEGIN TRANSACTION; sqlite> INSERT OR ROLLBACK INTO Products VALUES (1, 'Hammer', 9.99); sqlite> INSERT OR ROLLBACK INTO Products VALUES (2, NULL, 1.49); Error: NOT NULL constraint failed: Products.ProductName sqlite> INSERT OR ROLLBACK INTO Products VALUES (3, 'Saw', 11.34); sqlite> INSERT OR ROLLBACK INTO Products VALUES (4, 'Wrench', 37.00); sqlite> INSERT OR ROLLBACK INTO Products VALUES (5, 'Chisel', 23.00); sqlite> INSERT OR ROLLBACK INTO Products VALUES (6, 'Bandage', 120.00); sqlite> COMMIT; Error: cannot commit - no transaction is active sqlite> sqlite> SELECT * FROM Products; ProductId ProductName Price ---------- ----------- ---------- 3 Saw 11.34 4 Wrench 37.0 5 Chisel 23.0 6 Bandage 120.0
तो यह बाधा उल्लंघन के लिए मिला, फिर लेनदेन को वापस ले लिया। फिर बाद की पंक्तियों को संसाधित किया गया और फिर COMMIT
कीवर्ड का सामना करना पड़ा। तब तक, लेन-देन पहले ही वापस ले लिया गया था और इसलिए हमें यह बताते हुए एक और त्रुटि मिली कि कोई लेन-देन सक्रिय नहीं था।
अगर मैं इसे लेन-देन से हटा दूं तो यहां क्या होगा।
DELETE FROM Products;
INSERT OR ROLLBACK INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR ROLLBACK INTO Products VALUES (2, NULL, 1.49);
INSERT OR ROLLBACK INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR ROLLBACK INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR ROLLBACK INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR ROLLBACK INTO Products VALUES (6, 'Bandage', 120.00);
SELECT * FROM Products;
जब मैं इसे चलाता हूं तो मेरे टर्मिनल से पूरा आउटपुट होता है:
sqlite> DELETE FROM Products; sqlite> sqlite> INSERT OR ROLLBACK INTO Products VALUES (1, 'Hammer', 9.99); sqlite> INSERT OR ROLLBACK INTO Products VALUES (2, NULL, 1.49); Error: NOT NULL constraint failed: Products.ProductName sqlite> INSERT OR ROLLBACK INTO Products VALUES (3, 'Saw', 11.34); sqlite> INSERT OR ROLLBACK INTO Products VALUES (4, 'Wrench', 37.00); sqlite> INSERT OR ROLLBACK INTO Products VALUES (5, 'Chisel', 23.00); sqlite> INSERT OR ROLLBACK INTO Products VALUES (6, 'Bandage', 120.00); sqlite> sqlite> SELECT * FROM Products; ProductId ProductName Price ---------- ----------- ---------- 1 Hammer 9.99 3 Saw 11.34 4 Wrench 37.0 5 Chisel 23.0 6 Bandage 120.0
इस मामले में, यह ABORT
. की तरह काम करता है ।
पुष्टि करने के लिए, यहां ABORT
. का उपयोग करके वही कथन दिया गया है ROLLBACK
. के बजाय ।
DELETE FROM Products;
INSERT OR ABORT INTO Products VALUES (1, 'Hammer', 9.99);
INSERT OR ABORT INTO Products VALUES (2, NULL, 1.49);
INSERT OR ABORT INTO Products VALUES (3, 'Saw', 11.34);
INSERT OR ABORT INTO Products VALUES (4, 'Wrench', 37.00);
INSERT OR ABORT INTO Products VALUES (5, 'Chisel', 23.00);
INSERT OR ABORT INTO Products VALUES (6, 'Bandage', 120.00);
SELECT * FROM Products;
जब मैं इसे चलाता हूं तो मेरे टर्मिनल से पूरा आउटपुट होता है:
sqlite> DELETE FROM Products; sqlite> sqlite> INSERT OR ABORT INTO Products VALUES (1, 'Hammer', 9.99); sqlite> INSERT OR ABORT INTO Products VALUES (2, NULL, 1.49); Error: NOT NULL constraint failed: Products.ProductName sqlite> INSERT OR ABORT INTO Products VALUES (3, 'Saw', 11.34); sqlite> INSERT OR ABORT INTO Products VALUES (4, 'Wrench', 37.00); sqlite> INSERT OR ABORT INTO Products VALUES (5, 'Chisel', 23.00); sqlite> INSERT OR ABORT INTO Products VALUES (6, 'Bandage', 120.00); sqlite> sqlite> SELECT * FROM Products; ProductId ProductName Price ---------- ----------- ---------- 1 Hammer 9.99 3 Saw 11.34 4 Wrench 37.0 5 Chisel 23.0 6 Bandage 120.0