Postgresql insertar disparador para establecer el valor
Supongamos que en Postgresql, tengo una tabla T
y una de sus columnas es C1
.
Quiero activar una función cuando se agrega un nuevo registro a la tabla T
. La función debe comprobar el valor de la columna C1
en el nuevo registro y si es null/empty entonces establecer su valor a 'X'
.
Es esto posible?
2 answers
Tiene razón en que necesita un disparador, porque establecer un valor predeterminado para la columna no funcionará para usted: los valores predeterminados solo funcionan para los valores null
y no le ayudan a evitar valores en blanco.
En postgres hay un par de pasos para crear un disparador:
Paso 1: Cree una función que devuelva el tipo trigger
:
CREATE FUNCTION my_trigger_function()
RETURNS trigger AS '
BEGIN
IF NEW.C1 IS NULL OR NEW.C1 = '''' THEN
NEW.C1 := ''X'';
END IF;
RETURN NEW;
END' LANGUAGE 'plpgsql'
Paso 2: Crear un disparador que dispara antes de insertar, que le permite cambiar los valores antes de que se insertan, que invoca el función anterior:
CREATE TRIGGER my_trigger
BEFORE INSERT ON T
FOR EACH ROW
EXECUTE PROCEDURE my_trigger_function()
Y ya está.
Ver el código anterior ejecutándose en SQLFiddle demostrando que funciona correctamente!
Mencionas en un comentario que el valor 'X'
se recupera de una subconsulta. Si es así, cambie la línea relevante para algo así como:
NEW.C1 := (select some_column from some_table where some_condition);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-19 13:32:23
Es posible, pero es probable que sea mejor establecer una restricción predeterminada en la columna en su lugar. Al crear la tabla que se vería como:
create table mytable as (
C1 thetype not null default X
);
Esto dice que si agrega una fila a la tabla y no especifica el valor para C1, entonces se usará X en su lugar. El valor not null no es necesario, pero evita que las actualizaciones anulen esa columna asumiendo que eso es lo que desea.
EDITAR: Esto solo funciona para la constante X, de sus comentarios parece que hay dos posibles solución.
Usando un disparador se vería algo como esto:
create function update_row_trigger() returns trigger as $$
begin
if new.C1 is NULL then
new.C1 := X;
end if;
return new;
end
$$ language plpgsql;
create trigger mytrigger before insert on mytable for each row execute procedure update_row_trigger();
La variable new
en una función de activación es especial, representando la fila que se inserta. Especificar el desencadenador como un desencadenador before insert
significa que puede modificar la fila antes de que se escriba en la tabla.
La segunda solución sería usar una columna calculada que Postgres define de una manera inusual:
create or replace function C1(row mytable) returns columntype immutable as $$
begin
return X; -- where X is an expression using values from `row`
end
$$ language plpgsql;
Esto crea una función que toma una fila de su tabla y devuelve un valor, puede llamar está usando . notación sin embargo, lo que significa que se puede hacer:
select
*,
t.C1
from
mytable t;
La declaración de que la función es inmutable es opcional, pero es necesaria si desea indexar la "columna". Usted sería capaz de indexar esta columna como esta:
create index on mytable (C1(mytable));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-19 11:06:32