Frage

Ich möchte einen Auslöser für den folgenden Vorgang für eingefügte Datensätze ausführen:

 # pseudocode
 if new.group_id is null
    set new.group_id = new.id
 else
    # don't touch it
 end

Genauer gesagt: Sagen Sie, ich habe eine Tabelle mit drei Spalten: id Primärschlüssel, group_id int, value varchar.

Wenn ich mit einfüge mit group_id so wie das:

INSERT INTO table(value, group_id) VALUES ('a', 10)

Ich hätte gerne:

id | group_id | value
---+----------+------
 1 |       10 | a

Aber wenn ich weglässt group_id:

INSERT INTO table(value) VALUES ('b')

Es sollte automatisch auf die festgelegt werden id dieser Aufzeichnung:

id | group_id | value
---+----------+------
 2 |        2 | b

Ist es mit einem Auslöser möglich? (Ich weiß, ich kann den Datensatz nach dem Einfügen aktualisieren, aber der Auslöser wäre schöner.)

War es hilfreich?

Lösung

Ich weiß keine Möglichkeit, dies in einer Aussage zu tun, selbst wenn ich einen Auslöser benutze.

Die Trigger -Lösung, die @Lucky vorgeschlagen hat, würde in MySQL so aussehen:

CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
  SET NEW.group_id = COALESCE(NEW.group_id, NEW.id);
END

Es gibt jedoch ein Problem. In dem BEFORE INSERT Phase, die automatisch generierte id Wert wurde noch nicht generiert. Also wenn group_id ist NULL, es wird standardmäßig angelegt NEW.id Welches ist immer 0.

Aber wenn Sie diesen Auslöser in das Feuer während deses ändern AFTER INSERT Phase, also haben Sie Zugriff auf den generierten Wert von NEW.id, Sie können die Spaltenwerte nicht ändern.

MySQL unterstützt keine Ausdrücke für die DEFAULT einer Spalte, so dass Sie dieses Verhalten auch in der Tabellendefinition nicht deklarieren können.

Die einzige Lösung besteht darin, das zu tun INSERT, und dann sofort eine machen UPDATE um es zu ändern group_id Wenn es nicht festgelegt ist.

INSERT INTO MyTable (group_id, value) VALUES (NULL, 'a');
UPDATE MyTable SET group_id = COALESCE(group_id, id) WHERE id = LAST_INSERT_ID();

Andere Tipps

Ich antworte hier, wie in der akzeptierten Antwort Bill Karwin Zustände:

In der Voreinfügungsphase wurde der automatisch generierte ID-Wert noch nicht generiert. Also, wenn Group_id null ist, ist es standardmäßig mit New.id, was immer 0 ist.


Ich habe eine Antwort darauf - für OP (und die zu kommenden Besucher) sind hier nur wenige Punkte: Sie können die Tabelle nicht aktualisieren, wo der Trigger aufgerufen wird, denn sie erhalten Sie Fehler 1442:

Error Code: 1442
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

1. Um die neue Zeile zu aktualisierenVerwenden BEFORE INSERT ON Auf diese Weise können Sie alle Felder für die neue Zeile aktualisieren, auf die über einen neuen Bediener -IE zugegriffen werden kann

set NEW.group_id = NEW.id

2.GET AUTO_INCREMENT -Wert vor dem Einfügen:

SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='MyTable'

Zusammenfassend - der Trigger SQL für 'D ist etwas wie folgt:

DELIMITER //
DROP TRIGGER IF EXISTS MyTrigger//
CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
    IF new.group_id IS NULL
        set @auto_id := (SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES
                         WHERE TABLE_NAME='MyTable' AND TABLE_SCHEMA=DATABASE() ); 
        set NEW.group_id = @auto_id;
    ENF IF;
END;
//
DELIMITER ;

Das funktioniert für mich

DELIMITER $$
CREATE TRIGGER `myTriggerNameHere`
BEFORE INSERT ON `table` FOR EACH ROW
BEGIN
    SET NEW.group_id = IF(NEW.group_id IS NULL, LAST_INSERT_ID()+1, NEW.group_id);
END;
$$
DELIMITER ;

Ich glaube, dass dies für Sie funktionieren wird

Ich habe zwei Tische

test_b: a_id, value
test_c: a_id, value

Und hier ist ein Auslöser am Einsatz des Tests b. Es prüft, ob a_id null ist und ob es sich um 0 einfügt. 0

CREATE TRIGGER test_b AFTER INSERT ON test_b
  FOR EACH ROW 
    INSERT INTO test_c (a_id, value) VALUES (IFNULL(NEW.a_id, 0),NEW.value)

Dieser Auslöser sollte das tun, was Sie gefragt haben.

   CREATE TRIGGER mytrigger BEFORE INSERT ON mytable
          IF new.group_id IS NULL
            SET new.group_id = new.id
          END IF
      END;

Es wird von einem sehr ähnlichen Beispiel in der kopiert MySQL -Dokumentation Seite.

Ein Auslöser scheint in dieser Situation übertrieben zu sein. Wenden Sie einfach einen Standard an.

CREATE TABLE `test` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `value` varchar(100) NOT NULL,
    `group_id` TINYINT(3) UNSIGNED NOT NULL DEFAULT '2'
)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top