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).

#327 PL/pgSQL » Fonction avec paramètre OUT » 09/07/2010 09:36:26

mortimer.pw
Réponses : 11

Bonjour,


Je travaille sur une BD 8.4 sous Cent-OS.

Je dois réécrire des Fonctions Oracle en Pl/PgSQL.


Exemple :

FUNCTION Get_Doc(MODE IN VARCHAR2,ERREUR OUT VARCHAR2,DOC OUT VARCHAR2) RETURN NUMBER IS
     retour NUMBER:=-1;
BEGIN
     IF NOT(Ctrl(MODE,ERREUR,DOC)) THEN
          RAISE_APPLICATION_ERROR(-20001,ERREUR);
     ELSE
          retour:=1;
     END IF;
     RETURN(retour);
EXCEPTION
     WHEN OTHERS THEN
          ERREUR:=SQLERRM;
          RETURN(retour);
END Get_Doc;


En consultant la Doc, j'ai vu qu'il n'est pas possible d'écrire une Fonction avec des paramètres en OUT et de renvoyer une valeur.

Comment peut-on procéder ?

Merci pour les réponses.

#328 Général » Type de données CHARACTER » 01/07/2010 11:46:46

mortimer.pw
Réponses : 4

Bonjour,

Je travaille sur une 8.4.2 sous Cent-OS 5.

J'ai créé une table avec la structure suivante :

          CREATE TABLE type_action (
              id_type_action CHARACTER(3) NOT NULL,
              libelle CHARACTER VARYING(30) NOT NULL,
              id_type_operation CHARACTER(1) NOT NULL
          );
          ALTER TABLE geo.type_action OWNER TO postgres;


J'ai saisi des valeurs sur 1, 2 ou 3 caractères dans le champ ID_TYPE_ACTION.

Lorsque je fais un SELECT, je ne reçois jamais les espaces en fin sur les valeurs contenant 1 ou 2 caractères :

          select id_type_act,length(id_type_act),'--'||id_type_act||'--' from type_act;
                    RR, 2, --RR--
                    P, 1, --P--
                    QQQ,3, --QQQ--

Ne devrais-je pas obtenir :

                    RR , 3, --RR --
                    P  ,3, --P  --
                    QQQ,3, --QQQ--

Merci.

#330 Sécurité » Active Data Guard » 25/05/2010 09:54:22

mortimer.pw
Réponses : 2

Bonjour,

J'ai lu quelques articles sur la réplication mais je ne vois pas s'il est possible, comme sous Oracle, d'avoir une "standby" accessible en lecture ?

Quelqu'un peut-il me renseigner ou m'orienter vers plus d'infos ?

Merci.

#331 Re : Optimisation » Requête lente sur volume de données réduit » 12/03/2010 08:47:21

Bonjour Marc,
Ce n'est pas que je ne veux pas comprendre mais je dois migrer une base Oracle en production.
Les changements de structure ne peuvent pas se faire facilement.
Je vais travailler dans ce sens.
Merci pour votre analyse.

#332 Re : Optimisation » Requête lente sur volume de données réduit » 11/03/2010 08:46:26

Bonjour Marc,

Le fait d'avoir cette nouvelle colonne dans la table Document ne réglerai pas le problème des Documents qui ne sont pas dans la liste.

Concernant le CASE WHEN, je teste si le dernier caractère est alphanumérique.
     Si non Alors je prends la valeur entière de T.Doc
     Si oui Alors je prends la valeur de T.doc - le dernier caractère
Ensuite je compare avec la valeur de D.doc - le dernier caractère

#333 Re : Optimisation » Requête lente sur volume de données réduit » 10/03/2010 17:21:04

La table Document est alimentée grâce à une liste de documents à produire fournie par le client (la lettre de contrôle est ajoutée pendant cette alimentation).

La table Travail est alimentée par la production qui ne connait pas forcément le caractère de contrôle et qui parfois traite des documents qui ne sont pas dans la liste.

#334 Re : Optimisation » Requête lente sur volume de données réduit » 10/03/2010 15:52:37

Dans la table document, j'ai la liste des documents sur 7 chiffres + 1 lettre de contrôle

