Tôi đang sử dụng một thủ tục được lưu trữ đệ quy trong MySQL để tạo một bảng tạm thời được gọi id_list
, nhưng tôi phải sử dụng các kết quả của thủ tục đó trong một truy vấn chọn tiếp theo, vì vậy tôi không thể DROP
là bảng tạm thời trong quy trình ...
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;
Khi gọi thủ tục, giá trị đầu tiên là ID trên cùng của nhánh tôi muốn và giá trị thứ hai là tier
thủ tục sử dụng trong quá trình thu hồi. Trước vòng lặp đệ quy, nó kiểm tra xem tier = 0
và nếu nó chạy:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
Vì vậy, câu hỏi của tôi là: Nếu tôi không DROP
đặt MEMORY
bảng tạm thời ở cuối quy trình hoặc trong giao dịch của mình, bảng đó sẽ tồn tại trong bộ nhớ bao lâu? Là nó tự động bị hủy khi phiên kết thúc, hoặc nó sẽ vẫn còn trong bộ nhớ miễn là kết nối được mở?
** NB Câu trả lời rõ ràng có thể là bỏ bảng tạm thời trước câu lệnh cam kết, nhưng hãy giả sử trong giây lát rằng tôi không thể làm điều đó. *
EDIT : Nói chính xác hơn một chút, nếu kết nối liên tục được sử dụng, bảng có tồn tại qua nhiều yêu cầu không? Cho đến nay có vẻ như nó sẽ và chúng ta sẽ cần phải loại bỏ rõ ràng bảng tạm thời để giải phóng tài nguyên đó.
CẬP NHẬT : Dựa trên lời khuyên từ những người bình luận, tôi đã tìm ra cách điều chỉnh thủ tục được lưu trữ của mình để tôi có thể sử dụng bảng NHỚ NHỚ, nhưng DROP
cuối cùng có thể rõ ràng ...
Thay vì chỉ gọi thủ tục được lưu trữ và sử dụng bảng TEMP còn lại để thu thập kết quả trong truy vấn thực tế, tôi đã thay đổi CALL
định dạng để sử dụng OUT
biến thứ ba như sau:
CALL fetch_inheritance_groups('abc123','0',@IDS);
... sau đó trong thủ tục được lưu trữ, tôi đã thêm một giây IF tier = 0
ở cuối cùng với phần sau:
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;
Vì vậy, kết quả của thủ tục được lưu trữ bây giờ là danh sách ID được phân tách bằng dấu phẩy tương thích FIND_IN_SET
và do đó, truy vấn cuối cùng đã được sửa đổi để:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... Hiện tại là ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! Cảm ơn các bình luận viên cho đầu vào của bạn, và đã cho tôi lý do tôi cần phải cố gắng hơn một chút :)
DROP
NHỚ bàn. Tôi có giả định đúng không?