Domanda

Vorrei avere un trigger per eseguire le seguenti operazioni per i record inseriti:

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

Più chiaramente: dire che ho una tabella con tre colonne: id chiave primaria, group_id int, value varchar.

Quando inserisco con group_id in questo modo:

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

Mi piacerebbe avere:

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

ma quando ometto group_id :

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

dovrebbe essere automaticamente impostato su id di questo record:

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

È possibile con un trigger? (So ??di poter aggiornare il record dopo averlo inserito ma avere il trigger sarebbe più bello.)

È stato utile?

Soluzione

Non conosco alcun modo per farlo in una sola istruzione, anche usando un trigger.

La soluzione trigger suggerita da @Lucky sarebbe simile a questa in MySQL:

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

Tuttavia, c'è un problema. Nella fase PRIMA DELL'INSERIMENTO , il valore id generato automaticamente non è stato ancora generato. Quindi se group_id è null, il valore predefinito è NEW.id che è sempre 0.

Ma se cambi questo trigger in modo che si attivi durante la fase AFTER INSERT , quindi hai accesso al valore generato di NEW.id , non puoi modificare la colonna valori.

MySQL non supporta le espressioni per il DEFAULT di una colonna, quindi non puoi nemmeno dichiarare questo comportamento nella definizione della tabella.

L'unica soluzione è fare il INSERT , quindi fare immediatamente un UPDATE per cambiare il group_id se non è impostato.

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

Altri suggerimenti

Sto rispondendo qui, come nella risposta accettata Bill Karwin afferma:

  

Nella fase PRIMA DELL'INSERIMENTO, il valore ID generato automaticamente non è stato   generato ancora. Quindi, se group_id è null, il valore predefinito è NEW.id che è   sempre 0.


Ho una risposta per questo - per OP (e per i visitatori a venire), ecco alcuni punti: Non è possibile aggiornare la tabella da cui viene richiamato il trigger, poiché verrà visualizzato Errore 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.per aggiornare la nuova riga Utilizzare il trigger PRIMA DI INSERIRE , in questo modo è possibile aggiornare tutti i campi per la nuova riga, accessibili tramite NUOVO operatore, ad es.

set NEW.group_id = NEW.id

2. Ottieni il valore di incremento automatico prima di inserire :

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

Per riassumere: il trigger SQL per "dovrebbe essere qualcosa come il seguente:

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 ;

Questo funziona per me

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 ;

Credo che questo funzionerà per te

Ho due tabelle

test_b: a_id, value
test_c: a_id, value

Ed ecco un trigger sull'inserimento del test b. Verifica se a_id è null e se lo è inserisce 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)

Questo trigger dovrebbe fare quello che hai chiesto.

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

Viene copiato da un esempio molto simile nella documentazione MYSQL pagina

Un trigger sembra eccessivo in questa situazione. Basta applicare un valore predefinito.

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'
)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top