Exemple :
    1111111A
    4444444K
    2222222R
    6666666C


Alors que dans la table Travail, dans le champ doc, je peux recevoir soit :
    - 7 chiffres + 1 lettre de contrôle
    - 7 chiffres
    - X chiffres

Exemple :
    1111111A
    4444444K
    2222222
    6666666
    6487
    4474


Dans le CASE WHEN, je fais donc :

     SI  le dernier caractère de T.doc n'est pas une lettre  ALORS  je cherche T.doc = 7 premiers caractères de D.doc

     SINON  je cherche 7 premiers caractères de T.doc = 7 premiers caractères de D.doc



Je fais un  LEFT OUTER JOIN  pour récupérer les lignes de Travail même si le document n'existe pas dans Document.

J'espère être clair.

#335 Re : Optimisation » Requête lente sur volume de données réduit » 10/03/2010 15:21:21

La vue utilisée est la suivante :
          CREATE VIEW Vue_Action AS
    SELECT a.id_act1,ss1.libelle AS lib1,a.id_act2,ss2.libelle AS lib2,a.id_act3,ss3.libelle AS lib3,a.id_act4,ss4.libelle AS lib4
    FROM action a,ss_action1 ss1,ss_action2 ss2,ss_action3 ss3,ss_action4 ss4
    WHERE a.id_type1='G'
    AND a.id_type2=1
    AND to_char('now'::text::date::timestamp WITH time zone,'YYYYMMDD'::text)<=a.fin_action::text
    AND a.id_act1=ss1.id
    AND a.id_act2=ss2.id
    AND a.id_act3=ss3.id
    AND a.id_act4=ss4.id;

La clé primaire sur A est : ALTER TABLE action ADD CONSTRAINT pk_action PRIMARY KEY(id_act1,id_act2,id_act3,id_act4,fin_action);

Il ya a également un index sur travail : CREATE INDEX travail1 ON travail(jour,personne);

