Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

166
Views
Desencadenadores de actualización de SQL en el índice de restricción

Tengo una columna dentro de una tabla que puede tomar uno de estos tres valores: 'past', 'present', 'future'

Sin embargo, solo una fila puede tener el valor 'presente'. Esto está siendo verificado por un índice de restricción único simple. Aún así, quiero que, cuando llegue el momento, alguien haga manualmente una fila 'futura' en la fila 'presente', para activar una función. Después de crear el activador e intentar probarlo actualizando manualmente una fila 'futura' a la fila 'presente', como era de esperar, recibí el siguiente error:

ERROR: duplicate key value violates unique constraint "semester_status_present" DETAIL: Key (semester_status)=(present) already exists.

Pensarlo por un minuto es completamente lógico, pero ¿qué puedo hacer en este caso? ¿Está el índice fuera de lugar?

esta es la restricción de índice:

 CREATE UNIQUE INDEX semester_status_present ON public."Semester" USING btree (semester_status) WHERE semester_status = 'present'::semester_status;

¡gracias de antemano!

¡EDITAR!: ¡El disparador convierte la fila actual anterior en una fila pasada también! Sin embargo, el desencadenante es after update on "Semester" , ya que evita el ciclo de actualización infinito

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Utilice un activador anterior para que pueda cambiar la fila actual existente a una fila anterior antes de que la actualización intente crear una segunda fila actual y rompa la restricción.

Función de disparo.

 create function swap_present() returns trigger as $$ begin update "Semester" set semester_status = 'past' where semester_status = 'present'::semester_status and id != new.id; return new; end; $$ language plpgsql;

Puse una verificación en new.id allí para que el activador no cambie la fila que está cambiando. Reemplace esto con cualquiera que sea la identificación única en su tabla.

Definición de disparador.

 create trigger semester_trigger before insert or update on "Semester" for each row when (new.semester_status = 'present'::semester_status) execute procedure swap_present();

La cláusula when significa que solo nos preocupamos si está cambiando o insertando una fila actual.

over 4 years ago · Santiago Trujillo Report

0

Dado que es un disparador posterior, el valor duplicado se produce cuando el futuro se convierte en la fila actual, pero antes de que la fila actual no se haya cambiado al pasado.

Intente cambiar su disparador a antes. Eso significaría que habría un momento en el tiempo en el que no hay fila 'presente' (el presente se cambia a pasado, el futuro aún no se ha cambiado a presente).

Espero que desee que esto se ejecute por declaración en lugar de por fila. Probablemente querrá agregar una condición para que solo se active cuando una fila futura se cambie a una fila actual. De esa forma, agregar nuevas filas futuras o cambiar las filas presentes/pasadas no aplicará el disparador.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!