In meiner Datenbank habe ich eine Tabelle Employee
, die rekursive Verein hat (Mitarbeiter Chef anderer Mitarbeiter sein kann):Wie aktualisiert die gleiche Tabelle beim Löschen in MYSQL?
create table if not exists `employee` (
`SSN` varchar(64) not null,
`name` varchar(64) default null,
`designation` varchar(128) not null,
`MSSN` varchar(64) default null,
primary key (`ssn`),
constraint `fk_manager_employee` foreign key (`mssn`) references employee(ssn)
) engine=innodb default charset=latin1;
mysql> describe Employee;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| SSN | varchar(64) | NO | PRI | NULL | |
| name | varchar(64) | YES | | NULL | |
| designation | varchar(128) | NO | | NULL | |
| MSSN | varchar(64) | YES | MUL | NULL | |
+-------------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
Dann fügt: Jetzt
mysql> insert into Employee values
-> ("1", "A", "OWNER", NULL),
-> ("2", "B", "BOSS", "1"),
-> ("3", "C", "WORKER", "2"),
-> ("4", "D", "BOSS", "2"),
-> ("5", "E", "WORKER", "4"),
-> ("6", "F", "WORKER", "1"),
-> ("7", "G", "WORKER", "4")
-> ;
Query OK, 7 rows affected (0.02 sec)
Records: 7 Duplicates: 0 Warnings: 0
Ich habe folgende hierarchische Beziehung (Besitzer> Chef> Arbeiter) unter den Zeilen in der Tabelle:
A
/\
B F
/\
c D
/\
G E
Es folgt Select-Anweisung für die Tabelle:
mysql> SELECT * FROM Employee;
+-----+------+-------------+------+
| SSN | name | designation | MSSN |
+-----+------+-------------+------+
| 1 | A | OWNER | NULL |
| 2 | B | BOSS | 1 |
| 3 | C | WORKER | 2 |
| 4 | D | BOSS | 2 |
| 5 | E | WORKER | 4 |
| 6 | F | WORKER | 1 |
| 7 | G | WORKER | 4 |
+-----+------+-------------+------+
7 rows in set (0.00 sec)
Nun, ich möchte eine Beschränkung auferlegen wie: If any employee (BOSS) deleted then new BOSS of workers under him become immediate BOSS of deleted employee (Old BOSS)
. z.B. Wenn ich lösche, dann B
Werde BOSS von G
und E
.
Dafür habe ich geschrieben auch ein Trigger- wie folgt:
mysql> DELIMITER $$
mysql> CREATE
-> TRIGGER `Employee_before_delete` BEFORE DELETE
-> ON `Employee`
-> FOR EACH ROW BEGIN
-> UPDATE Employee
-> SET MSSN=old.MSSN
-> WHERE MSSN=old.MSSN;
-> END$$
Query OK, 0 rows affected (0.07 sec)
mysql> DELIMITER ;
Aber wenn ich eine Löschung durchführen:
mysql> DELETE FROM Employee WHERE SSN='4';
ERROR 1442 (HY000): Can't update table 'Employee' in stored function/trigger
because it is already used by statement which invoked this stored
function/trigger.
ich learn here dass this trigger is not possible
weil In MySQL triggers can't manipulate the table they are assigned to
.
Gibt es einige anderen möglichen Weg, dies zu tun? Ist es möglich, Nested Query
zu verwenden? Kann mir jemand eine andere Methode vorschlagen? Ein Vorschlag wäre genug, sollte aber effizient sein.
EDIT:
ich Antworten bekommen: Statt Trigger ein stored procedure
oder two consecutive queries
möglich. First und second.
Die Lösung, die ich für dieses Problem wie unten beschrieben, funktioniert gut!:
- A eine Funktion Helfersignal als ich für
MYSQL version older then 5.5
schreibe.
DELIMITER //
CREATE PROCEDURE `my_signal`(in_errortext VARCHAR(255)) BEGIN SET @sql=CONCAT('UPDATE `', in_errortext, '` SET x=1'); PREPARE my_signal_stmt FROM @sql; EXECUTE my_signal_stmt; DEALLOCATE PREPARE my_signal_stmt; END//
- Eine Stored Procedure Mitarbeiter aus
Employee
Tabelle zu löschen.
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//
DELIMITER;
Können Sie Folgendes versuchen? Es sieht eher zu einfach für Ihre Anforderung speziell im Hinblick auf eine dynamische Deletion ... 'Update Employee' ' set MSSN = (wählen MSSN von employee' 'wo ssn = '4');' 'löschen von Mitarbeiter wo ssn = 4;' – bonCodigo
@bonCodigo: Sie meinen zwei aufeinander folgende Abfrage zum Löschen. Kann in Betracht gezogen werden ... Aber ich muss darüber nachdenken - Danke! –
Yeah zwei aufeinander folgende Abfragen. Es scheint auch, dass EntityFramework in SQL Server Repository-Muster bietet - es könnte Ihnen ermöglichen, die Löschfunktion des Repositorys über eine gespeicherte Prozedur rekursiv zu machen. Ich habe es nicht persönlich gemacht. Vielleicht könntest du das gleiche hier nachahmen. Interessante Frage +1 – bonCodigo