क्यू एंड ए स्टाइल
खैर, शोध करने और घंटों तक समस्या से लड़ने के बाद, मुझे पता चला कि इसे पूरा करने के दो तरीके हैं, आपकी तालिका की संरचना पर निर्भर करता है और यदि आपके पास अखंडता बनाए रखने के लिए विदेशी कुंजी प्रतिबंध सक्रिय हैं। मैं इसे एक साफ प्रारूप में साझा करना चाहता हूं ताकि मेरी स्थिति में लोगों को कुछ समय बचाया जा सके।
विकल्प 1: आप पंक्ति को हटा सकते हैं
दूसरे शब्दों में, आपके पास विदेशी कुंजी नहीं है, या यदि आपके पास है, तो आपका SQLite इंजन कॉन्फ़िगर किया गया है ताकि कोई अखंडता अपवाद न हों। जाने का रास्ता INSERT या REPLACE है । यदि आप ऐसे खिलाड़ी को सम्मिलित / अद्यतन करने का प्रयास कर रहे हैं, जिसकी आईडी पहले से मौजूद है, तो SQLite इंजन उस पंक्ति को हटा देगा और आपके द्वारा प्रदत्त डेटा सम्मिलित करेगा। अब सवाल आता है: पुरानी आईडी को संबद्ध रखने के लिए क्या करें?
मान लें कि हम डेटा उपयोगकर्ता_नाम = 'स्टीवन' और आयु = 32 के साथ यूपीएसईआरटी करना चाहते हैं ।
इस कोड को देखें:
INSERT INTO players (id, name, age)
VALUES (
coalesce((select id from players where user_name='steven'),
(select max(id) from drawings) + 1),
32)
चाल तालमेल में है। यह उपयोगकर्ता 'स्टीवन' की आईडी लौटाता है यदि कोई हो, और अन्यथा, यह एक नई ताज़ा आईडी लौटाता है।
विकल्प 2: आप पंक्ति को हटा नहीं सकते
पिछले समाधान के साथ घूमने के बाद, मुझे एहसास हुआ कि मेरे मामले में जो डेटा को नष्ट कर सकता है, क्योंकि यह आईडी अन्य तालिका के लिए एक विदेशी कुंजी के रूप में काम करती है। इसके अलावा, मैंने टेबल को DELETE CASCADE पर क्लॉज़ के साथ बनाया , जिसका मतलब होगा कि यह डेटा को चुपचाप हटा देगा। खतरनाक।
इसलिए, मैंने पहले एक IF क्लॉज के बारे में सोचा, लेकिन SQLite में केवल CASE है । और इस मामले का उपयोग नहीं किया जा सकता है (या कम से कम मैंने इसे प्रबंधित नहीं किया था) एक अद्यतन क्वेरी करने के लिए यदि EXISTS (खिलाड़ियों से आईडी का चयन करें जहां user_name = 'स्टीवन'), और INSERT यदि ऐसा नहीं हुआ। नही जाओ।
और फिर, आखिरकार मैंने सफलता के साथ, जानवर बल का उपयोग किया। तर्क यह है कि प्रत्येक यूपीएसईआरटी के लिए जिसे आप प्रदर्शन करना चाहते हैं, पहले यह सुनिश्चित करने के लिए INSERT या IGNORE को निष्पादित करें कि हमारे उपयोगकर्ता के साथ कोई पंक्ति है, और फिर उसी डेटा के साथ एक UPDATE क्वेरी निष्पादित करें जिसे आपने सम्मिलित करने का प्रयास किया था।
पहले जैसा ही डेटा: user_name = 'स्टीवन' और उम्र = 32।
-- make sure it exists
INSERT OR IGNORE INTO players (user_name, age) VALUES ('steven', 32);
-- make sure it has the right data
UPDATE players SET user_name='steven', age=32 WHERE user_name='steven';
और बस यही!
संपादित करें
जैसा कि एंडी ने टिप्पणी की है, पहले डालने की कोशिश कर रहा है और फिर अपडेट से फायरिंग ट्रिगर हो सकता है जो अपेक्षा से अधिक बार होता है। यह मेरी राय में डेटा सुरक्षा का मुद्दा नहीं है, लेकिन यह सच है कि अनावश्यक घटनाओं को अंजाम देना थोड़ा कम मायने रखता है। इसलिए, एक बेहतर समाधान होगा:
-- Try to update any existing row
UPDATE players SET age=32 WHERE user_name='steven';
-- Make sure it exists
INSERT OR IGNORE INTO players (user_name, age) VALUES ('steven', 32);