Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

167
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda