Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL > Requêtes
Requêtes Forum d'entraide sur les requêtes SQL spécifiques à PostgreSQL, les triggers, les vues, etc.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 15/11/2011, 11h38   #1
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Par défaut Afficher commentaire séquence postgres

Bonjour

Je cherche à afficher le commentaire d'une séquence postgres, ainsi que le commentaire d'une fonction, et ce soit à l'aide de requêtes sql, soit à l'aide de psql sous linux…

J'ai essayé directement sous la console ceci :
\d nom_sequence

mais ça me renvoie ceci et non le commentaire en question :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
Séquence « public.act_id »
    Colonne    |  Type   
---------------+---------
 sequence_name | name
 last_value    | bigint
 increment_by  | bigint
 max_value     | bigint
 min_value     | bigint
 cache_value   | bigint
 log_cnt       | bigint
 is_cycled     | BOOLEAN
 is_called     | BOOLEAN
Auriez vous une idée de comment faire pour récupérer le commentaire d'une séquence et aussi d'une fonction sous postgres, comme on récupère le commentaire d'une table ou de ses champs ?

Pour une table je fais comme ça et ça marche :
Code :
1
2
3
4
5
6
7
8
9
 
-- Premièrement je récupère l'oid correspondant à ma table
SELECT oid FROM pg_class WHERE relname = 'nom_table';
 
-- Puis je récupère le commentaire
SELECT description FROM pg_description WHERE objoid = '123456789' AND objsubid = 0;
 
-- On peut aussi récupérer le commentaire comme ça :
SELECT col_description('123456789','0');
Cordialement,
Ginger
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2011, 12h32   #2
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Avec psql, \ds+ devrait faire l'affaire pour une séquence ou \df+ pour une fonction.
En SQL, on peut aussi aller chercher dans pg_description comme pour une table, mais avec l'OID de la séquence.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2011, 14h26   #3
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Merci pour la réponse Pour le commentaire d'une séquence ça fonctionne bien en psql :
Ainsi que par ces 2 solutions de requête sql :
Code :
1
2
SELECT col_description('321654987','0');
SELECT description FROM pg_description WHERE objoid = '321654987' AND objsubid = 0;
Pour le commentaire d'une fonction ça marche aussi avec psql, par contre en sql je n'arrive pas à récupérer l'oid de la fonction, ça existe au moins ?

J'ai essayé ces 3 solutions :
Code :
1
2
3
SELECT oid FROM pg_class WHERE relname = 'ma_fonction(param1, param2, param3)';
SELECT oid FROM pg_class WHERE relname = 'ma_fonction()';
SELECT oid FROM pg_class WHERE relname = 'ma_fonction';
Mais le champ oid reste vide peut-être que c'est normal ?
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2011, 14h49   #4
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Dans le cas d'une fonction l'OID doit être récupéré dans pg_catalog.pg_proc (plutôt que pg_class).
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/11/2011, 15h11   #5
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
J'ai essayé ça :
Code :
1
2
 
SELECT 'ma_fonction(character varying,bigint,numeric)'::regprocedure::oid;
Et ça renvoie bien l'oid de la fonction
Je récupère la liste des fonctions comme ça :
Code :
1
2
 
SELECT * FROM pg_proc proc JOIN pg_language lang ON proc.prolang = lang.oid WHERE lang.lanname = 'plpgsql';
et donc pour ta solution (merci ) j'ai tenté ceci :
Code :
1
2
 
SELECT oid FROM pg_catalog.pg_proc WHERE proname = 'calcul_montant_remise' AND proargnames = '{param1,param2,param3}' ORDER BY proname
Mais si il y a plusieurs fonctions avec le même nom, comment savoir quel résultat est le bon ? Est ce possible de comparer les résultats avec le champ proargtypes ? C'est ce qui me semble être la seule solution de comparaison en ce cas…

Si oui, est ce que chaque type (chaine, entier, decimal etc…) possède un numéro bien spécifique ? Parce que si j'affiche les résultats de cette requête, soit l'oid, le nom, les arguments et les types de la fonction :
Code :
1
2
 
