sql >> Base de Datos >  >> RDS >> PostgreSQL

PostgreSQL:establezca un valor de celda predeterminado de acuerdo con otro valor de celda

Esto no es posible con un simple DEFAULT valor, como dice claramente el manual:

El valor es cualquier expresión libre de variables (no se permiten subconsultas ni referencias cruzadas a otras columnas de la tabla actual).

Podrías usar un gatillo en cambio:

CREATE OR REPLACE FUNCTION trg_foo_b_default()
  RETURNS trigger
  LANGUAGE plpgsql AS
$func$
BEGIN
   -- For just a few constant options, CASE does the job:
   NEW.b := CASE NEW.a
               WHEN 'peter'  THEN 'doctor'
               WHEN 'weirdo' THEN 'shrink'
               WHEN 'django' THEN 'undertaker'
               ELSE NULL
            END;

   /*
   -- For more, or dynamic options, consider a lookup table:
   SELECT INTO NEW.b  t.b
   FROM   def_tbl t
   WHERE  t.a = NEW.a;
   */

   RETURN NEW;
END
$func$;


CREATE TRIGGER b_default
BEFORE INSERT ON foo
FOR EACH ROW
WHEN (NEW.b IS NULL AND NEW.a IS NOT NULL)
EXECUTE PROCEDURE trg_foo_b_default();

Para hacerlo más eficiente, use un WHEN cláusula en la definición del disparador (disponible desde Postgres 9.0):De esta manera, la función disparadora solo se ejecuta cuando es realmente útil. (Suponiendo que podemos dejar que b IS NULL deslizar si a IS NULL .)

Funciona de forma similar, pero sutilmente diferente moda desde un DEFAULT value.
Con un valor predeterminado, puede insertar explícitamente NULL para anular el valor predeterminado. Eso no es posible aquí, NULL en b se reemplaza con el valor derivado de a .