Et voici le explain analyze :
Limit  (cost=643219.80..643219.81 rows=1 width=367) (actual time=30633.571..30633.572 rows=1 loops=1)
   ->  Sort  (cost=643219.80..643878.07 rows=263307 width=367) (actual time=30633.569..30633.569 rows=1 loops=1)
         Sort Key: t.heure
         Sort Method:  top-N heapsort  Memory: 25kB
         ->  Merge Join  (cost=632566.01..641903.27 rows=263307 width=367) (actual time=30633.309..30633.462 rows=43 loops=1)
               Merge Cond: ((((((a.id_act1)::text || (a.id_act2)::text) || (a.id_act3)::text) || (a.id_act4)::text)) = ((t.id_action)::text))
               ->  Sort  (cost=1668.72..1680.86 rows=4855 width=132) (actual time=364.533..364.702 rows=726 loops=1)
                     Sort Key: (((((a.id_act1)::text || (a.id_act2)::text) || (a.id_act3)::text) || (a.id_act4)::text))
                     Sort Method:  quicksort  Memory: 4222kB
                     ->  Hash Join  (cost=49.88..1371.46 rows=4855 width=132) (actual time=1.566..234.961 rows=14447 loops=1)
                           Hash Cond: (a.id_act1 = ss1.id)
                           ->  Hash Join  (cost=48.29..1303.12 rows=4855 width=120) (actual time=1.500..194.138 rows=14447 loops=1)
                                 Hash Cond: (a.id_act3 = ss3.id)
                                 ->  Hash Join  (cost=35.57..1223.65 rows=4855 width=107) (actual time=1.115..177.392 rows=14447 loops=1)
                                       Hash Cond: (a.id_act4 = ss4.id)
                                       ->  Hash Join  (cost=7.42..1128.74 rows=4855 width=91) (actual time=0.299..159.552 rows=14447 loops=1)
                                             Hash Cond: (a.id_act2 = ss2.id)
                                             ->  Seq Scan on action a  (cost=0.00..1054.56 rows=4855 width=82) (actual time=0.065..132.866 rows=14447 loops=1)
                                                   Filter: ((id_type1 = 'G'::bpchar) AND (id_type2 = 1::numeric) AND (to_char((('now'::text)::date)::timestamp with time zone, 'YYYYMMDD'::text) <= (fin_action)::text))
                                             ->  Hash  (cost=4.41..4.41 rows=241 width=13) (actual time=0.223..0.223 rows=241 loops=1)
                                                   ->  Seq Scan on ss_action2 ss2  (cost=0.00..4.41 rows=241 width=13) (actual time=0.007..0.091 rows=241 loops=1)
                                       ->  Hash  (cost=16.40..16.40 rows=940 width=21) (actual time=0.803..0.803 rows=940 loops=1)
                                             ->  Seq Scan on ss_action4 ss4  (cost=0.00..16.40 rows=940 width=21) (actual time=0.009..0.347 rows=940 loops=1)
                                 ->  Hash  (cost=7.32..7.32 rows=432 width=17) (actual time=0.374..0.374 rows=432 loops=1)
                                       ->  Seq Scan on ss_action3 ss3  (cost=0.00..7.32 rows=432 width=17) (actual time=0.008..0.172 rows=432 loops=1)
                           ->  Hash  (cost=1.26..1.26 rows=26 width=16) (actual time=0.046..0.046 rows=26 loops=1)
                                 ->  Seq Scan on ss_action1 ss1 (cost=0.00..1.26 rows=26 width=16) (actual time=0.014..0.031 rows=26 loops=1)
               ->  Sort  (cost=630897.29..630924.41 rows=10847 width=235) (actual time=30268.120..30268.133 rows=43 loops=1)
                     Sort Key: ((t.id_action)::text)
                     Sort Method:  quicksort  Memory: 31kB
                     ->  Nested Loop Left Join  (cost=965.91..630170.27 rows=10847 width=235) (actual time=768.841..30267.651 rows=43 loops=1)
                           Join Filter: (CASE WHEN (lastalpha(t.doc) = 0::numeric) THEN (t.doc)::text ELSE substr((t.doc)::text, 1, (length((t.doc)::text) - 1)) END = substr((d.doc)::text, 1, (length((d.doc)::text) - 1)))
                           ->  Index Scan using travail1 on travail t  (cost=0.01..66.19 rows=62 width=219) (actual time=0.068..0.420 rows=43 loops=1)
                                 Index Cond: ((jour = (('now'::text)::date - 1)) AND (personne = '0000123'::bpchar))
                           ->  Materialize  (cost=965.90..1315.81 rows=34991 width=25) (actual time=0.001..13.739 rows=34991 loops=43)
                                 ->  Seq Scan on document d  (cost=0.00..930.91 rows=34991 width=25) (actual time=0.010..31.729 rows=34991 loops=1)
Total runtime: 30636.099 ms
(37 rows)

Merci pour votre aide Marc.

#336 Re : Optimisation » Requête lente sur volume de données réduit » 10/03/2010 13:33:02

Bonjour Marc,

En fait je travaille à la migration d'un système basé sur une BD Oracle vers PostgreSQL.
En Oracle, cela fonctionne trés bien avec des temps de réponse trés acceptables et sur des volumes beaucoup plus importants surtout sur la table travail.

Pourquoi dites-vous "il n'y a pas jointure au sens relationnel" ?
je cherche l'égalité entre le champ T.doc de la table travail et le champ D.doc de la table document.
Idem pour le champ T.id_action qui doit avoir une correspondance dans la table Action en concaténant les champs A.id_act1||A.id_act2||A.id_act3||A.id_act4

#337 Optimisation » Requête lente sur volume de données réduit » 10/03/2010 12:19:38

mortimer.pw
Réponses : 14

Bonjour,

Je travaille sur une BD 8.4.2 sous Cent-OS 5.2.

J'ai une requête qui est trés lente alors que le volume de données dans ma base est ridicule.
La requête doit me retourner la dernière ligne de travail de la personne '0000123' pour la veille.

Voilà la requête :
    SELECT T.*,A.*,D.libelle
    FROM Travail T LEFT OUTER JOIN Document D ON (CASE WHEN LastAlpha(T.doc)=0 THEN T.doc ELSE SUBSTR(T.doc,1,LENGTH(T.doc)-1) END)=SUBSTR(D.doc,1,LENGTH(D.doc)-1),Vue_Action A
    WHERE T.jour=CURRENT_DATE-1
    AND T.personne='0000123'
    AND T.id_action=A.id_act1||A.id_act2||A.id_act3||A.id_act4
    ORDER BY T.jour DESC,T.heure DESC LIMIT 1;

