この質問は、行の削除時に同じテーブルを更新する必要が ある以前の質問の順序です。
trigger または nested-query の代わりに Stored Procedureを使用して 2 つのソリューションを作成できます。
どちらもヘルパー関数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//
- 2番目の解決策:前の質問で提案されたように
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//
ここで、結合を使用すると効率的な SELECT が効率的であることを読みました。しかし、私の問題にはテーブルが1つしか含まれておらず、結合が比較的メモリを消費するため、私のソリューション(最初)は2番目よりもはるかに効率的だと感じています。
Employee table
が十分に大きい場合、どちらがより効率的であるかを提案してください。私にとってどちらが良いですか?理由
編集: 小さなテーブルが7行のみで構成されていることを確認しましたが、両方のソリューションに同じ時間がかかります。
mysql> CALL delete_employee(4);
Query OK, 1 row affected (0.09 sec)
テーブルヒューリスティックのため、SQL関数が非決定論的に動作することを私は知っています。どちらの選択が良いですか?クエリをさらに最適化する方法について何らかの考えがある場合。