PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#2 PL/pgSQL » Mise à jour de table distante » 30/08/2022 05:55:51

Lamethode
Réponses : 2

Bonjour à tous,
Encore Débutant que je suis, je désire mettre à jour 4 champs d'une table B en utilisant des données d'une Table A. Il existe une relation de 1 à plusieurs allant de la table A vers la table B. Je précise que a mise à jour doit se faire à chaque fois qu'on entre une nouvelle information.
Sans trop savoir si ma vision ou mon script marchera, je tente le coup.

le script pour les 2 tables est

create table trou(
code varchar(10) PRIMARY KEY,
position_x numeric NOT NULL,
position_y numeric NOT NULL,
angle1 numeric NOT NULL,
angle2 numeric NOT NULL
);
create table contenu_trou(
code varchar(10),
debut numeric,
fin numeric,
attitude varchar(5),
debut_x numeric,
debut_y numeric,
fin_x numeric,
fin_y numeric,
geom geometry GENERATED ALWAYS AS
    (ST_MakeLine(ST_Point(debut_x, debut_y,32644), ST_Point(fin_x, fin_y,32644))) STORED,
constraint con_trou primary key (code, "debut"),
CONSTRAINT "trou?" FOREIGN KEY (code)
        REFERENCES trou (code) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE NO ACTION);

Pour y arriver,  je décide de tenter une fonction qui pourra automatiser la mise à jour des champs (debut_x, debut_y, fin_x et fin_y) en se servant des champs debut et fin de la table trou (la relation mathématique étant connue).
Je me dit qu'un trigger pourrait faire l'affaire mais vu les paramètres à définir au préalable, je suis hésitant et j'opte pour une fonction retournant un void.

CREATE OR REPLACE FUNCTION position_contenu()
RETURNS void
as $$
DECLARE
               cd varchar(10),
            st numeric,
               nd numeric,
           x1 numeric,
           y1 numeric,
               x2 numeric,
           y2 numeric;
BEGIN
        SELECT CASE 
          WHEN code= $1 THEN --tester la correspondance des HoleID et opérer l'ensemble des calculs--
              New.$4:=position_x+(New.$6*cos(radian(angle1))*sin(radian(180-angle2)))
          AND New.$5:=position_y-(New.$6*cos(radian(angle1))*sin(radian(angle2-90)))            
          AND New.$6:=position_x+(New.$7*cos(radian(angle1))*sin(radian(180-angle2)))
          AND New.$7:=position_y-(New.$7*cos(radian(angle1))*sin(radian(angle2-90)))
          ELSE FALSE
        END
          FROM trou
END
$$
language 'sql';

A peine la fonction lancer, j'ai une erreur que je ne comprends pas

ERROR: ERREUR:  erreur de syntaxe sur ou près de « varchar »
LINE 7:         cd varchar(10),
                   ^


Merci de m'aider.

#3 Re : PL/pgSQL » Problème de stabilité » 27/04/2022 19:33:47

Merci beaucoup.
J'y avais pas pensé.
Résolu

#4 PL/pgSQL » Problème de stabilité » 27/04/2022 12:45:16

Lamethode
Réponses : 2

Bonjour à tous,
Je souhaite concatener un champ de type entier avec une lettre de l'alphabet sous postgres 13.
Quand bien même je pense qu'on peut concatener une chaîne et une non-chaîne tel que mentionné dans la documentation, je suis confronter à un problème de stabilité.
Ci-dessous mon code et l'erreur
CREATE TABLE "Test"
(
   
    "Champ1" Integer NOT NULL
    ,"Champ2" Varchar (20) GENERATED ALWAYS AS
        (CASE WHEN "Champ1" > 0 THEN 'A' || "Champ1" ELSE "Champ1"|| 'NS' END) STORED
    ,"Champ3" character varying(20)
    ,"Champ4" Numeric
);

ERROR: ERREUR:  l'expression de génération n'est pas immuable


SQL state: 42P17

Merci de m'aider.

