SQLite
 sql >> डेटाबेस >  >> RDS >> SQLite

SQLite में संघर्ष पर कैसे काम करता है

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     


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQLiteDatabase.query () में स्ट्रिंग [] चयनआर्ग का उपयोग करना

  2. किसी गतिविधि से जावा क्लास में डेटा कैसे पास करें

  3. execSQL:बाइंडर्ग बेहतर है?

  4. कैसे Substr () SQLite में काम करता है

  5. डेटाटाइप बेमेल (कोड 20) डालने के दौरान