Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes PostgreSQL Discussion :

Trigger AFTER UPDATE


Sujet :

Requêtes PostgreSQL

  1. #1
    Candidat au Club
    Trigger AFTER UPDATE
    Je rencontre une difficulté étant novice sur PostgreSQL. J'utilise la version 11.
    Voici mon problème :

    - je créé un trigger comme suis :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    DROP TRIGGER coupurelaser_afterupdate ON "GESTION_QUAIS"."CoupureLaser";
     
    create trigger coupurelaser_afterupdate after
    update
        on
        "GESTION_QUAIS"."CoupureLaser" for each row
        when ((new."DateHeureOff" is not null and old."DateHeureOff" is null)) execute procedure "GESTION_QUAIS".apresupdatecoupurelaser();


    - Voici le le code de la fonction appelée suite au déclenchement de l'évènement :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    CREATE OR REPLACE FUNCTION "GESTION_QUAIS".apresupdatecoupurelaser()
     RETURNS trigger
     LANGUAGE plpgsql
    AS $function$
    	declare 
    			ilIDT_VEHICULES_SUR_SITE		INT8 			;
    			dtDateHeureOff					timestamp		;
    			ilIDT_MOUVEMENTS_DU_JOUR		INT8 			;
    			ilNumVoie						INT4			;
    	begin	
    		ilIDT_VEHICULES_SUR_SITE		:= new."IDT_VEHICULES_SUR_SITE";
    		dtDateHeureOff					:= new."DateHeureOff";
    		ilIDT_MOUVEMENTS_DU_JOUR		:= new."IDT_MOUVEMENTS_DU_JOUR";
    		ilNumVoie 						:= new."NUMERO_VOIE";
    		if 	new."IDT_MOUVEMENTS_DU_JOUR" is not null AND new."IDT_MOUVEMENTS_DU_JOURDepart" is not null then -- c'est un via
    			update "GESTION_QUAIS"."T_MOUVEMENTS_DU_JOUR" as mvtj set mvtj."ETAT"=8, mvt."HEURE_DEPART_EFFECTUEE" = "GESTION_QUAIS".TimeOffDatetime(dtDateHeureOff) where mvtj."IDT_MOUVEMENTS_DU_JOUR" = ilIDT_MOUVEMENTS_DU_JOUR;
    			update "GESTION_QUAIS"."T_QUAIS" as quais set quais."OCCUPATION_QUAI" = '0', quais ."QUI_OCCUPE" = null, quais ."HEURE_LIBERATION_PREVUE" =null, quais ."IDT_MOUVEMENTS_DU_JOUR" = null where quais ."NUM_QUAI_SHAKTIWARE" = ilNumVoie;
    		else
    			if new."NUMERO_VOIE" = 129 then	-- quai de lavage
    				if new."IDT_MOUVEMENTS_DU_JOUR" is not null and new."IDT_MOUVEMENTS_DU_JOURDepart" is null then -- c'est un mouvement simple : arrivée ou départ
    					update "GESTION_QUAIS"."T_MOUVEMENTS_DU_JOUR" as mvtj set mvtj."ETAT"=1, mvt."HEURE_DEPART_EFFECTUEE" = null where mvtj."IDT_MOUVEMENTS_DU_JOUR" = ilIDT_MOUVEMENTS_DU_JOUR and mvtj."ETAT" = 8;
    				end if;
    			else
    				if new."IDT_MOUVEMENTS_DU_JOUR" is not null and new."IDT_MOUVEMENTS_DU_JOURDepart" is null then --  c'est un mouvement simple : arrivée ou départ
    					update "GESTION_QUAIS"."T_MOUVEMENTS_DU_JOUR" as mvtj set mvtj."ETAT"=8, mvt."HEURE_DEPART_EFFECTUEE" = "GESTION_QUAIS".TimeOffDatetime(dtDateHeureOff) where mvtj."IDT_MOUVEMENTS_DU_JOUR" = ilIDT_MOUVEMENTS_DU_JOUR;
    					update "GESTION_QUAIS"."T_QUAIS" as quais set quais."OCCUPATION_QUAI" = '0', quais ."QUI_OCCUPE" = null, quais ."HEURE_LIBERATION_PREVUE" = null, quais ."IDT_MOUVEMENTS_DU_JOUR" = null where quais ."NUM_QUAI_SHAKTIWARE" = ilNumVoie;
    				end if;
    			end if;
    		end if;
    		return new;
    	END;
    $function$
    ;



    Voici l'erreur renvoyée par PostgreSQL dans le cas ou est demandé le update sur 2 tables différentes de la table ou est levé l'évènement :

    Error synchronizing data with database

    Motif:
    SQL Error [0A000]: ERREUR: les fonctions renvoyant un ensemble ne sont pas autorisés dans UPDATE
    Où*: fonction PL/pgsql "GESTION_QUAIS".apresupdatecoupurelaser(), ligne 23 à instruction SQL

    Mon besoin :
    - comprendre la cause de cette erreur.
    - comment la levée.

    Je vous remercie de votre lecture et de vos lumières.

  2. #2
    Membre expert
    Salut
    Il faut voir la définition de la fonction
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    "GESTION_QUAIS".TimeOffDatetime
    . Peut-être qu'elle renvoie un select ou record.
    Si tel le cas vous devez la définir pour qu'elle donne une valeur simple.
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  3. #3
    Candidat au Club
    Salut et merci de ta réponse.

    La fonction dont tu parles est effectivement mon problème.
    Je te remercie pour la façon dont tu m'as répondu qui ne m'a pas donner la solution en tant que telle mais le chemin pour y arriver.


    Code initial en erreur :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    CREATE OR REPLACE FUNCTION "GESTION_QUAIS".timeoffdatetime(p timestamp without time zone, OUT heure time without time zone)
     RETURNS SETOF time without time zone
     LANGUAGE plpgsql
    AS $function$	
     
    	begin
    		if p is null then 
    			RETURN QUERY
    			select null::time as TimeReturn;
    		else
    			RETURN QUERY
    			select
    				concat(
    				case when date_part('hour',p)<10
    					then concat('0',date_part('hour',p)::text,':')
    					else concat(date_part('hour', p)::text,':')
    				end ,
    				case when date_part('minute', p)<10
    					then concat('0',date_part('minute', p)::text,':')
    					else concat(date_part('minute', p)::text,':')
    				end,
    				case when date_part('second', p)<10
    					then concat('0',date_part('second', p)::text)
    					else date_part('second', p)::text
    				end
    				)::time as TimeReturn;
    			return;
    		end if;		
    	END;
    $function$
    ;


    Mon code final corrigé :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    DROP FUNCTION "GESTION_QUAIS".timeoffdatetime(timestamp without time zone);
    CREATE OR REPLACE FUNCTION "GESTION_QUAIS".timeoffdatetime(p timestamp without time zone)
     RETURNS time without time zone
     LANGUAGE plpgsql
    AS $function$	
    	declare 
    		TimeReturn time;
    	begin
    		if p is null then 
    			select into TimeReturn null::time;
    		else
    			select  into TimeReturn
    				concat(
    				case when date_part('hour',p)<10
    					then concat('0',date_part('hour',p)::text,':')
    					else concat(date_part('hour', p)::text,':')
    				end ,
    				case when date_part('minute', p)<10
    					then concat('0',date_part('minute', p)::text,':')
    					else concat(date_part('minute', p)::text,':')
    				end,
    				case when date_part('second', p)<10
    					then concat('0',date_part('second', p)::text)
    					else date_part('second', p)::text
    				end
    				)::time;
    		end if;	
    	return TimeReturn;
    	END;
    $function$
    ;