所以这是我的问题,我编写了一个存储过程来执行以下任务。在表events
中,对于不再存在的场所可能存在可能存在的事件。并非所有事件都与场地相关联,而是在场地ID字段中具有整数值的事件,否则它是NULL(或者可能为零,但是会被考虑)。场地会定期从我们的系统中删除,当发生这种情况时,无法在该确切时间删除与该场地相关的所有事件。相反,稍后定期运行任务,删除具有不再引用场地表中现有记录的场地ID的每个事件。我为此编写了一个存储过程,它似乎工作。
这是存储过程:
DROP PROCEDURE IF EXISTS delete_synced_events_orphans;
DELIMITER $$
CREATE PROCEDURE delete_synced_events_orphans()
BEGIN
DECLARE event_count int(11) DEFAULT 0;
DECLARE active_event_id int(11) DEFAULT 0;
DECLARE active_venue_id int(11) DEFAULT 0;
DECLARE event_to_delete_id int(11) DEFAULT NULL;
CREATE TEMPORARY TABLE IF NOT EXISTS possible_events_to_delete (
event_id int(11) NOT NULL,
venue_id_temp int(11) NOT NULL
) engine = memory;
# create an "array" which is a table that holds the events that might need deleting
INSERT INTO possible_events_to_delete (event_id, venue_id_temp) SELECT `events`.`id`, `events`.`venue_id` FROM `events` WHERE `events`.`venue_id` IS NOT NULL AND `events`.`venue_id` <> 0;
SELECT COUNT(*) INTO `event_count` FROM `possible_events_to_delete` WHERE 1;
detector_loop: WHILE `event_count` > 0 DO
SELECT event_id INTO active_event_id FROM possible_events_to_delete WHERE 1 LIMIT 1;
SELECT venue_id_temp INTO active_venue_id FROM possible_events_to_delete WHERE 1 LIMIT 1;
# this figures out if there are events that need to be deleted
SELECT `events`.`id` INTO event_to_delete_id FROM `events`, `venues` WHERE `events`.`venue_id` <> `venues`.`id` AND `events`.`id` = active_event_id AND `events`.`venue_id` = active_venue_id;
#if no record meets that query, the active event is safe to delete
IF (event_to_delete_id <> 0 AND event_to_delete_id IS NOT NULL) THEN
DELETE FROM `events` WHERE `events`.`id` = event_to_delete_id;
#INSERT INTO test_table (event_id_test, venue_id_temp_test) SELECT `events`.`id`, `events`.`venue_id` FROM `events` WHERE `events`.`id` = event_to_delete_id;
END IF;
DELETE FROM possible_events_to_delete WHERE `event_id` = active_event_id AND `venue_id_temp` = active_venue_id;
SET `event_count` = `event_count` - 1;
END WHILE;
END $$
DELIMITER ;
以下是两个表的表结构:
CREATE TABLE IF NOT EXISTS events (
id int(11) NOT NULL,
event_time timestamp NOT NULL,
venue_id_temp int(11) NOT NULL
);
CREATE TABLE IF NOT EXISTS venues (
event_id int(11) NOT NULL,
venue_id_temp int(11) NOT NULL
);
存储过程按照书面形式工作,但我想知道如何使其更好地运行。它似乎做了很多额外的处理来实现它的目标。有没有更好的方法可以查询手头的数据,或者是否有其他更有用的命令和我可以使用的关键词,我只是不知道,这将使我能够更好地完成这项任务(更少的线路更少的计算)。我仍然在学习如何使用存储过程,所以我使用它们尽可能实用地完成任务,我想了解如何进行这个特定的查询以更好地利用MySQL的全部功能。谢谢大家。
答案 0 :(得分:2)
Everithing更简单:
DROP PROCEDURE IF EXISTS delete_synced_events_orphans;
DELIMITER $$
CREATE PROCEDURE delete_synced_events_orphans()
BEGIN
DELETE
FROM `events`
WHERE `venue_id` IS NOT NULL AND `venue_id` <> 0
AND `venue_id` NOT IN (SELECT `id` FROM `venues`)
;
END $$
DELIMITER ;
那就是它。 :)
你认为当务之急,试图说MySQL 如何来完成你的任务。但SQL是一种声明性语言,旨在说明要做什么。