delete.sql 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. --
  2. PRAGMA foreign_keys = ON;
  3. PRAGMA recursive_triggers = ON;
  4. PRAGMA encoding = "UTF-8";
  5. ----------------------------------------------------------------------------------------
  6. -- create structure
  7. ----------------------------------------------------------------------------------------
  8. -- https://www.sqlite.org/lang_droptrigger.html
  9. DROP TRIGGER IF EXISTS master_delete;
  10. DROP TRIGGER IF EXISTS ms_insert;
  11. DROP TRIGGER IF EXISTS ms_delete;
  12. -- https://www.sqlite.org/lang_dropview.html
  13. DROP VIEW IF EXISTS ms;
  14. -- https://www.sqlite.org/lang_droptable.html
  15. DROP TABLE IF EXISTS master;
  16. DROP TABLE IF EXISTS slave;
  17. -- https://www.sqlite.org/lang_createtable.html
  18. CREATE TABLE slave (
  19. id INTEGER PRIMARY KEY
  20. );
  21. CREATE TABLE master (
  22. id INTEGER PRIMARY KEY
  23. ,rel INTEGER NOT NULL REFERENCES slave(id) -- ON DELETE CASCADE
  24. );
  25. -- https://www.sqlite.org/lang_createtrigger.html
  26. CREATE TRIGGER master_delete AFTER DELETE ON master
  27. FOR EACH ROW
  28. -- WHEN NOT EXISTS (SELECT id FROM master WHERE rel = old.rel)
  29. -- WHEN (0=(SELECT COUNT(id) FROM master WHERE rel = old.rel))
  30. BEGIN
  31. DELETE FROM slave WHERE id = OLD.rel AND (0=(SELECT COUNT(id) FROM master WHERE rel = OLD.rel));
  32. END;
  33. -- https://www.sqlite.org/lang_createview.html
  34. CREATE VIEW ms AS SELECT
  35. master.id AS id
  36. ,slave.id AS rel
  37. FROM master
  38. INNER JOIN slave ON master.rel = slave.id;
  39. CREATE TRIGGER ms_insert INSTEAD OF INSERT ON ms
  40. FOR EACH ROW BEGIN
  41. INSERT OR IGNORE INTO slave(id) VALUES(NEW.rel);
  42. -- SELECT LAST_INSERT_ROWID(); into a temp table.
  43. INSERT INTO master(id,rel) VALUES(NEW.id,NEW.rel);
  44. END;
  45. CREATE TRIGGER ms_delete INSTEAD OF DELETE ON ms
  46. FOR EACH ROW BEGIN
  47. DELETE FROM master WHERE id = OLD.id;
  48. DELETE FROM slave WHERE (0=(SELECT COUNT(id) FROM master WHERE rel = OLD.rel)) AND id = OLD.rel;
  49. END;
  50. ----------------------------------------------------------------------------------------
  51. -- populate
  52. ----------------------------------------------------------------------------------------
  53. -- https://www.sqlite.org/lang_insert.html
  54. INSERT INTO slave (id) VALUES (2);
  55. INSERT INTO slave (id) VALUES (3);
  56. INSERT INTO master (id,rel) VALUES (20,2);
  57. INSERT INTO master (id,rel) VALUES (21,2);
  58. INSERT INTO master (id,rel) VALUES (30,3);
  59. INSERT INTO master (id,rel) VALUES (31,3);
  60. INSERT INTO ms (id,rel) VALUES (40,4);
  61. INSERT INTO ms (id,rel) VALUES (41,4);
  62. ----------------------------------------------------------------------------------------
  63. -- delete some
  64. ----------------------------------------------------------------------------------------
  65. -- https://www.sqlite.org/lang_delete.html
  66. DELETE FROM master WHERE id=20;
  67. DELETE FROM master WHERE id=21;
  68. -- DELETE FROM slave WHERE id=2;
  69. DELETE FROM ms WHERE id=40;
  70. DELETE FROM ms WHERE id=41;
  71. ----------------------------------------------------------------------------------------
  72. -- print result
  73. ----------------------------------------------------------------------------------------
  74. -- https://www.sqlite.org/lang_select.html
  75. SELECT
  76. master.id
  77. ,slave.id
  78. FROM master
  79. LEFT JOIN slave ON master.rel = slave.id
  80. UNION
  81. SELECT
  82. master.id
  83. ,slave.id
  84. FROM slave
  85. LEFT JOIN master ON master.rel = slave.id
  86. ORDER BY master.id,slave.id;