Vous n'êtes pas identifié(e).
Pages : 1
Bonjour à tous,
Je viens de créer un trigger afin de mettre à jour des champs d'une table.
Le trigger est le suivant:
CREATE OR REPLACE FUNCTION test_colpl()
RETURNS trigger AS $$
BEGIN
UPDATE "DHCollar_Planned"
SET "Xto"=
CASE New."HoleID"
WHEN "Azimuth" >=0 AND "Azimuth"<180
THEN New."Xplanned"+New."FinalDepth"
ELSE
New."Xplanned"-New."FinalDepth"
END;
RETURN NEW;
UPDATE "DHCollar_Planned"
SET "Yto"=
CASE New."YHoleID"
WHEN "Azimuth" >=0 AND "Azimuth"<90 OR "Azimuth" >=270 AND "Azimuth"<359
THEN New."Xplanned"+New."FinalDepth"
ELSE
New."Xplanned"-New."FinalDepth"
END;
RETURN NEW;
END $$ LANGUAGE plpgsql;
CREATE TRIGGER SrvLine
BEFORE INSERT OR UPDATE
ON "DHCollar_Planned"
FOR EACH ROW
EXECUTE FUNCTION test_colpl();
Besoin d'aide car lors de l'importation de données j'ai le message d'erreur suivant:
ERREUR: l'opérateur n'existe pas : character varying = boolean
LIGNE 4 : WHEN "Azimuth" >=0 AND "Azimuth"<180
^
ASTUCE : Aucun opérateur ne correspond au nom donné et aux types d'arguments.
Vous devez ajouter des conversions explicites de type.
REQUTE : UPDATE "DHCollar_Planned"
SET "Xto"=
CASE New."HoleID"
WHEN "Azimuth" >=0 AND "Azimuth"<180
THEN New."Xplanned"+New."FinalDepth"
ELSE
New."Xplanned"-New."FinalDepth"
END
CONTEXTE : fonction PL/pgSQL test_colpl(), ligne 4 à instruction SQL
Je précise que tous les champs impliqués sont en doubles précision.
Merci
Dernière modification par Lamethode (17/02/2022 13:11:33)
Hors ligne
Je ne vois pas d'explication à première vue. Pourriez-vous créer un script qui permette de reproduire le problème de zéro ?
Mis à part ça, je ne pense pas que le code soit correct de toutes façons. Voulez-vous vraiment mettre à jour tous les enregistrements de la table à chaque déclenchement du trigger? Pourquoi ne pas positionner tout simplement NEW."Xto" et NEW."Yto"? De plus, la 2ème requête ne devrait à priori pas être exécutée vu qu'il y a un return entre les 2.
Julien.
https://rjuju.github.io/
En ligne
Oups c'est les nouveaux enregistrements que je veux mettre à jour.
J'aurais repris avec SET New."Yto"= and SET New."Xto"=
et supprimer le Return New qui est entre les deux instructions Update.
Le résultat est pareille
Hors ligne
Je pense que l'erreur vient peut être
de la condition car le message dit que le charactère varying = boolean n'existe pas.
ERREUR: l'opérateur n'existe pas : character varying = boolean
LIGNE 4 : WHEN "Azimuth" >=0 AND "Azimuth"<180
Que puis-je faire car la mise à jour de ces champs est soumise à condition ?
Hors ligne
L'erreur est normale parce que l'expression CASE est un mix incorrect des deux formes possibles de CASE
UPDATE "DHCollar_Planned"
SET "Xto"=
CASE New."HoleID"
WHEN "Azimuth" >=0 AND "Azimuth"<180
THEN New."Xplanned"+New."FinalDepth"
ELSE
New."Xplanned"-New."FinalDepth"
END;
Si on veut exprimer que si "Azimuth" >=0 AND "Azimuth"<180 alors "Xto" doit prendre la valeur New."Xplanned"+New."FinalDepth" et sinon la valeur New."Xplanned"-New."FinalDepth", alors c'est la forme CASE WHEN condition1 THEN valeur1 WHEN condition2 THEN valeur2 etc... et le New."HoleID" n'a rien à faire là.
L'autre forme possible est CASE expression WHEN valeur1 THEN autre valeur ELSE ... END qui teste les égalités entre l'expression et les valeurs successives.
Un autre problème est que dans un trigger on ne met pas à jour les champs avec un nouvel UPDATE de la table qui est train d'être modifiée mais avec une assignation directe des champs: NEW.colonne := valeur;
Apparemment les champs à mettre à jour sont NEW."Xto" et NEW."Yto", mais la présence de New."HoleID" et New."YHoleID" dans ce code n'a pas de raison apparente.
Si vous avez besoin de plus d'aide sur ce code, essayez de décrire ce qu'il doit faire.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Merci Daniel.
Ma base de données connaît des mises à jour journalière.
Je veux à terme générer des polylignes en me basant sur les champs Position (X,Y), Azimut et Longueur.
Etant donné que j'ai un nouveau débutant,
j'ai décidé d'opérer en 2 étapes :
1- Créer des champs Xto et Yto qui abriteront la position des prochains points mais des champs qui seront automatiquement calculées.
2- Générer une géométrie ligne à partir des positions de début et de fin .
Hors ligne
Pour 2) je ne sais pas ce que c'est
Pour 1) la syntaxe standard serait :
BEGIN
NEW."Xto" := CASE WHEN "Azimuth" >=0 AND "Azimuth"<180
THEN NEW."Xplanned"+NEW."FinalDepth"
ELSE
NEW."Xplanned"-NEW."FinalDepth"
END;
NEW."Yto" := CASE WHEN "Azimuth" >=0 AND "Azimuth"<90 OR "Azimuth" >=270 AND "Azimuth"<359
THEN NEW."Xplanned"+NEW."FinalDepth"
ELSE
NEW."Xplanned"-NEW."FinalDepth"
END;
RETURN NEW;
END
En Postgres moderne (depuis la version 12) plutôt qu'un trigger on conseillerait plutôt de déclarer des colonnes générées, par exemple:
ALTER TABLE "DHCollar_Planned" ADD "YTo" numeric generated always
as (CASE WHEN "Azimuth" >=0 AND "Azimuth"<90 OR "Azimuth" >=270 AND "Azimuth"<359
THEN "Xplanned"+"FinalDepth"
ELSE
"Xplanned"-"FinalDepth"
END)
stored;
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Pour 2) j'imagine que c'est quelque chose du genre ST_MakeLine(ST_Point(xfrom, yfrom), ST_Point(xto, yto)), mais difficile à dire sans la définition de la table.
Julien.
https://rjuju.github.io/
En ligne
Merci bien dverite.
ça a fonctionné.
Hors ligne
rjuju oui oui c'est effectivement cela mais comme xto et yto sont des colonnes générées, il refuse.
Je vais tenter de passer par un trigger en espérant que ça marche.
Hors ligne
Pages : 1