2010-03-30 13 views
84

पर मेरे पास दो टेबल हैं: ट्रैक और वेप पॉइंट्स, ट्रैक में कई तरीके हो सकते हैं, लेकिन एक रास्ता बिंदु केवल 1 ट्रैक को सौंपा गया है।SQLite का उपयोग कर एंड्रॉइड में विदेशी कुंजी बाधाएं? कैस्केड

पॉइंट टेबल में मेरे पास "trackidfk" नामक एक कॉलम है जो ट्रैक बनने के बाद track_ID को सम्मिलित करता है, हालांकि मैंने इस कॉलम पर विदेशी कुंजी बाधाओं को सेट नहीं किया है।

जब मैं एक ट्रैक हटाता हूं तो मैं निर्दिष्ट मार्ग बिंदुओं को हटाना चाहता हूं, क्या यह संभव है? मैंने ट्रिगर्स का उपयोग करने के बारे में पढ़ा लेकिन मुझे नहीं लगता कि वे एंड्रॉइड में समर्थित हैं।

public void onCreate(SQLiteDatabase db) { 
    db.execSQL("CREATE TABLE " + TABLE_NAME 
       + " (" 
       + _ID   + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
       + LONGITUDE + " INTEGER," 
       + LATITUDE + " INTEGER," 
       + TIME  + " INTEGER," 
       + TRACK_ID_FK + " INTEGER" 
       + ");" 
      ); 

    ... 
} 

उत्तर

229

डिलीट कैस्केड पर विदेशी कुंजी बाधाएं समर्थित हैं, लेकिन आपको उन्हें सक्षम करने की आवश्यकता है।
मैंने अभी अपने SQLOpenHelper पर निम्न जोड़ा है, जो चाल चल रहा है।

@Override 
public void onOpen(SQLiteDatabase db) { 
    super.onOpen(db); 
    if (!db.isReadOnly()) { 
     // Enable foreign key constraints 
     db.execSQL("PRAGMA foreign_keys=ON;"); 
    } 
} 

मैंने अपना संदर्भ कॉलम निम्नानुसार घोषित किया। एंड्रॉयड 1.6 में

mailbox_id INTEGER REFERENCES mailboxes ON DELETE CASCADE 
+32

एक टिप्पणी के रूप में: यह केवल स्क्लाइट संस्करण 3.6.1 9 के बाद से काम करता है। – VansFannel

+58

जिसका अर्थ यह है कि यह केवल एंड्रॉइड 2.2 फियोयो के बाद काम करता है जिसमें SQLite 3.6.22 – Intrications

+2

@ फिल है, आप केवल अगर पढ़ने-योग्य स्थिति का उपयोग क्यों करते हैं? –

4

मैं SQLite बॉक्स के इस बाहर का समर्थन करता है नहीं लगता है:

वेपोइंट तालिका बनाने के लिए। मुझे अपने ऐप्लिकेशन में कर रहा हूँ है:

  1. लेनदेन
  2. हटाएं विस्तार डेटा (वेपोइंट अपने उदाहरण में)
  3. हटाएं मास्टर डाटा (पटरियों अपने उदाहरण में)
  4. सफलता
  5. पर लेन-देन प्रतिबद्ध बनाएं

इस तरह से मुझे यकीन है कि या तो सभी डेटा हटा दिया गया है या कोई भी नहीं।

+0

लेकिन क्या आप एक विधि का उपयोग कर दोनों टेबलों से हट रहे हैं? – jcrowson

+0

हां, मैं एपीआई से नोट्स नमूना के साथ काफी कुछ चला गया। जब मैं आपके मामले में एक ट्रैक क्या हटाना चाहता हूं, तो मैं लेनदेन बनाता हूं, ट्रैक और मार्ग बिंदु हटाता हूं और लेनदेन करता हूं। यह सब एक ही समय में है। –

4

ट्रिगर एंड्रॉइड द्वारा समर्थित हैं और उस प्रकार का कैस्केड डिलीट एसक्लाइट द्वारा समर्थित नहीं है। एंड्रॉइड पर ट्रिगर्स का उपयोग करने का एक उदाहरण here पाया जा सकता है। हालांकि लेनदेन का उपयोग करते हुए थॉर्स्टन ने कहा कि शायद ट्रिगर जितना आसान हो।

3

SQLite संस्करण 3.5.9 तो यह विदेशी कुंजी का समर्थन नहीं करता है ...

http://www.sqlite.org/foreignkeys.html "इस दस्तावेज़ को एसक्यूएल विदेशी कुंजी SQLite संस्करण 3.6 में पेश की कमी के लिए समर्थन का वर्णन करता है। 19. "