SELECT oid, proname, proargnames, proargtypes FROM pg_catalog.pg_proc WHERE proname = 'ma_fonction'
Résultats (2 lignes de résultats que j'ai condensé ici pour plus de clarté):
Code :
1
2
3
4
5
 
oid : 123456789 | 321654987
proname : ma_fonction | ma_fonction
proargnames : {character varying,bigint,numeric} | {character varying,double precision,numeric}
proargtypes : 1043 20 1700 | 1043 701 1700
Et bien 1043 correspondrait à character varying, 20 à bigint, 1700 à numeric et double precision à 701…
Est ce que c'est toujours pareil pour tout le monde ?

Parce que si oui, comment écrire cette requête correctement ? :
Code :
1
2
 
SELECT 'ma_fonction(1043,20,1700)'::regprocedure::oid;
Ou alors comment récupérer les bons types des paramètres de la fonction ma_fonction ?

En attendant j'utilise ma solution (qui au final fait bien la différence entre les fonctions grâce aux types des parametres…)
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2011, 18h38   #6
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Citation:
Et bien 1043 correspondrait à character varying, 20 à bigint, 1700 à numeric et double precision à 701…
Est ce que c'est toujours pareil pour tout le monde ?
Oui ce sont les OIDs des types dans pg_type.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 16/11/2011, 10h41   #7
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Ah ok

J'ai ces deux requêtes :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
-- récupère tous les noms des types
SELECT typname FROM pg_type 
 
-- Récupère toutes les fonctions et leurs types de paramètres
SELECT proname, proargtypes, proargnames 
FROM pg_proc proc 
JOIN pg_language lang ON proc.prolang = lang.oid 
WHERE lang.lanname = 'plpgsql';
 
-- la 2e requete renvoie :
nom_fonction1, 1043 20 1700, {param1,param2,param3}
nom_fonction2, 1043 701 1700, {param1,param2,param3}
En fait il faudrait que je puisse retrouver les typname correspondant à chaque proargtypes de chaque fonction trouvée, donc j'ai essayé de faire une jointure entre les tables pg_type et pg_proc :
Code :
1
2
3
4
5
6
7
8
9
10
11
 
-- récupère toutes les fonctions et leurs types (numeros et noms)
SELECT proname, proargtypes, proargnames, typname 
FROM pg_proc proc 
JOIN pg_type ON proargtypes[0] = pg_type.oid
JOIN pg_language lang ON proc.prolang = lang.oid 
WHERE lang.lanname = 'plpgsql';
 
-- Ce qui renvoie :
nom_fonction1, 1043 20 1700, {param1,param2,param3}, varchar
nom_fonction2, 1043 701 1700, {param1,param2,param3}, varchar

Suivons par exemple nom_fonction1 :
Code :
1
2
3
 
-- Si je met proargtypes[1] ça renvoie int8
-- Si je met proargtypes[2] ça renvoie numeric
Probleme résolu merci beaucoup !
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/11/2011, 13h46   #8
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Sinon tu peux faire la même chose que psql c'est-à-dire utiliser la fonction pg_catalog.pg_get_function_arguments(). Elle prend l'oid de la fonction et elle renvoie la liste en texte des arguments de la fonction avec leurs types.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 15h26   #9
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Bonjour

J'essaie de faire la même chose que ce que j'avais fait, soit ceci :
Citation:
SELECT proname, proargtypes, proargnames, typname
FROM pg_proc proc
JOIN pg_type ON proargtypes[0] = pg_type.oid
JOIN pg_language lang ON proc.prolang = lang.oid
WHERE lang.lanname = 'plpgsql';

-- Ce qui renvoie :
nom_fonction1, 1043 20 1700, {param1,param2,param3}, varchar
nom_fonction2, 1043 701 1700, {param1,param2,param3}, varchar
… Mais il faudrait que ça me renvoie ça :
Code :
1
2
 
nom_fonction1, 1043 20 1700, {param1,param2,param3}, varchar bigint numeric
Je ne sais pas comment faire ma requête pour que ça trouve le nom de chaque type correspondant au numéro de chaque type…
Plus explicitement :
1043 20 1700 CORRESPOND A varchar bigint numeric

(et donc pour l'instant j'arrive seulement à récupérer varchar…)

En attendant j'essaie d'utiliser ta solution pg_catalog.pg_get_function_arguments() merci

EDIT


Si je fais ça :
Code :
1
2
3
4
5
6
7
8
9
10
 
-- essai 1
SELECT pg_catalog.pg_get_function_arguments(p.oid) 
FROM pg_catalog.pg_proc p 
 
-- essai 2
SELECT pg_catalog.pg_get_function_arguments(p.oid) 
FROM pg_catalog.pg_proc p 
JOIN pg_language lang ON p.prolang = lang.oid 
WHERE lang.lanname = 'plpgsql'
Ca me renvoie une erreur :
Code :
1
2
3
4
5
6
7
8
9
10
 
RROR:  FUNCTION pg_catalog.pg_get_function_arguments(oid) does NOT exist
HINT:  No FUNCTION matches the given name AND argument types. You may need TO ADD explicit type casts.
 
 
********** Erreur **********
 
ERROR: FUNCTION pg_catalog.pg_get_function_arguments(oid) does NOT exist
État SQL :42883
Astuce : No FUNCTION matches the given name AND argument types. You may need TO ADD explicit type casts.
… ?
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 16h08   #10
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
C'est quelle version de postgresql?
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 16h15   #11
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Je suis sous pg_admin version 1.14 et pour postgres j'ai la 8.0.15
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 16h17   #12
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Non il faut faire pour avoir la version de postgresql
Les objets et fonctions de pg_catalog dépendent pas mal de la version de postgresql.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 16h21   #13
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Oui je viens de voir ça j'ai mis la version dans le post précédent du coup.
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 17h40   #14
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Ah je pense que j'ai trouvé une alternative :
Code :
1
2
3
4
5
6
7
 
SELECT typname 
FROM pg_proc proc 
JOIN pg_type ON proargtypes[0] = pg_type.oid OR proargtypes[1] = pg_type.oid OR proargtypes[2] = pg_type.oid OR proargtypes[3] = pg_type.oid OR proargtypes[4] = pg_type.oid 
JOIN pg_language lang ON proc.prolang = lang.oid 
WHERE lang.lanname = 'plpgsql' 
AND proargtypes = '1043 701 1700 20 20';
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 11h08   #15
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Bonjour

Le code que j'ai trouvé hier fonctionne bien, mais quand il y a une centaine de requêtes à faire ça met un temps fou (j'execute mes requêtes dans une boucle php, je sais ce n'est pas bien :s) :
Code :
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// données parametres
$hote = $_POST['hote'];
$port = $_POST['port'];
$bdd = $_POST['bdd'];
$util = $_POST['util'];
$mdp = $_POST['mdp'];
$proj = $_POST['proj'];

// connexion à la base
$connect = pg_connect( "host=".$hote." port=".$port." dbname=".$bdd." user=".$util." password=".$mdp );

// je recupere les fonctions et leurs arguments
$reqArgs = 'SELECT proname, proargnames 
FROM pg_proc proc 
JOIN pg_language lang ON proc.prolang = lang.oid 
WHERE lang.lanname = \'plpgsql\';';
$resArgs = pg_query($connect,$reqArgs);

$fonctions[] = array(); // tableau des fonctions
$tabArgs = array(); // tableau des arguments
while($rowArgs = pg_fetch_array($resArgs))
{
        $fonctions[] = $rowArgs[0];	
       $tabArgs[] = $rowArgs[1];
}

for( $i=0; $i<count($tabArgs); $i++ )
{
        $arg = substr( $tabArgs[$i],1,strlen($tabArgs[$i]) );
	$arg = substr( $arg,0,(strlen($arg)-1) );
	
	// on compte le nb d'arguments
	$nbArg = substr_count($arg,',')+1;
	
	// on execute la requete
	$reqComFct = 'SELECT proname, typname 
	FROM pg_proc proc';
	
	for( $j=0; $j<$nbArg; $j++)
	{
		if($j == 0)
		{
			$reqComFct .= ' JOIN pg_type ON proargtypes['.$j.'] = pg_type.oid';
		}
		if($j > 0)
		{
			$reqComFct .= ' OR proargtypes['.$j.'] = pg_type.oid';
		}
	}
	
	$reqComFct .= ' JOIN pg_language lang ON proc.prolang = lang.oid 
	WHERE lang.lanname = \'plpgsql\' 
	ORDER BY proname;';
	echo $reqComFct; // si j'affiche toutes les requetes, aucun pb elles s'affichent correctement
	
	$resComFct = pg_query($connect,$resComFct);
	echo $resComFct; // par contre évidemment dès que je veux executer toutes mes requetes, ça prend beaucoup trop de temps au risque de faire planter le navigateur...
}
Est ce que c'est possible de faire autrement ? :s
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 12h12   #16
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Si au final le but est similaire à la commande \df de psql (liste de toutes les fonctions avec leurs arguments) tu peux lancer psql avec l'option -E, faire \df et voir quelle requête il fait lui (c'est à ça que sert l'option -E).
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 14h44   #17
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Merci c'est parfait

J'ai testé \df et \df+, voici ce la requête sql pour cette dernière commande :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
SELECT n.nspname AS "Schéma",
  p.proname AS "Nom",
  CASE WHEN p.proretset THEN 'setof ' ELSE '' END ||
  pg_catalog.format_type(p.prorettype, NULL) AS "Type de données du résultat",
  pg_catalog.oidvectortypes(p.proargtypes) AS "Type de données des paramètres",
  u.usename AS "Propriétaire",
  l.lanname AS "Langage",
  p.prosrc AS "Code source",
  pg_catalog.obj_description(p.oid, 'pg_proc') AS "Description"
FROM pg_catalog.pg_proc p
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
     LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang
     LEFT JOIN pg_catalog.pg_user u ON u.usesysid = p.proowner
WHERE p.prorettype <> 'pg_catalog.cstring'::pg_catalog.regtype
      AND p.proargtypes[0] <> 'pg_catalog.cstring'::pg_catalog.regtype
      AND NOT p.proisagg
      AND pg_catalog.pg_function_is_visible(p.oid)
ORDER BY 1, 2, 3, 4;
Elle renvoie toutes les fonctions et leurs commentaires, nikel.

je ne comprend pas le ORDER BY 1, 2, 3, 4 par contre :s A quoi correspondent les 1 2 3 et 4 ? EDIT --> Ah j'ai compris, il s'agit de chaque colonne dans le select c'est bien ça ?

Je vais essayer de la modifier pour que ça renvoie seulement les fonctions du schéma, et non les fonctions postgres du catalogue (pg_catalog).

EDIT

Voici la requête qui récupère toutes les fonctions et leurs commentaires :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
SELECT p.proname AS "Nom", pg_catalog.obj_description(p.oid, 'pg_proc') AS "Description"
FROM pg_catalog.pg_proc p
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang
LEFT JOIN pg_catalog.pg_user u ON u.usesysid = p.proowner
WHERE p.prorettype <> 'pg_catalog.cstring'::pg_catalog.regtype
AND p.proargtypes[0] <> 'pg_catalog.cstring'::pg_catalog.regtype
AND NOT p.proisagg
AND pg_catalog.pg_function_is_visible(p.oid) 
AND n.nspname = 'public'
ORDER BY 1;
Un grand merci pour tes réponses ça m'a beaucoup aidé !
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 15h08   #18
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Citation:
je ne comprend pas le ORDER BY 1, 2, 3, 4 par contre :s A quoi correspondent les 1 2 3 et 4 ? EDIT --> Ah j'ai compris, il s'agit de chaque colonne dans le select c'est bien ça ?
Oui c'est un raccourci qui veut dire ordonne par la 1ere colonne, puis par la 2eme etc...
Ca évite de recopier toute l'expression dans le ORDER BY
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 15h20   #19
Nouveau Membre du Club
 
Inscription : mai 2009
Messages : 105
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 105
Points : 31
Points : 31
Ok ! C'est bien pratique pour ordonner.

Encore merci !
ginger4957 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h18.


 
 
 
 
Partenaires

Hébergement Web