Soy nuevo en PostgreSQL y me encanta cómo funcionan las restricciones con la seguridad de nivel de fila, pero no sé cómo hacer que hagan lo que quiero.
Tengo una columna y quiero agregar una restricción que cree una longitud mínima para una columna de texto, esta verificación funciona para eso:
(length((column_name):: text) > 6)PERO, también evita que los usuarios actualicen las filas donde column_name ya tiene menos de 6 caracteres.
Quiero hacerlo para que no puedan cambiar ese valor A eso, pero aún pueden actualizar una fila donde eso ya está sucediendo, para que puedan cambiarlo según sea necesario de acuerdo con mi nueva política.
es posible?
PERO, también evita que los usuarios actualicen las filas donde column_name ya tiene menos de 6 caracteres.
Bueno no. Cuando intenta agregar esa restricción CHECK , se verifican todas las filas existentes y se genera una excepción si se encuentra alguna infracción.
Tendrías que hacerlo NOT VALID . Entonces sí.
Realmente necesita un disparador en INSERT o UPDATE que verifique nuevos valores. No es tan barato ni tan resistente a las balas, pero sigue siendo bastante sólido. Me gusta:
CREATE OR REPLACE FUNCTION trg_col_min_len6() RETURNS trigger LANGUAGE plpgsql AS $func$ BEGIN IF TG_OP = 'UPDATE' AND OLD.column_name IS NOT DISTINCT FROM NEW.column_name THEN -- do nothing ELSE RAISE EXCEPTION 'New value for column "note" must have at least 6 characters.'; END IF; RETURN NEW; END $func$; -- trigger CREATE TRIGGER tbl1_column_name_min_len6 BEFORE INSERT OR UPDATE ON tbl FOR EACH ROW WHEN (length(NEW.column_name) < 7) EXECUTE FUNCTION trg_col_min_len6();db<>violín aquí
Debería ser más eficiente verificar una condición WHEN para el disparador directamente. Entonces, la función de disparo solo se llama para valores cortos y puede ser súper simple.
Ver:
Puede crear activadores independientes para Insertar y Actualizar, lo que permite que cada uno defina por completo cuándo debe activarse. Si se requiere una lógica completamente diferente para la acción DML, esta técnica permite escribir funciones de activación dedicadas. En este caso, no se requiere que la función de activación se reduzca para raise exception ... . Ver demostración
-- Single trigger function for both Insert and Delete create or replace function trg_col_min_len6() returns trigger language plpgsql as $$ begin raise exception 'Cannot % val = ''%''. Must have at least 6 characters.' , tg_op, new.val; return null; end; $$; -- trigger before insert create trigger tbl_val_min_len6_bir before insert on tbl for each row when (length(new.val) < 6) execute function trg_col_min_len6(); -- trugger before update create trigger tbl_val_min_len6_bur before update on tbl for each row when ( length(new.val) < 6 and new.val is distinct from old.val ) execute function trg_col_min_len6();