Froyo में यह SQLite संस्करण 3.6.22, तो ... है

संपादित करें: SQLite संस्करण देखने के लिए: adb शेल sqlite3 -संस्करण

+0

तो इस तरह की बाधाओं को बताने का कोई तरीका है .. मेरा मतलब है कि स्क्लाइट संस्करण को अपग्रेड करने का कोई तरीका है .. क्योंकि हमें एंड्रॉइड 2.1 में सॉफ़्टवेयर संस्करण का समर्थन करना होगा, जिसमें – NullPointerException

+0

के ऊपर स्क्लाइट संस्करण 3.5.9 है, नहीं, आपके पास है खुद के द्वारा सब कुछ संभाल करने :( – GBouerat

1

"हटाएँ झरना पर" के साथ विदेशी कुंजी SQLite में समर्थित हैं एंड्रॉइड 2.2 और ऊपर में। लेकिन उनका उपयोग करते समय सावधान रहें: कभी-कभी एक कॉलम पर एक विदेशी कुंजी को फायर करते समय एक त्रुटि की सूचना दी जाती है, लेकिन असली समस्या किसी अन्य कॉलम में बाल तालिका में विदेशी कुंजी बाधा में होती है, या कुछ अन्य तालिका इस तालिका को संदर्भित करती है।

ऐसा लगता है कि SQLite उनमें से एक को फायर करते समय सभी बाधाओं की जांच करता है। यह वास्तव में प्रलेखन में उल्लेख किया गया है। डीडीएल बनाम डीएमएल बाधा जांच।

51

एंड्रॉइड 4 के बाद से।1 (एपीआई 16) SQLiteDatabase समर्थन करता है:

public void setForeignKeyConstraintsEnabled (boolean enable) 
25

e.shishkin से पोस्ट के रूप में एपीआई 16 से कहते हैं ऊपर आप db.setForeignKeyConstraintsEnabled(boolean)

@Override 
public void onConfigure(SQLiteDatabase db){ 
    db.setForeignKeyConstraintsEnabled(true); 
} 
6

जो भी @phil का उपयोग कर SqLiteOpenHelper.onConfigure(SqLiteDatabase) विधि में विदेशी कुंजी की कमी सक्षम होना चाहिए उल्लेख किया गया है अच्छा है। लेकिन आप विदेशी मुद्रा सेट करने के लिए डाटाबेस में उपलब्ध एक और डिफ़ॉल्ट विधि का उपयोग कर सकते हैं। यह सेट है ForeForeignKeyConstraints सक्षम (सत्य)।

@Override 
public void onOpen(SQLiteDatabase db) { 
    super.onOpen(db); 
    if (!db.isReadOnly()) { 
     // Enable foreign key constraints 
     db.execSQL("PRAGMA foreign_keys=ON;"); 
       //(OR) 
     db.setForeignKeyConstraintsEnabled (true) 
    } 
} 

डॉक्स के लिए SQLiteDatabase.setForeignKeyConstraintsEnabled

+2

प्रलेखन तुम्हें तैनात पता चलता है: 'एक अच्छा समय सही बुला openOrCreateDatabase (फ़ाइल, SQLiteDatabase.CursorFactory) के बाद है इस विधि कॉल करने या onConfigure (SQLiteDatabase) में callback.' बजाय 'ओपन' पर, 'कॉन्फिगर' पर सही जगह प्रतीत होती है। –

8

कभी एक और अधिक पूरा जवाब के साथ जवाब देने के लिए एक सवाल का बहुत पुराना देखें।

@Override public void onOpen(SQLiteDatabase db) { 
    super.onOpen(db); 
    if (!db.isReadOnly()) { 
     setForeignKeyConstraintsEnabled(db); 
    } 
    mOpenHelperCallbacks.onOpen(mContext, db); 
} 

private void setForeignKeyConstraintsEnabled(SQLiteDatabase db) { 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
     setForeignKeyConstraintsEnabledPreJellyBean(db); 
    } else { 
     setForeignKeyConstraintsEnabledPostJellyBean(db); 
    } 
} 

private void setForeignKeyConstraintsEnabledPreJellyBean(SQLiteDatabase db) { 
    db.execSQL("PRAGMA foreign_keys=ON;"); 
} 

@TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
private void setForeignKeyConstraintsEnabledPostJellyBean(SQLiteDatabase db) { 
    db.setForeignKeyConstraintsEnabled(true); 
} 
संबंधित मुद्दे