Saya menggunakan prosedur tersimpan rekursif di MySQL untuk menghasilkan tabel sementara bernama id_list
, tapi saya harus menggunakan hasil prosedur itu dalam tindak lanjut pilih kueri, jadi saya tidak bisa DROP
tabel sementara dalam prosedur ...
BEGIN;
/* generates the temporary table of ID's */
CALL fetch_inheritance_groups('abc123',0);
/* uses the results of the stored procedure in the WHERE */
SELECT a.User_ID
FROM usr_relationships r
INNER JOIN usr_accts a ON a.User_ID = r.User_ID
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
GROUP BY r.User_ID;
COMMIT;
Saat memanggil prosedur, nilai pertama adalah ID teratas dari cabang yang saya inginkan, dan yang kedua adalah tier
yang digunakan prosedur selama rekursi. Sebelum loop rekursif ia memeriksa apakah tier = 0
dan apakah itu berjalan:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
Jadi pertanyaan saya adalah: Jika saya tidak tabel DROP
sementara MEMORY
di akhir prosedur, atau dalam transaksi saya, berapa lama tabel itu akan bertahan dalam memori? Apakah itu secara otomatis terjatuh setelah sesi berakhir, atau akankah itu tetap ada dalam memori selama koneksi terbuka?
** NB Jawaban yang jelas mungkin untuk menjatuhkan tabel temp sebelum pernyataan komit, tetapi mari kita asumsikan sejenak bahwa saya tidak bisa melakukan itu. *
EDIT : Untuk menjadi sedikit lebih tepat, bagaimana jika koneksi persisten digunakan, akankah tabel bertahan melalui beberapa permintaan? Sejauh ini tampaknya itu akan dan bahwa kita akan perlu secara eksplisit menghapus tabel temp untuk membebaskan sumber daya itu.
PEMBARUAN : Berdasarkan saran dari para komentator, saya telah menemukan cara untuk menyesuaikan prosedur tersimpan saya sehingga saya dapat memanfaatkan tabel TEMP MEMORY, tetapi dapat secara eksplisit DROP
di akhir ...
Daripada hanya memanggil prosedur tersimpan dan menggunakan tabel TEMP yang tersisa untuk mengumpulkan hasil dalam kueri yang sebenarnya, saya telah mengubah CALL
format untuk menggunakan OUT
variabel ketiga seperti:
CALL fetch_inheritance_groups('abc123','0',@IDS);
... lalu dalam prosedur tersimpan, saya menambahkan sedetik IF tier = 0
di bagian paling akhir dengan yang berikut:
IF tier = 0
THEN
SELECT GROUP_CONCAT(DISTINCT iid SEPARATOR ',') FROM id_list INTO inherited_set;
DROP TEMPORARY TABLE IF EXISTS id_list;
END IF;
Jadi hasil dari prosedur yang tersimpan sekarang adalah daftar ID yang dipisahkan koma yang kompatibel dengan FIND_IN_SET
, dan permintaan akhir telah dimodifikasi sehingga:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... sekarang ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! Terima kasih kepada komentator atas masukan Anda, dan untuk memberi saya alasan saya perlu mencoba sedikit lebih keras :)
DROP
MEMORY sementara meja. Apakah saya berasumsi dengan benar?