Vous n'êtes pas identifié(e).
Est-ce que id de A est une clef primaire ?, Est-ce que id de B est une clef primaire ?,
Si oui, pourquoi ne pas les créer à titre de clef primaire ?
Un index n'est pas la même chose qu'une clef car une clef primaire implique l'unicité alors que ce n'est pas le cas d'un index.
D’où votre hachage puisque les ID ne sont pas uniques !
De plus des tables de plus de 20 colonnes, ne représentent généralement pas des tables relationnelles mais une simple transposition de fichiers. Or un SGBRD est fait pour faites des tables et non des fichiers.
Bref, commencez par revoir votre conception de la base en faisant des vrais tables et non des fichiers.
Lisez l'article que j'ai écrit à ce sujet : http://blog.developpez.com/sqlpro/p1007 … s-petites/
En, sus, nommez vos colonnes avec de vrais noms et non pas F1 à F48. Et enfin, dans votre base de données, toutes les colonnes doivent avoir un nom différents, sauf celle qui servent de clef étrangères....
A +
Il aurait fallu créer les 3 index :
(A), (A, B) et (B)
A +
Récrivez votre requête comme ceci :
WITH
T AS
(select count(*) AS N from matab)
SELECT COALESCE((SELECT N FROM T), 0) AS RESULTATA
Amusant... On en revient à la demande de DDL que j'ai posté en 1ere réponse à ce fil de discussion et pour laquelle on m'a menacé d'être banni !
A +
Sans la requête originale, ni le DDL des tables en jeu, pensez vous que la boule de cristal intégrée dans PG puisse vous donner une réponse ?
Mais comme le "serarch path" peut changer à tout moment, je ne voit pas l'intérêt de l'oublier pour ces schémas là.
Et par votre réponse, vous me confirmez bien qu'il ne le met pas lorsque c'est dans le "search path".
A +
1) vous aurez sans doutes de meilleures performances si vous utilisez une table plustôt que les UNION
2) vous n'avez pas besoin d'autant de parenthèses
3) pour le BETWEEN, c'est un comportement standard pour rendre le prédicat sargable.
A +
Par définition, les tables systèmes ne vous appartiennent pas. En principes ce ne devraient être que de vues et pas des tables. Il n'est donc pas possible d'en modifier le comportement pour vos besoin car il est parfaitement possible que la vue soit modifiée ou supprimée sans préavis au gré des évolutions de PostGreSQL !
A +
Oui, car toucher aux privilèges (et non pas droits) pose des problèmes de "recompilation" donc de perf.... Mieux vaut que le schéma soit le plus stable possible
Pour les tables spécifiques, ça n'est pas une obligation. De plus tu peut jouer sur les schéma en ventilant tes vues sur des schémas différents et donner des privilèges au niveau du schéma. Ainsu qune même vue peut exister dans deux schémas différents avec des colonnes différentes et des privilèges spécifiques.
Enfin, une bonne chose aurait été que PG implémente les trigger DDL comme c'est le cas de SQL Server, car tu aurait pu gérer automatiquement par du SQL dynamique l'attribution des privilèges en cas d'évolution des structures des tables et vues
A +
Je viens de publier un article sur la création des fonctions scalaires en PGplSQL avec comparaison de SQL Server et PostGreSQL.
Vous pouvez le lire à : http://blog.developpez.com/sqlpro/p1006 … fonctions/
Il est amusant de savoir que j'ai été vivement critiqué sur ce forum pour avoir osé comparé SQL Server et PostGreSQL !!!
Je prépare la suite de cette série d'article qui comportera :
2) les fonctions table et les fonctions "procédures"
3) les fonctions "trigger"
Mais ce matériel ne sera pas disponible avant quelques semaines !
A +
Il suffit de créer une table de regroupement ou bien d'utiliser une CTE pour simuler cette table.
Exemple :
WITH T_GROUP AS
(SELECT 1 AS GROUPE, '101201' AS DEBUT, '110103' AS FIN
UNION ALL
SELECT 2 AS GROUPE, '110201' AS DEBUT, '110303' AS FIN
UNION ALL
SELECT 3 AS GROUPE, '110401' AS DEBUT, '110503' AS FIN
UNION ALL
SELECT 4 AS GROUPE, '110601' AS DEBUT, '110703' AS FIN)
SELECT ...
FROM MaTable AS T
INNER JOIN T_GROUP AS G
ON T."date" BETWEEN G.DEBUT AND G.FIN
GROUP BY GROUPENOTA : il n'est pas sain d'intitulé un identifiant SQL (nom de table, de colonne...) par un mot clef de SQL comme DATE. Vous allez au devant de problèmes....
A +
Une vue et le grant associé est pourtant la meilleure solution en terme d'évolutivité, et de performances.
En principe on devrait toujours développer les applications clientes à partie des vues et jamais en accès direct aux tables.
C'est le MED (Modèle Externe de Données), composé de vues, procédures et trigger, généralement le grand oublié des développeurs !
Quelques références sur le sujet :
http://www.cybermed.jussieu.fr/Broussai … Chap4.html
http://errachidiaista.co.cc/cc/fichiers … rique2.doc
A +
...Caster un int dans un smallint, ça pourrait valoir de belles surprises à l'exécution: que faire quand j'ai deux variantes d'une fonction: une qui prend 2 smallint en paramètre, une qui prend deux bigint, et que la fonction smallint va sortir en erreur alors que la bigint va fonctionner (dépassement de capacité si je fais tout bêtement la somme)? Ça aussi c'est totalement incompréhensible pour l'utilisateur. Les casts sont donc implicites vers des types plus capacitifs. Le cast smallint vers int et vers bigint le sont. Real vers numeric aussi.
Quand je dit "au plus juste", c'est bien entendu pas au plus petit, mais vers le type le plus juste qui permet de satisfaire les différents types donné. Il n'y a donc jamais de de INT vers SMALLINT !
Sauf que ce n'est pas le comportement de PostGreSQL en matière de passage des arguments aux fonctions, et cela est un handicap, car oblige soit à caster explicitement dans ses requêtes, soit à faire plusieurs version de la même fonction.
... sur la recompliation...
Rien à voir, les procédures PLPgSQL ne sont pas stockées compilées dans la base. Elles sont compilées à la première exécution, dans chaque session. Et recompilées automatiquement quand une nouvelle version devient visible.
C'est bien là le problème. Il y a des fois ou une recompilation favorise la création d'un plan plus adapté. Et cela fait défaut au niveau de PG.
... sur la comparaison PG SQL Server ...
Excellente généralisation. Je remarque simplement que vous revenez toujours sur SQL Server. Et que ce n'est pas l'exemple pertinent ici. Ici, c'est la comparaison avec Oracle qui est la plus intéressante. Et la plus en la défaveur de PLPgSQL. Gardez donc vos délires sur les «gens du libre».
Le mot est donc lâché... Je suis délirant ! Merci, votre masque est tombé !!!
A +
- la case du tableau final «récupération des erreurs» est fausse, ou maladroitement formulée: on peut avoir autant de bloc exception qu'on veut dans une fonction, pour peu que chacune soit dans un bloc begin/end. Il y a d'ailleurs une modification du comportement de RAISE sur le sujet sur la 9.1. Vous pouvez lire mon doc sur le sujet: http://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.1
Je vais corriger le tableau. Votre lien ne marche pas.
- pour l'absence de masquage de code, ce n'est vrai qu'en plpgsql. En C, évidemment, mais même dans d'autres langages aussi qui ont des modules d'obfuscation, il y a moyen. mais il ne faut pas attendre d'option pour ça dans plpgsql avant un moment à mon avis, le masquage de code n'est pas vraiment dans les préoccupations de gens développant un logiciel sous licence affiliée à BSD. Si quelqu'un veut en contribuer un, par contre, je présume que ça sera accepté, si c'est fait proprement.
L'article parle de fonction en, PGplSQL, pas en C ou d'autres langage. Le fait de coder des fonctions directement en natif est souvent plus performant pour des fonctions basiques proche du traitement des données. De plus les langages externes ont tous le même défaut d'impédance ce qui les rends difficilement apte aux traitements des données relationnelles (gestion du NULL, de la collation...).
Le faite que PostGreSQL ne mette pas en place des mécanisme de masquage des UDF PLpgSQL est dommage, car la plupart des SGBDR le font...
- un lien vers la doc en français ça aurait pu être bien, vu qu'on s'embête à la traduire, même si moi aussi je ne lis que la version anglaise.
Le problème est que la traduction est parfois assez mauvais comme l'exemple que j'ai donné en PS dans l'article. D’où mon souhait d'aller à la source pour être le plus exact possible.
- un mot sur anyelement/anyarray lors du polymorphisme, ça aurait certainement valu la peine (et ça aurait permis d'être complet dans le tableau récapitulatif sur ce point)
Mon article ne traite pas des types de données de PGplSQL, ni du polymorphisme en général, mais des fonctions. J'aurais aussi pu parler de bien d'autres types, ainsi que des choses plus subtiles sur le polymorphisme, mais ce n'est pas le sujet !
- pour ce qui est de l'impact du logging sur les performances, c'est mesurable, mais loin d'être énorme dans la majorité des cas. J'ai des clients qui tracent intégralement plusieurs milliers de requête à la seconde, l'impact reste faible, excepté sur la taille des logs bien sûr. Et on n'est pas obligé de les envoyer dans pg_log, on peut l'envoyer dans un syslogger, voir un syslogger sur un serveur distant, pour avoir un mécanisme asynchrone. En tout cas, conseiller aux lecteurs passer les message en terse, je ne pense pas que ça soit une bonne idée: on perd la trace du «contexte», le «hint», la requête en cours. Donc on rend le débogage ou l'analyse des traces bien plus difficile. Le plus important, c'est de ne pas dépasser debug1, après ça log vraiment très fort. Par ailleurs, le client_min_messages peut se modifier dans une session, avec un SET. Pas la peine d'éditer le fichier de configuration, et d'altérer toutes les sessions, si c'est pour débugger ce qu'on est en train de faire.
Là vous aurez du mal à me convaincre, car j'ai vu en prod des ralentissements épouvantables due à la journalisation, notamment quand l'install de PG a été faite sans considération des disques... Et en production on ne fait pas de débogage... Ça c'est valable dans les premières heures de prod. Pas dans la continuité !
- le transtypage n'est pas fait par le compilateur, mais directement dans la phase d'analyse de la requête appelante. le cast de int -> smallint est déclaré 'AS ASSIGNMENT', pas 'AS IMPLICIT', ce qui explique qu'il est utilisable 'dans le SQL' (pour un insert, je présume ?), mais pas automatiquement pour détecter si une fonction est candidate dans le cadre du polymorphisme. Le cast dans l'autre sens est implicite, lui, ce qui est logique. Tout ça est expliqué dans la doc de 'CREATE CAST'. Trop de casts implicites risqueraient de rendre plusieurs fonctions 'candidates', et donc de rendre les casts normaux inutilisables.
Sauf que c'est contraire aux principes fondamentaux du SQL qui est de réaliser systématqiuement des CAST implicite au plus juste... et c'est particulièrement lourd pour le développement comme pour l'écriture des requêtes...
Je présume que cela est aussi du au fait qu'il n'existe pas de RECOMPILE....
Et puis, cette apparemment irrépressible envie de comparer à SQL Server… le plpgsql est fait avant tout pour ressembler au PL/SQL d'Oracle (c'est très clair dans la doc, les développeurs ne s'en sont jamais caché non plus), même si évidemment il ne va pas aussi loin (mais il y a 14 autres langages de procédures stockées pour compenser, en cas de besoin).
Cela ne vous intéresse pas et apparemment cela vous ennui que je fasse ce genre de comparaison. Pourtant cela aide bien des gens à commencer par mes clients qui passent de SQL Server à PG et inversement (d'ailleurs plus dans ce sens) mais aussi utilisent les deux ! Et c'est toujours instructif de voir ce que font les autres, en particulier parce que PG emprunte à beaucoup de SGBDR les mécanismes nouveaux qu'il y introduit, à commencer, comme vous l'avez justement fait remarqué, par Oracle.
Il est d'ailleurs amusant de voir qu'en règle général chez les gens du libre, dès que l'on compare à un produit commercial, ils ressentent immédiatement le besoin de dire que ce n'est pas bien, ça ne sert à rien, c'est stupide, que sous Linux c'est toujours mieux.... etc. Le problème c'est que dans la vrai vie c'est pas d'un côté 100% libre et de l'autre 100% commercial. La plupart des entreprises ont à la fois du libre et du commercial et je connais peu d'entreprises qui n'ont que du libre ! Voyez par exemple les postes client !
Mais là le sujet devient politique !
A +
Bonjour,
voici le premier d'une nouvelle série d'articles consacrés au développement des fonctions sous PLpgSQL
Ce premier article est consacré aux fonctions scalaires appelées dans la norme SQL "UDF" pour User Defined Function
Il sera suivi dans les mois prochains de deux autres articles : l'un sur les fonctions de manipulation des tables et l'autre sur les fonctions
Sommaire :
0 - INTRODUCTION
1 - CRÉATION D'UNE FONCTION SCALAIRE
2 - UTILISATION DE LA FONCTION
3 - FONCTION AVEC LANGAGE SQL
4 - QUELQUES MOTS CLEFS DE PL/pgSQL
5 - ARGUMENTS
6 - VARIABLES ET CONSTANTES
7 - POLYMORPHISME
8 - STRUCTURES DE TEST ET BRANCHEMENTS
9 - GESTION D'ERREUR
10 - DÉBOGAGE
11 - DIRECTIVES DIVERSES À LA CRÉATION DES FONCTIONS
12 - MÉTADONNÉES DES FONCTIONS
13 - CONSEILS DE CODAGE
ANNEXE 1 : COMPARAISON MS SQL SERVER vs POSTGRESQL
ANNEXE 2 : VOCABULAIRE
ANNEXE 3 : QUELQUES RÉFÉRENCES
A lire : http://blog.developpez.com/sqlpro/p1006 … fonctions/
Toutes vos remarques et conseils sont les bienvenus !
A +
Ah justement ça m'évite de créer un nouveau thread ! La question que je voulais poser ce matin est la suivante :
"La place des colonnes est-elle importante sous PostgreSQL ?", car en effet il me semble que vous certaines db il est fortement recommandé de placer les colonnes de type de taille fixe au début, et les type variables (text, varchar) à la fin.
Visiblement, d'après ce que gleu indique, PostgreSQL ne regroupe pas automatiquement les types fixes en debut de ligne, donc j'en deduis que la place des colonnes suivant leur type influe directement sur les performances.
Si oui, l'impact est-il vraiment mesurable sur une table qui fait < 1 Go ?
Oui, sur des grosses tables si vous faites beaucoup d'UPDATE....
A +
Il faut utiliser une contrainte CHECK !
CREATE TABLE thirdLevel
(
id bigserial primary key,
name varchar(255) NOT NULL,
type varchar(255) NOT NULL DEFAULT 'info' CHECK (type IN ('info', 'exemple', type = 'lien'))
);A lire sur les contraintes CHECK : http://sqlpro.developpez.com/cours/sqla … ie2#L7.1.6
Et aussi : http://sqlpro.developpez.com/contrainte … es_SQL.pdf § 4
Au passage nommer une colonne type et même name est particulièrement mauvais... type étant un mot clef de SQL, vous allez au devant de problèmes...
A +
Dans ce cas utilisez soit un trigger, soit une UDF lié avec contraintes CHECK.
A +
Mea culpa, j'avais oublié d'enlever les # des entrées de postgresql.conf !!!
Merci
A +
Bonjour,
j'ai besoin des tester des routines complexes (donc faire du RAISE DEBUG...), mais je ne sais pas comment passer le serveur en mode debug car cela ne journalise rien... (même en modification les paramètres log_min_messages et client_min_messages)
Pour mémo, ma config :
Windows XP,
PG 8.3. 8.4 et 9.1
client d'admin pgAdminIII
A +
Effectivement, je confirme qu'il y avait bien un produit cartésien (requête sur 4 fois la même table) suivi d'un ORDER BY ; je vais donc faire un système de fichiers dédié ; ceci dit, je ne peux pas empêcher certains utilisateurs de faire ce genre de requête...i
Si en leur imposant de faire des jointures avec des JOIN et non dans la clause WHERE... Cela empêche ce type d'erreur est cette syntaxe est la norme depuis la version 1992, soit 19 ans !!!
A lire : http://sqlpro.developpez.com/cours/sqla … res/#LII-B
Je m'étonne encore qu'il y ai des développeurs faisant leur jointures dans la clause WHERE !
Quel manque de formation....
A +
Bref, désinstallation et reinstallation... !
Ok merci
A +
Exemple :
CREATE FUNCTION F_JOUR_EN_8(d DATE)
RETURNS DATE
AS
$corps$
DECLARE semaine CONSTANT INTEGER := 7;
date_retour DATE;
BEGIN
d := d + semaine * INTERVAL '1 DAY';
RETURN d;
END;
$corps$
LANGUAGE PLPGSQLMessage d'erreur précis :
ERREUR: « $1 » est déclaré CONSTANT
CONTEXT: compilation de la fonction PL/pgsql « f_jour_en_8 » près de la ligne 4
Avec ou sans alias l'utilisation des arguments est passé en valeur !
A +
8.1. Auparavant, il était possible d'utiliser la clause ALIAS FOR (http://docs.postgresql.fr/8.0/plpgsql-d … ON-ALIASES), qui donnait le même résultat.
Oui, ça j’avais vu, mais le problème est que même en ALIAS c'est de la constante !!!!
A +
Bonjour,
Savez vous de quand date (quelle version de PG) la syntaxe permettant d'utiliser directement le nom des paramètres dans le corps des functions à la place de leur position ordinale avec les $1, $2, $3... ?
A +