2012-02-20 13 views
9

Por ejemplo:¿Puedo actualizar Nuevo en antes de insertar el disparador en sqlite?

create table test (id numeric, t date not null); 

create trigger test_in 
before insert on test 
for each row 
when New.t is null 
begin 
-- set New.t = now(); 
end; 

Conjunto New.t no funcionó, where can be only select/insert/update/delete stmt. No puedo cambiar la estructura de base de datos (se puede establecer el valor por defecto). Después del disparo de inserción tampoco es adecuado debido a la restricción "no nula". La única solución que he encontrado:

insert into test values (New.id, now()); 
select raise(ignore); 

base de datos de prueba para fines ilustrativos, en la práctica hay casos más complicados con los datos calculados. Puede haber algo así como "update New set New.t = now()", o no?

+0

¿Se puede crear una vista con un gatillo INSTEAD OF e insertarlo en la vista? –

+0

También es una variante de la decisión, pero no resuelve el problema. En mi caso, las tablas se crean en el proceso de sincronización. Puedo ejecutar cualquier ddl después. – lunicon

+0

En el modelo de la base de datos principal también se usa trigger con set stmt. Puedo crear una vista, pero tendré que cambiarla y programarla (si puedo ...) – lunicon

Respuesta

6

No, no puedes actualizar NUEVO.

Lo que suelo hacer es usar una VISTA con un gatillo INSTEAD OF ya que mu es para comentarios cortos.

En su caso, la mejor solución puede ser utilizar un después desencadenador de inserción/actualización cuando NEW.t IS NULL para actualizar t en la fila afectada (s):

CREATE TRIGGER test_in 
AFTER INSERT ON test 
FOR EACH ROW 
WHEN (NEW.t IS NULL) 
BEGIN 
    UPDATE test SET t = now() WHERE id = NEW.id; 
END; 

FYI, la columna debe id probablemente se declare como INTEGER PRIMARY KEY ...

+0

No encajo esta opción debido a la restricción "no nulo" - inserción fallida con nulo :(PS y no debe confundirse con los recién llegados, mejor use la actualización ... donde rowid = new.rowid – lunicon

+0

Bueno, dado que tiene este disparador t no será NULL, por lo que puede soltar esa restricción. En cuanto a rowid ... insinué eso, pero tiene razón en que los recién llegados pueden no entender la pista. Por otro lado, no todos los RDBMS siempre tienen rowids. Sí, SQLite3 básicamente siempre tiene un rowid, _but_ puedes tener columnas llamadas 'rowid' que no son INTEGER PRIMARY KEY, así que sentí que sería más seguro recomendar que tengas una INTEGER PRIMARY KEY explícita. – Nico

Cuestiones relacionadas