Je fais une jointure entre travail et action pour récupérer les paramètres liés à une action.
Je fais une jointure entre travail et document pour récupérer le libelle du document

Le volume des tables est :
   travail : 82591 enregistrements
   action : 20325 enregistrements
   document : 34991 enregistrements

J'ai fait un explain mais je ne sais pas l'exploiter :
Limit  (cost=632614.91..632614.92 rows=1 width=367)
   ->  Sort  (cost=632614.91..632620.69 rows=2309 width=367)
         Sort Key: t.heure
         ->  Hash Join  (cost=2102.89..632603.37 rows=2309 width=367)
               Hash Cond: (a.id_act1 = ss1.id)
               ->  Hash Join  (cost=2101.30..632570.04 rows=2309 width=355)
                     Hash Cond: (a.id_act2 = ss2.id)
                     ->  Hash Join  (cost=2093.88..632530.86 rows=2309 width=346)
                           Hash Cond: (a.id_act3 = ss3.id)
                           ->  Nested Loop  (cost=2081.16..632486.40 rows=2309 width=333)
                                 ->  Hash Join  (cost=2081.16..631828.23 rows=2309 width=317)
                                       Hash Cond: ((t.id_action)::text = ((((a.id_act1)::text || (a.id_act2)::text) || (a.id_act3)::text)|| (a.id_act4)::text))
                                       ->  Nested Loop Left Join  (cost=965.91..630170.27 rows=95 width=235)
                                             Join Filter: (CASE WHEN (lastalpha(t.doc) = 0::numeric) THEN (t.doc)::text ELSE substr((t.doc)::text, 1, (length((t.doc)::text) - 1)) END = substr((d.doc)::text, 1, (length((d.doc)::text) - 1)))
                                             ->  Index Scan using travail1 on travail t  (cost=0.01..66.19 rows=62 width=219)
                                                   Index Cond: ((jour = (('now'::text)::date - 1)) AND (personne = '0000781'::bpchar))
                                             ->  Materialize  (cost=965.90..1315.81 rows=34991 width=25)
                                                   ->  Seq Scan on document d  (cost=0.00..930.91 rows=34991 width=25)
                                       ->  Hash  (cost=1054.56..1054.56 rows=4855 width=82)
                                             ->  Seq Scan on action a  (cost=0.00..1054.56 rows=4855 width=82)
                                                   Filter: ((id_type1 = 'G'::bpchar) AND (id_type2 = 1::numeric) AND (to_char((('now'::text
)::date)::timestamp with time zone, 'YYYYMMDD'::text) <= (fin_action)::text))
                                 ->  Index Scan using pk_ss_action4 on ss_action4 ss4  (cost=0.00..0.27 rows=1 width=21)
                                       Index Cond: (ss4.id = a.id_act4)
                           ->  Hash  (cost=7.32..7.32 rows=432 width=17)
                                 ->  Seq Scan on ss_action3 ss3  (cost=0.00..7.32 rows=432 width=17)
                     ->  Hash  (cost=4.41..4.41 rows=241 width=13)
                           ->  Seq Scan on ss_action2 ss2  (cost=0.00..4.41 rows=241 width=13)
               ->  Hash  (cost=1.26..1.26 rows=26 width=16)
                     ->  Seq Scan on ss_action1 ss1 (cost=0.00..1.26 rows=26 width=16)
(29 rows)

J'espère fournir suffisamment d'éléments.

Pouvez-vous m'aider ?

#338 Re : Général » FATAL: the database system is shutting down » 04/03/2010 13:22:03

Merci messieurs pour votre rapidité et les explications claires.

#339 Re : Général » FATAL: the database system is shutting down » 04/03/2010 12:24:02

Bonjour Marc,

J'ai fait le pg_ctl -m immediate stop, puis redémarrer le serveur. Tout va bien. Merci.

