मेरे पास एक एकल तालिका है जहां शीर्ष स्तर की वस्तुओं के लिए parentId कॉलम 0 हो सकता है या अन्य वस्तुओं से संबंधित वस्तुओं के लिए एक संख्या हो सकती है। नेस्टिंग कितनी गहराई तक जा सकती है इसकी कोई सीमा नहीं है।

id     parentId     title
-------------------------
1      0            Item1
2      1            Item11
3      2            Item22
4      0            Item2
5      4            Item21

मैं जो चाहता हूं वह यह है कि हर बार जब मैं एक आइटम हटाता हूं, तो बच्चे के प्रत्येक बच्चे और बच्चे को हटा दिया जाता है, जब तक कि किसी आइटम में parentId मौजूद न हो।

मुझे पता है कि मैं नीचे के बच्चे से शुरू होने वाले रिकॉर्ड और क्वेरी DELETE के माध्यम से लूप कर सकता हूं लेकिन मुझे आश्चर्य है कि यह केवल SQLite कमांड के साथ किया जा सकता है

2
bmalex 12 सितंबर 2020, 02:32

2 जवाब

सबसे बढ़िया उत्तर

आप तालिका को फिर से परिभाषित कर सकते हैं:

CREATE TABLE tablename (
  `id` INTEGER PRIMARY KEY,
  `parentId` INTEGER,
  `title` VARCHAR(6),
  FOREIGN KEY (`parentId`) REFERENCES tablename(`id`) ON DELETE CASCADE
);

ताकि कॉलम parentId कॉलम id को संदर्भित करने वाली एक विदेशी कुंजी हो, जो टेबल का PRIMARY KEY होना चाहिए या एक UNIQUE इंडेक्स/बाधा होनी चाहिए।

ON DELETE CASCADE क्रिया यह सुनिश्चित करती है कि जब आप एक पंक्ति हटाते हैं तो सभी बच्चों की पंक्तियाँ भी हटा दिया जाएगा (बच्चों की पंक्तियों के बच्चे वगैरह)।

साथ ही 0 के बजाय आपको शीर्ष स्तर के आइटम को null पर सेट करना होगा ताकि कोई विदेशी कुंजी बाधा उल्लंघन न हो।

आपको विदेशी कुंजी समर्थन को चालू चालू करना होगा क्योंकि यह डिफ़ॉल्ट रूप से बंद है और यह SQLiteOpenHelper की onConfigure() विधि से किया जा सकता है:

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

अब जब आप तालिका से एक पंक्ति हटाते हैं तो आपके द्वारा हटाई गई पंक्ति के स्तर के नीचे के स्तरों की सभी पंक्तियाँ भी हटा दी जाएँगी।

आपको डिवाइस से ऐप को अनइंस्टॉल करना पड़ सकता है ताकि डेटाबेस को हटा दिया जाए और डेटाबेस और तालिका को नई परिभाषा के साथ फिर से बनाने के लिए फिर से चलाया जाए।

एक डेमो देखें।

1
forpas 12 सितंबर 2020, 10:51

यह कोड id कॉलम या parentId कॉलम में "ID" वाली हर एक पंक्ति को हटा देगा:

void deleteItemAndChildren(String ID){
        //Deletes the row that has that ID in id column
        int deletedIdsCount = db.delete(tableName, "id=?", new String[]{ID});

        //Deletes the row that has that ID in parentId column
        int deletedChildrenCount = db.delete(tableName, "parentId=?", new String[]{ID});

        Log.i("CountOfDeletedRows", "was "+ ID +" Deleted: " + (deletedIdsCount>0) + " Count of children deleted: " + deletedChildrenCount );
}

चीयर्स!

0
khalid3e 12 सितंबर 2020, 03:41