#5 PL/pgSQL » Contrainte CHECK avec condition » 31/03/2022 01:02:30

Lamethode
Réponses : 1

Bonjour à tous,
Je souhaite contrôler une saisie de données via une contrainte CHECK respectant des conditions. Celle doit doit débuter par transformer un nombre en charactère .

Ci-dessous le code


CREATE OR REPLACE FUNCTION code_chk (id integer, cat varchar(20), code varchar(20),spletype varchar(20))
RETURNS BOOLEAN AS
$$
New.$1:='A'||New.$1; --Ajout de la lettre A afin de transformer l'ID en charactère--
    SELECT CASE 
    --vérification enfant--
          WHEN ($1 like '%11' OR $1 like '%31' OR $1 like '%51' OR $1 like '%71' OR $1 like '%91')
                  AND (($3='2-FDDUP') AND ($4='Quarter core'))
                  THEN True 
    --vérification parent--
          WHEN ($1 like '%10' OR $1 like '%30' OR $1 like '%50' OR $1 like '%70' OR $1 like '%90')
                  AND (($3='1-Par') AND ($4='Quarter core'))
                THEN True
    --vérification du blanc--
          WHEN ($1 like '%09' OR $1 like '%29' OR $1 like '%49' OR $1 like '%69' OR $1 like '%89')
                  AND (($4='Blank') AND ($3 like 'Blk%'))
                THEN True
    --vérification du CRM--
          WHEN ($1 like '%19' OR $1 like '%39' OR $1 like '%59' OR $1 like '%79' OR $1 like '%99')
                  AND (($4='Standard') AND ($3 like 'Std%'))
                THEN True        
          ELSE False
    END
FROM "X" WHERE ($1>380000 AND $2='QAQC')  --Condition pour effectuerla vérification--
$$ LANGUAGE 'sql';

ALTER TABLE "X"
ADD CONSTRAINT "QC Checking"
CHECK (code_chk("SampleID","SampleCategory","SampleCode","SampleType"));



Voici l'erreur que j'obiens

erreur de syntaxe sur ou près de « $1 »
LINE 6:  New.$1:='A'||New.$1;


Merci de m'aider

#7 Re : PL/pgSQL » Chevauchement de données » 07/03/2022 19:03:29

Je veux bien contourner le problème en créant un champ

"Overlap" numrange[]

Ce qui modifierait la contrainte EXCLUDE sous la forme

EXCLUDE USING GIST ("HoleID" WITH =, "Overlap" WITH &&)

Mais la question est de savoir comment remplir automatiquement le champ "Overlap" en utilisant les champs "mFrom" et "mTo"?

#8 Re : PL/pgSQL » Chevauchement de données » 07/03/2022 18:58:52

Voici le scénario 2 avec la contrainte EXCLUDE
CREATE TABLE  "DHSample"
(
  "SampleID" integer NOT NULL,
    "HoleID" character varying(20) ,
    "mFrom" Numeric NOT NULL,
    "mTo" Numeric ,
    "mLoss" numeric,
    "SpleLength" double precision generated always as
    (CASE WHEN "SampleCategory"='NO SAMPLE' THEN "mTo"-"mFrom" WHEN "SampleCategory"='QAQC'THEN
     NULL ELSE "mTo"-"mFrom"-"mLoss" END) stored,
    "SampleCategory" character varying(10)  NOT NULL DEFAULT 'SAMPLE'::character varying,
        CONSTRAINT "DHSample_pkey" PRIMARY KEY ("SampleID"),
    CONSTRAINT "DHSple_mTo_check" CHECK ("mTo" > "mFrom"),
        CONSTRAINT "DHSpleTest_mFrom_check" CHECK ("mFrom" >= 0::numeric)
        EXCLUDE USING GIST ("HoleID" WITH =, ["mFrom","mTo"] ::numrange WITH &&)
)
;

