"सम्मिलित करें यदि मौजूद नहीं है तो" SQLite में कथन


143

मेरे पास एक SQLite डेटाबेस है। मैं तालिका में मान ( users_id, lessoninfo_id) सम्मिलित करने का प्रयास कर रहा हूं bookmarks, यदि दोनों एक पंक्ति में पहले से मौजूद नहीं हैं।

INSERT INTO bookmarks(users_id,lessoninfo_id) 
VALUES(
    (SELECT _id FROM Users WHERE User='"+$('#user_lesson').html()+"'),
        (SELECT _id FROM lessoninfo 
        WHERE Lesson="+lesson_no+" AND cast(starttime AS int)="+Math.floor(result_set.rows.item(markerCount-1).starttime)+") 
        WHERE NOT EXISTS (
            SELECT users_id,lessoninfo_id from bookmarks 
            WHERE users_id=(SELECT _id FROM Users 
            WHERE User='"+$('#user_lesson').html()+"') AND lessoninfo_id=(
                SELECT _id FROM lessoninfo
                WHERE Lesson="+lesson_no+")))

यह यह कहते हुए एक त्रुटि देता है:

जहां सिंटैक्स के पास डीबी त्रुटि।

जवाबों:


138

यदि आपके पास मेमो नामक एक तालिका है जिसमें दो कॉलम हैं idऔर textआपको इस तरह करने में सक्षम होना चाहिए:

INSERT INTO memos(id,text) 
SELECT 5, 'text to insert' 
WHERE NOT EXISTS(SELECT 1 FROM memos WHERE id = 5 AND text = 'text to insert');

यदि एक रिकॉर्ड में पहले से ही एक पंक्ति होती है, जहां text'टेक्स्ट डालने के लिए' idबराबर है और 5 के बराबर है, तो सम्मिलित ऑपरेशन को अनदेखा किया जाएगा।

मुझे नहीं पता कि यह आपके विशेष प्रश्न के लिए काम करेगा, लेकिन शायद यह आपको आगे बढ़ने के संकेत देता है।

मैं आपको सलाह दूंगा कि आप इसके बजाय अपनी तालिका डिज़ाइन करें ताकि किसी भी डुप्लिकेट की अनुमति न हो जैसा कि @CLs answerनीचे समझाया गया है।


436

यदि आप कभी भी डुप्लिकेट नहीं करना चाहते हैं, तो आपको इसे तालिका बाधा के रूप में घोषित करना चाहिए:

CREATE TABLE bookmarks(
    users_id INTEGER,
    lessoninfo_id INTEGER,
    UNIQUE(users_id, lessoninfo_id)
);

(दोनों स्तंभों पर एक प्राथमिक कुंजी का समान प्रभाव होगा।)

तब डेटाबेस को यह बताना संभव है कि आप ऐसे रिकॉर्डों को चुपचाप अनदेखा करना चाहते हैं जो इस तरह की बाधा का उल्लंघन करेंगे :

INSERT OR IGNORE INTO bookmarks(users_id, lessoninfo_id) VALUES(123, 456)

12
फिर नई सम्मिलित पंक्ति की आईडी या पहले से मौजूद एक को प्राप्त करने का इष्टतम तरीका क्या है, इसलिए मैं इसे किसी अन्य तालिका में सम्मिलित कर सकता हूं जिसमें इस के लिए एक विदेशी कुंजी है? उदाहरण के लिए मेरे पास दो टेबल हैं person (id, name unique)और cat (person_id, name unique)मैं बहुत सारे जोड़े सम्मिलित करना चाहता हूं (person_name, cat_name)?
और सराफ

2
मौजूदा पंक्ति की आईडी पढ़ना केवल चुनिंदा क्वेरी से संभव है। लेकिन यह एक अलग सवाल है।
सीएल।

1
शायद जोड़ने के ON CONFLICT IGNOREलिए CREATE TABLEथोड़ा और अधिक उपयोगी होगा
defhlt

1
@ rightaway717 "उपेक्षा" का मतलब है कि कुछ भी नहीं होता है; इस सवाल का अपडेट से कोई लेना-देना नहीं है।
सीएल।

1
@ Hack06 Android के सम्मिलित () अलग व्यवहार करता है; आपको इसे InsertOrThrow () या insertWithOnConflict () के साथ बदलना चाहिए ।
सीएल।

21

एक अद्वितीय कॉलम के लिए, इसका उपयोग करें:

INSERT OR REPLACE INTO table () values();

अधिक जानकारी के लिए, देखें: sqlite.org/lang_insert


यह मेरे लिए काम नहीं करता है। यह हमेशा आवेषण के रूप में सम्मिलित करता है या my_table (col1, col2) मान ('1', '2') में प्रतिस्थापित करता है; 1 2 की कई पंक्तियों को जोड़ेंगे
पीटर मूर

मैं यह जोड़ सकता हूं कि यदि बाधा डाल दी जाती है तो यह अच्छी तरह से काम करता है Unique(col1,col2)और आपके पास col3 भी है, क्योंकि एक आवेषण या अनदेखी विफल हो जाएगी जहां यह नए मान के लिए col3 को अपडेट करेगा। insert or replace into my_table values('1','2','5')एक पंक्ति की जगह'1','2','3'
पीटर मूर

4
insert into bookmarks (users_id, lessoninfo_id)

select 1, 167
EXCEPT
select user_id, lessoninfo_id
from bookmarks
where user_id=1
and lessoninfo_id=167;

यह सबसे तेज़ तरीका है।

कुछ अन्य एसक्यूएल इंजनों के लिए, आप एक डमी तालिका का उपयोग कर सकते हैं जिसमें 1 रिकॉर्ड है। उदाहरण के लिए:

select 1, 167 from ONE_RECORD_DUMMY_TABLE
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.