这个问题是我之前的问题的顺序,要求在删除一行时更新同一张表。
我可以使用存储过程而不是触发器或嵌套查询 来编写两个解决方案。
两者都使用辅助函数my_signal(msg)。
从Employee
表中删除员工的存储过程。
- 拳头解决方案:使用
UPDATE
表中的行,无需连接操作:
CREATE PROCEDURE delete_employee(IN dssn varchar(64)) BEGIN DECLARE empDesignation varchar(128); DECLARE empSsn varchar(64); DECLARE empMssn varchar(64); SELECT SSN, designation, MSSN INTO empSsn, empDesignation, empMssn FROM Employee WHERE SSN = dssn; IF (empSsn IS NOT NULL) THEN CASE WHEN empDesignation = 'OWNER' THEN CALL my_signal('Error: OWNER can not deleted!'); WHEN empDesignation = 'WORKER' THEN DELETE FROM Employee WHERE SSN = empSsn; WHEN empDesignation = 'BOSS' THEN BEGIN UPDATE Employee SET MSSN = empMssn WHERE MSSN = empSsn; DELETE FROM Employee WHERE SSN = empSsn; END; END CASE; ELSE CALL my_signal('Error: Not a valid row!'); END IF; END//
- 第二种解决方案:正如我在上一个问题中建议的那样,使用
INNER JOIN
CREATE PROCEDURE delete_employee(IN dssn varchar(64)) BEGIN DECLARE empDesignation varchar(128); DECLARE empSsn varchar(64); DECLARE empMssn varchar(64); SELECT SSN, designation, MSSN INTO empSsn, empDesignation, empMssn FROM Employee WHERE SSN = dssn; IF (empSsn IS NOT NULL) THEN IF (empDesignation = 'OWNER') THEN CALL my_signal('Error: OWNER can not deleted!'); END IF; UPDATE `Employee` A INNER JOIN `Employee` B ON A.SSN= B.MSSN SET B.MSSN = A.MSSN WHERE A.SSN = empSsn; DELETE FROM `Employee` WHERE SSN = empSsn; ELSE CALL my_signal('Error: Not a valid row!'); END IF; END//
我在这里读到,使用 join 对于 Efficient SELECT 是有效的。但是我的问题只包括一个表,我觉得我的解决方案(第一个)比第二个更有效,因为 join 会比较消耗内存。
Employee table
如果足够大,请建议我哪个更好,更有效。哪个更适合我?原因
编辑: 我检查了只包含 7 行的小表,两种解决方案都需要相同的时间。
mysql> CALL delete_employee(4);
Query OK, 1 row affected (0.09 sec)
我知道 SQL 函数的行为是不确定的,因为表启发式。哪个选择更好?如果您有一些想法,可以进一步优化查询。