ERROR: ERREUR:  erreur de syntaxe sur ou près de « [ »
LINE 15:         EXCLUDE USING GIST ("HoleID" WITH =, ["mFrom","mTo"]...
                                                      ^


SQL state: 42601
Character: 687


La table ne se crée pas du tout... Les champs mFrom et mTo doivent obligatoirement être dans la base de données.

#9 Re : PL/pgSQL » Chevauchement de données » 07/03/2022 18:54:13

Voici le scénario 1 qui fonctionne à merveille sans la contrainte EXCLUDE mais qui accepte éventuellement les chevauchements

CREATE TABLE  "DHSample"
(
  "SampleID" integer NOT NULL,
    "HoleID" character varying(20) ,
    "mFrom" Numeric NOT NULL,
    "mTo" Numeric ,
    "mLoss" numeric,
    "SpleLength" double precision generated always as
    (CASE WHEN "SampleCategory"='NO SAMPLE' THEN "mTo"-"mFrom" WHEN "SampleCategory"='QAQC'THEN
     NULL ELSE "mTo"-"mFrom"-"mLoss" END) stored,
    "SampleCategory" character varying(10)  NOT NULL DEFAULT 'SAMPLE'::character varying,
        CONSTRAINT "DHSample_pkey" PRIMARY KEY ("SampleID"),
    CONSTRAINT "DHSple_mTo_check" CHECK ("mTo" > "mFrom"),
        CONSTRAINT "DHSpleTest_mFrom_check" CHECK ("mFrom" >= 0::numeric)
)
;

INSERT INTO  "DHSample" ("SampleID","HoleID", "mFrom", "mTo", "mLoss", "SampleCategory") VALUES (100,'Z1', 0, 1, -0.2, 'SAMPLE');

INSERT INTO  "DHSample" ("SampleID","HoleID", "mFrom", "mTo", "mLoss", "SampleCategory") VALUES (101,'Z1', 1, 3, 0 , 'SAMPLE');

INSERT INTO  "DHSample" ("SampleID","HoleID", "mFrom", "mTo", "mLoss", "SampleCategory") VALUES (102,'Z1', 2.63, 6.04, 0.17, 'SAMPLE');

#10 Re : PL/pgSQL » Chevauchement de données » 07/03/2022 16:45:40

Voici le script de la table :

CREATE TABLE  "DHSample"
(
  "SampleID" integer NOT NULL (PK),
    "HoleID" character varying(20) ,
    "mFrom" Numeric NOT NULL,
    "mTo" Numeric ,
    "mLoss" numeric,
    "SpleLength" double precision generated always as
    (CASE WHEN "SampleCategory"='NO SAMPLE' THEN "mTo"-"mFrom" WHEN "SampleCategory"='QAQC'THEN
     NULL ELSE "mTo"-"mFrom"-"mLoss" END) stored,
    "SampleCategory" character varying(10)  NOT NULL DEFAULT 'SAMPLE'::character varying,
    CONSTRAINT "DHSple_mTo_check" CHECK ("mTo" > "mFrom"),
        CONSTRAINT "DHSpleTest_mFrom_check" CHECK ("mFrom" >= 0::numeric)

)
;

Il y a un flux important de données et je dois absolument empêcher tout chevauchement entre les données (mFrom et mTo) ayant un même HoleID.

#11 Re : PL/pgSQL » Chevauchement de données » 06/03/2022 20:36:08

Après avoir transformé les champs début et fin en numeric et lu la documentation,
J'ai ajouté un champ Valrange de type numrange[]
  j'ai ensuite écrit cette contrainte d'exclusion
EXCLUDE USING GIST ("ID" WITH =, "Valrange"("mFrom","mTo",'[]'::numeric) WITH &&)

mais cela ne fonctionne toujours pas

#12 PL/pgSQL » Remplissage automatique » 24/02/2022 16:16:31

Lamethode
Réponses : 2

Bonjour à tous,

Je suis débutant et je bloque encore sur du remplissage automatique :

1- Je veux remplir des champs d'une table en fonction de la valeur d'autre champ
2- Je recherche comment écrire une contrainte qui pourra vérifier que mes données ne se chevauchent pas (champ mFrom et mTo) pour un même HoleID
3- Renvoyer un message claire et précis lorsqu'une contrainte est violée

J'ai pu écrire les différents scripts relatifs à ma préoccupation numéro 1 mais le code 4 lui ne fonctionne pas du tout car il bloque.

Voici les différents scripts que j'ai pu écrire :

Code 1 :
CREATE TABLE "DHSample_Test"
(
    "SampleID" integer NOT NULL,
    "HoleID" character varying(20) ,
    "mFrom" Numeric NOT NULL,
    "mTo" Numeric NOT NULL,
    "mLoss" double precision,
    "SpleLength" double precision generated always as
    (CASE WHEN "SampleCategory"='NO SAMPLE' THEN "mTo"-"mFrom" WHEN "SampleType"='Standard' or "SampleType"='Blank'
            THEN NULL ELSE  "mTo"-"mFrom"-"mLoss" END) stored,
    "SampleCategory" character varying(10)  NOT NULL DEFAULT 'SAMPLE'::character varying,
    "SampleCode" character varying(10)  NOT NULL DEFAULT '1-Org'::character varying,
    "DupSampleID"  double precision GENERATED ALWAYS AS (CASE WHEN "SampleCode"='1-Par'
            THEN "SampleID"+1 ELSE NULL END) stored,
    "StandardCode" character varying(20) GENERATED ALWAYS AS (CASE WHEN "SampleID" LIKE ¨%19'OR  THEN Standard'
            THEN "SampleCode" ELSE NULL END) stored ,
    "DispatchID" character varying(50)  NOT NULL DEFAULT 'UNK',
    "SampleType" character varying(20)  NOT NULL DEFAULT 'Half core'::character varying,
    "SampleGen" integer NOT NULL DEFAULT 0,
    "kgWeightSampleRef" double precision,
    "kgWeightSampleReject" double precision,
    "SamplingPlannedBy" character varying(20),
    "SampledBy" character varying(5)  DEFAULT 'BN'::character varying,
    "SamplingDate" date,
    "Comments" character varying(255)  ,
    "EditBy" character varying(5)  DEFAULT 'LFC'::character varying,
    "EditDate" timestamp with time zone ,
   
    CONSTRAINT "DHSample_Test_pkey" PRIMARY KEY ("SampleID"),
    CONSTRAINT "DHSample_Test_EditBy_fkey" FOREIGN KEY ("EditBy")
        REFERENCES "RefColStaffName" ("StaffNameCode") MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
        NOT VALID,
    CONSTRAINT "DHSample_Test_HoleID_fkey" FOREIGN KEY ("HoleID")
        REFERENCES "DHCollar" ("HoleID") MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
        NOT VALID,
    CONSTRAINT "DHSample_Test_SampleCategory_fkey" FOREIGN KEY ("SampleCategory")
        REFERENCES "RefSpleCateg" ("SampleCategCode") MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
        NOT VALID,
    CONSTRAINT "DHSample_Test_SampleCode_fkey" FOREIGN KEY ("SampleCode")
        REFERENCES "RefSpleCode" ("SampleCode") MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
        NOT VALID,
    CONSTRAINT "DHSample_Test_SampleType_fkey" FOREIGN KEY ("SampleType")
        REFERENCES "RefSpleType" ("SampleTypeCode") MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
        NOT VALID,
    CONSTRAINT "DHSample_Test_SampledBy_fkey" FOREIGN KEY ("SampledBy")
        REFERENCES "RefColStaffName" ("StaffNameCode") MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
        NOT VALID,
    CONSTRAINT "DHSample_Test_mTo_check" CHECK ("mTo" > "mFrom"),
    CONSTRAINT "DHSample_Test_mFrom_check" CHECK ("mFrom" >= 0::double precision),

Code 2 : -- Pour vérifier la profondeur saisie afin qu'elle ne dépasse pas celle de la table DHCollar--

CREATE OR REPLACE FUNCTION sple_Depth_Max_CHECKING (hole character varying (20), spledepth double precision)
RETURNS BOOLEAN AS
$$
SELECT CASE 
          WHEN "FinalDepth" < $2 THEN false
          ELSE true
        END
FROM "DHCollar" WHERE "HoleID"=$1
$$ LANGUAGE 'sql';
ALTER TABLE "DHSample"
   ADD CONSTRAINT sple_max_depth_check CHECK (sple_Depth_Max_CHECKING ("HoleID", "mTo"));

Code 3 :

CREATE OR REPLACE FUNCTION lastupdate()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN

New."EditDate":= current_timestamp;
  New."EditBy":= 'LFC';
RETURN NEW;
END;
$BODY$;
CREATE TRIGGER last_update
    BEFORE INSERT OR UPDATE
    ON "DHSample_Test"
    FOR EACH ROW
    EXECUTE FUNCTION lastupdate();


Code 4 :

CREATE OR REPLACE FUNCTION sple_code_filling()
RETURNS TRIGGER AS
$$
BEGIN
    NEW."SampleCategory" :=
        CASE WHEN "SampleID" < 0 THEN 'NO SAMPLE'
        WHEN (SELECT "SampleID" FROM "DHSample_Test" WHERE CAST("SampleID" AS TEXT)
           LIKE ANY ('%31' , '%51' , '%71','%91', '%09', '%29',
            '%49', '%69', '%89', '%19', '%39', '59%', '%79', '%99'));
        THEN  'QAQC'
        ELSE 'SAMPLE'
        END;
       
    New."SampleCode" :=
        CASE WHEN "SampleType"= 'Half core' AND "SampleID">0  THEN '1-Org'
        WHEN "DupSampleID" >0 THEN '1-Par'
        WHEN "SampleType" = 'Blank' THEN 'Blk-G'
        WHEN "SampleType" = 'Quarter core' AND "DupSampleID"= NULL THEN '2-FDDUP'
        WHEN "SampleType" = 'NO SAMPLE' THEN '1-99NR'
        ELSE NULL
        END;
    RETURN NEW;   
END
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER     fill_sple_tab   
    BEFORE INSERT OR UPDATE
    ON "DHSample_Test"
    FOR EACH ROW
    EXECUTE FUNCTION sple_code_filling();


Merci

#13 Re : PL/pgSQL » Trigger non fonctionnel Postgresql 13 » 18/02/2022 16:40:54

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.

#15 Re : PL/pgSQL » Trigger non fonctionnel Postgresql 13 » 18/02/2022 00:39:28

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 .

#16 Re : PL/pgSQL » Trigger non fonctionnel Postgresql 13 » 17/02/2022 18:44:02

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 ?

#17 Re : PL/pgSQL » Trigger non fonctionnel Postgresql 13 » 17/02/2022 18:42:05

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

#18 PL/pgSQL » Trigger non fonctionnel Postgresql 13 » 17/02/2022 13:09:10

Lamethode
Réponses : 9

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

#20 Re : PL/pgSQL » Chevauchement de données » 02/01/2022 12:26:24

Merci julien.
Je vais transformer les doubles précision en numerique

#21 Re : PL/pgSQL » Chevauchement de données » 02/01/2022 12:24:44

Merci Guillaume pour ta contribution.
Stp peux-tu me mettre sur la voie pour le trigger ou la contrainte exclude?

#22 PL/pgSQL » Chevauchement de données » 31/12/2021 01:53:04

Lamethode
Réponses : 15

Bonjour à tous,
Étant nouveau utilisateur de postgres, j'ai créé une base de données sous postgres 13. Elle contient des tables
dont 4 Champs
ID integer (PK)
Numéro entité varchar (20)
début double precision not null
fin double precision not nulle.
Je souhaite créé une contrainte qui vérifiera que pour un numéro d'entité identique, les champs début et fin d'un enregistrement ne doivent pas chevaucher avec un autre enregistrement.
Je précise que la clé primaire définie ou choisi ne règle pas mon problème.
Merci de m'aider.

Pied de page des forums

Propulsé par FluxBB