Faut-il s'inquiter ? étes-vous sûr qu'en aucun cas il n'y a de perte de données ? y-a-t'il un Bug ? la version 8.4.2 ?

Merci pour votre réponse.

#340 Général » FATAL: the database system is shutting down » 04/03/2010 11:59:29

mortimer.pw
Réponses : 7

Bonjour,

Je travaille sur une version 8.4.2 sous Cent-OS 5.2.

Je viens de lancer la commande : pg_ctl stop et ............. failed
pg_ctl: server does not shut down

Dans le fichier de log, j'ai ces lignes :
2623 2010-03-04 10:16:25 CET 2 LOG: received smart shutdown request
2629 2010-03-04 10:16:25 CET 2 LOG: autovacuum launcher shutting down
[local] 23938 2010-03-04 10:28:21 CET /usr/local/pgsql/bin/postmaster 1 FATAL: the database system is shutting down
[local] 23943 2010-03-04 10:28:48 CET /usr/local/pgsql/bin/postmaster 1 FATAL: the database system is shutting down

J'essaye de me connecter : psql template1 : psql: FATAL: the database system is shutting down

Je fais un pg_ctl status : pg_ctl: server is running (PID: 2623)

Quelqu'un à t'il déjà rencontré ce problème ?

Que faut-il faire ?

Merci pour vos réponses.

#341 Re : PHP » REFCURSOR et PHP » 03/03/2010 15:46:07

Si cela peut aider d'autres personnes :

function test_refcursor()
{
  pg_query("begin");
  $res1 = pg_query("SELECT fcurs()");
  if ($res1!==false) {
    list($cname) = pg_fetch_array($res1);
    $res2 = pg_query("FETCH ALL IN \"" . $cname . "\"");
    if ($res2!==false) {
      $all = pg_fetch_all($res2);
      print_r($all);
    }
  }
  pg_query("commit");
}

Solution proposée par Estofilo sur Developpez.com

#342 Re : PHP » REFCURSOR et PHP » 02/03/2010 14:58:25

Désolé Guillaume, mais il semble que le tableau soit vide.

Voici les lignes de PHP :
                $result1 = pg_query($_query);
                $arr1 = pg_fetch_array($result1,NULL,PGSQL_ASSOC);
                $tmp = array_keys($arr1);
                $result2 = pg_query("FETCH ALL IN ".$tmp[0]);
                $arr2 = pg_fetch_array($result2,NULL,PGSQL_ASSOC);

voici ce qui s'affiche :
Warning: pg_query() [function.pg-query]: Query failed: ERROR: cursor "data" does not exist in /usr/local/apache....
Warning: pg_fetch_array() expects parameter 1 to be resource, boolean given in /usr/local/apache....

J'ai ajouté : print_r("--".$_query."--");  pour voir la query, et j'obtiens cela :
--select User.Clients() as data --

Peux-tu m'aider ?

#343 Re : PHP » REFCURSOR et PHP » 02/03/2010 12:59:57

Guillaume,

J'ai bien compris le principe PostgreSQL.

Par contre côté PHP, cela veut-il dire que $result = pg_query($_query); me retourne le nom du curseur ?
Et que je dois faire un nouveau query : $result2 = pg_query("FETCH ALL IN ".$result); ?
Avant de faire la boucle : while ($arr = pg_fetch_array($result2,NULL,PGSQL_ASSOC)) ?

Je ne connais vraiment pas PHP et n'est pas trouvé d'exemple.

Merci pour les solutions.

#344 Re : PHP » REFCURSOR et PHP » 02/03/2010 12:20:26

Bonjour Guillaume,

En fait, je dois reprendre une interface écrite en PHP.

Cette interface communiquait avec une BD Oracle.
Je dois l'adapter pour communiquer avec PostgreSQL.

J'ai des fonctions Oracle qui renvoient des SYS_REFCURSOR.
J'ai réécrit pour renvoyer des REFCURSOR.

Je dois maintenant les exploiter dans le PHP.

Y-a-t'il une solution ?

Merci pour ton aide.

#345 PHP » REFCURSOR et PHP » 02/03/2010 10:53:36

mortimer.pw
Réponses : 8

Bonjour à tous,

