ฉันใช้โพรซีเดอร์ที่จัดเก็บแบบเรียกซ้ำใน MySQL เพื่อสร้างตารางชั่วคราวที่เรียกว่าid_list
แต่ฉันต้องใช้ผลลัพธ์ของโพรซีเดอร์นั้นในแบบสอบถามแบบติดตามผลดังนั้นฉันจึงไม่สามารถDROP
ใช้ตารางชั่วคราวภายในโพรซีเดอร์ ...
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;
เมื่อเรียกโปรซีเจอร์ค่าแรกคือ ID บนสุดของแบรนช์ที่ฉันต้องการและที่สองคือtier
โพรซีเดอร์ที่ใช้ในระหว่างการเรียกซ้ำ ก่อนการวนซ้ำแบบซ้ำมันจะตรวจสอบว่าtier = 0
มันทำงานอยู่หรือไม่:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
ดังนั้นคำถามของฉันคือ: ถ้าฉันไม่ตารางDROP
ชั่วคราวMEMORY
เมื่อสิ้นสุดขั้นตอนหรือในการทำธุรกรรมของฉันตารางนั้นจะอยู่ในหน่วยความจำนานแค่ไหน มันจะลดลงโดยอัตโนมัติเมื่อเซสชั่นสิ้นสุดหรือจะยังคงอยู่ในหน่วยความจำตราบใดที่การเชื่อมต่อเปิด?
** NB คำตอบที่ชัดเจนอาจวางตาราง temp ก่อนคำสั่ง commit แต่ลองสมมติสักครู่ว่าฉันไม่สามารถทำได้ *
แก้ไข : หากต้องการความแม่นยำมากขึ้นอีกเล็กน้อยจะเกิดอะไรขึ้นหากมีการใช้การเชื่อมต่อแบบถาวรตารางจะคงอยู่ตามคำขอหลายคำขอหรือไม่ จนถึงตอนนี้ดูเหมือนว่ามันจะและเราจะต้องลบตารางชั่วคราวเพื่อเพิ่มทรัพยากรนั้น
อัปเดต : ตามคำแนะนำจากผู้แสดงความคิดเห็นฉันได้พบวิธีการปรับขั้นตอนการจัดเก็บของฉันเพื่อที่ฉันจะสามารถใช้ตารางหน่วยความจำ TEMP ได้ แต่สามารถสรุปDROP
ได้ในตอนท้าย ...
แทนที่จะเรียกขั้นตอนการจัดเก็บและใช้ตาราง TEMP ที่เหลือเพื่อรวบรวมผลลัพธ์ในการสืบค้นจริงฉันเปลี่ยนCALL
รูปแบบการใช้OUT
ตัวแปรตัวที่สามดังนี้
CALL fetch_inheritance_groups('abc123','0',@IDS);
... จากนั้นภายในโพรซีเดอร์ที่เก็บไว้ฉันเพิ่มวินาทีIF tier = 0
ในตอนท้ายด้วย:
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;
ดังนั้นผลลัพธ์ของกระบวนงานที่เก็บไว้ในขณะนี้จึงเป็นรายการที่คั่นด้วยเครื่องหมายจุลภาคของ ID ที่เข้ากันได้FIND_IN_SET
และดังนั้นแบบสอบถามสุดท้ายจึงถูกแก้ไขเพื่อให้:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... ตอนนี้ ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! ขอบคุณผู้แสดงความคิดเห็นสำหรับการป้อนข้อมูลของคุณและให้เหตุผลที่ฉันต้องลองให้หนักขึ้นหน่อย :)
DROP
ทำการลบหน่วยความจำชั่วคราวอย่างชัดเจนโต๊ะ. ฉันถือว่าถูกต้องหรือไม่