Je travaille sous Cent-OS 5.2, PostgreSQL 8.4.2.
Je souhaite récupérer un REFCURSOR dans un tableau sous PHP (grand débutant PHP).

J'ai écrit une Fonction Postgres qui retourne un REFCURSOR.

CREATE OR REPLACE FUNCTION USER.Clients() RETURNS REFCURSOR AS '
DECLARE
        RClient REFCURSOR;
BEGIN
        OPEN RClient FOR
                SELECT C.id_client,C.libelle
                FROM USER.Client C;
        RETURN RClient;
END;
' LANGUAGE 'plpgsql';

J'ai utilisé PG_FETCH_ARRAY sous PHP (comme dans la Doc : http://www.php.net/manual/fr/function.p … array.php).
J'essaye d'afficher les valeurs mais je n'obtiens rien.

        public function db_ref_cursor($_query)
        {
                $aRetTab = array();
                $result = pg_query($_query);
                while ($arr = pg_fetch_array($result,NULL,PGSQL_ASSOC))
                        {
                                echo $arr["libelle"].' <br/> <br/>';
                        }
                pg_free_result($result);
                return $aRetTab;
        }

Quelqu'un à t'il déjà utilisé un REFCURSOR sous PHP ?

Pouvez-vous m'aider à construire mon tableau à partir de ce REFCURSOR ?

Merci pour les réponses.

#346 Re : PL/pgSQL » Afficher un refcursor » 19/02/2010 12:23:19

J'ai bien lu la Doc mais en fait j'étais parti à fond sous PgAdmin.

Merci encore Guillaume.

#347 Re : PL/pgSQL » Afficher un refcursor » 19/02/2010 11:39:07

Bonjour,

Effectivement, peut-être en détaillant mon problème ce sera plus clair.

J'ai un développeur PHP qui me demande une fonction Pl/PgSQL.
Cette fonction doit :
   - Retourner une liste de N derniers clients,
   - Prendre en entrée un Curseur et un Entier(N),
   - Retourner le Curseur.


J'ai créé la fonction :

CREATE OR REPLACE FUNCTION DernieresLignes(REFCURSOR,NUMERIC) RETURNS REFCURSOR AS '
DECLARE
BEGIN
   OPEN $1 FOR
   SELECT C.*
   FROM Client C
   ORDER BY C.id_client DESC LIMIT TO_NUMBER($2);
   RETURN $1;
END;
' LANGUAGE 'plpgsql';

Pour vérifier que ma fonction marche et avant de la founir au développeur, je souhaite visualiser le résultat de la fonction (sous psql ou PgAdmin).

Comment faire ?

Merci pour votre aide.

#348 PL/pgSQL » Afficher un refcursor » 19/02/2010 10:56:09

mortimer.pw
Réponses : 5

Bonjour à tous,

Je travaille avec PostgreSQL 8.4.2 sous CentOS 5.2.

Je voudrais afficher le résultat d'une fonction qui retourne un REFCURSOR sous psql ou PgAdmin.

Avez-vous une solution ?

Merci pour vos réponses.

#349 Général » Tablespaces et disque unique » 12/02/2010 08:50:46

mortimer.pw
Réponses : 4

Bonjour à tous,

Je travaille actuellement sur la mise en place d'un Serveur PostgreSQL 8.4.2 sur CentOS 5.2.

Je m'intérogge sur l'utilité de définir des tablespaces sur une machine qui ne contient qu'un disque. Même question sur les tablespaces temporaires. Le default tablespace est-il suffisant ?

Avez-vous des avis, des infos à me donner ?

Merci pour les réponses.

#350 Re : Général » Paramètrage et démarrage de l'autovacuum » 08/02/2010 09:27:23

Bonjour Guillaume,
J'ai arrêté et redémarré PostgreSQL aprés que la machine soit complétement démarrée.
Les 2 services stats_buffer et stats_collector sont démarrés.
C'est donc bien qu'il y a un problème avec le réseau.
J'ai demandé à l'équipe système de modifier l'ordre des démarrage des différents services.
A présent tout fonctionne bien.
Désolé pour le temps perdu.
Merci encore.

Pied de page des forums

Propulsé par FluxBB