Database-SQL-RDBMS HOW-TO pour Linux &nl (PostgreSQL Object Relational Database System), &nl version française. <author>Al Dev (Alavoor Vasudevan) <htmlurl url="mailto:aldev@hotmail.com" name="aldev@hotmail.com"> &nl Adaptation française <htmlurl url="mailto:apb@club-internet.fr" name="Albert-Paul Bouillot"> &nl </author> <date>v2.0, 17 November 1997, version française Janvier 1998 <abstract> Ce document explique COMMENT mettre en place une Base de Données Relationnelle SQL Objet de la nouvelle génération "PostgreSQL" sur votre système unix qui pourra être utilisée comme Base de Données Serveur d'Application ou Serveur Web. PostgreSQL se rapproche chaque mois un peu plus des standards Internationaux ISO et ANSI SQL 1998,92,89. Ce document donne aussi des informations sur les programmes d'interface à la base de données tels que frontaux GUIs, outils RAD (Développement Rapide d'Application ), interfaçage des langages de programmation ("C", "C++", Java, Perl), pilotes ODBC, JDBC ainsi que sur les outils et programmes interfaçage d'une Base de Données Web . L'information donnée ici est valable pour toutes autres plates-formes unix et autres Bases de Données. Cette information sera très utile aux nouveaux utilisateurs de PostgreSQL, des Bases de Données et du langage SQL. </abstract> <!-- Table of contents --> <toc> <!-- Begin the document --> <sect>Introduction <p> Tout système informatique au monde a besoin d'une base de données pour stocker/retrouver les informations. Sans base de données, un ordinateur devient inutile. La première raison pour laquelle on utilise un ordinateur est de stocker, retrouver et traiter l'information et de faire cela très rapidement, et donc, de faire économiser du temps. En même temps le système doit être simple, robuste, rapide, fiable, économique et d'utilisation aisée. Les systèmes de gestion de base de données les plus courants sont basés sur les spécifications ISO (International Standard Organisation) SQL lesquelles sont également basées sur les standards américains ANSI SQL. Les spécifications courantes généralement utilisées sont l'ANSI SQL 92 et l'ANSI SQL 89. Le prochain standard est le SQL 1998/99 aussi appelé SQL-3. Les systèmes de gestion de bases de données les plus répandus tels que Oracle, Sybase et Informix s'appuient sur ces standards ou essaient de les implanter. <p> Ainsi qu'il est indiqué dans ce document, il y a plus de 20 variétés, commerciales/internet, de systèmes de gestion de base de données actuellement utilisés dans le monde et beaucoup, beaucoup plus dans un futur proche. En l'absence d'un standard tel que l'ANSI/ISO SQL, il serait très difficile pour l'utilisateur de développer une application une fois pour toutes et de l'utiliser avec tous les systèmes de gestion de bases de données. Aujourd'hui, l'utilisateur veut développer son application une fois pour toutes en utilisant les normes ISO SQL, ODBC, JDBC et la vendre afin qu'elle puisse être utilisée sur une grande variété de systèmes de gestion de base de données a travers le monde. <p> PostgreSQL est la Base de Donnée LIBRE la plus populaire au monde qui implante la plupart des standards ISO SQL, ANSI SQL/98, SQL/92 et ANSI SQL/89 RDBMS. PostgreSQL est une base de données relationnelle Objet de la nouvelle génération et les futurs standards ANSI SQL tels que le SQL 1998 (SQL-3) et au-delà traiteront de manière croissante de bases de données Objet et de types de données Objet. PostgreSQL est le seul SGBD (RDBMS - Relational Data Base Management System) au monde qui supporte les bases de données Objet et SQL. Ce document vous explique comment installer le système de gestion de base de données ainsi que tous les paquetages concernant les bases de données, comment mettre en place la base de données Web, la base de données application , les frontaux GUIs et les programmes interfaçage. On ne saurait trop RECOMMANDER d'écrire vos applications bases de données 100 &percnt compatibles avec les standards ISO/ANSI SQL, ODBC, JDBC ceci rendant votre application portable sur de multiples SGDBD (Systèmes de gestion de Bases de Données) tels que PostgreSQL, Oracle, Sybase, Informix etc. La haute qualité, et un large ensemble de possibilités de PostgreSQL viennent du fait que ce système est développé suivant le principe du 'Modèle de développement de Systèmes Ouvert'. Les systèmes ouverts sont ceux ou la totalité du code source est fournie et ou le développement se fait à travers l'internet par une très large communauté de cerveaux humains en réseau. La tendance future des développement logiciels réside dans ce que l'on appelle les "super autoroutes de l'information" qui s'étendent à travers le monde entier. Dans les années à venir, la croissance d'internet va être explosive et de ce fait favorisera l'adoption de PostgreSQL par les utilisateurs. Avec l'application des principes de la physique (quantique, classique, thermodynamique), des mathématiques et des statistiques à la qualité des logiciels, on obtient la meilleure qualité des logiciels 'Systèmes Ouverts' tel que PostgreSQL en mettant le code source des programmes a la disposition d'un grand nombre de cerveaux humains interconnectés par les super-autoroutes de l'information. Plus le nombre de cerveaux au travail sera grand, meilleure sera la qualité du logiciel produit. Le modèle "Système Ouvert" évite aussi de réinventer la roue tout en étant particulièrement économique, en diminuant les délais de distribution et en suivant les lois économiques modernes d'optimisation des ressources nationales et globales. Dans un futur proche, à l'aube du 21-ième siècle, la manière de se procurer un logiciel va changer. Les utilisateurs accorderont en premier lieu leur préférence aux logiciels ouverts tel PostgreSQL. Acheter un logiciel PEUT devenir une attitude archaïque. On a seulement besoin d'acheter un bon matériel, cela vaut mieux de dépenser de l'argent en matériel et trouver le logiciel sur internet. <p> Puisqu'une masse importante de travail a été effectuée sur PostgreSQL au cours des 12 dernières années, cela n'aurait aucun sens de recréer ex-nihilo un autre système de gestion de base de données satisfaisant aux normes ANSI/ISO SQL. Il est bien plus intéressant de prendre le code existant de PostgreSQL, de commencer à l'utiliser, de l'améliorer et d'y ajouter les fonctionnalités manquantes. PostgreSQL n'est pas seulement un SGBD libre mais aussi un "Produit Internet" et à ce titre mérite respect et reconnaissance de tout un chacun. <sect>Qu'est-ce que PostgreSQL ? <p> PostgreSQL Version 6.2.1 patch level 3 est un SGBD libre, son code source complet est fourni. De plus, c'est un SGBD Relationnel-Objet pratiquement conforme (de plus en plus conforme) aux normes ANSI SQL1998,92,89. Il fonctionne sur diverses plates-formes matérielles sous différents Systèmes d'Exploitation. PostgreSQL est une amélioration du SGDB POSTGRES, prototype de recherche de SGDB de la prochaine génération. PostgreSQL, tout en conservant le puissant modèle de données et la richesse des types de données de POSTGRES, remplace le langage de requête PostQuel par un sous-ensemble étendu de SQL. Le développement de PostgreSQL est réalisé par une équipe de développeurs Internet qui sont tous inscrits à la liste de diffusion "PostgreSQL development mailing list". Son coordinateur actuel est Marc G. Fournier <htmlurl url="mailto:scrappy@postgreSQL.org" name="scrappy@postgreSQL.org"> . Cette équipe est maintenant responsable des développements actuels et futurs de PostgreSQL. Les auteurs de PostgreSQL 1.01 sont Andrew Yu et Jolly Chen. De nombreux autres ont contribué au portage, aux tests, à la mise au point et a l'amélioration du code. Le code original Postgres, duquel PostgreSQL est issu, est le résultat de l'effort de nombreux étudiants de troisième cycle, de deuxième cycle et d'enseignants sous la direction du Professeur Michael Stonebraker de l'université de Californie, Berkeley. Le nom original du logiciel à Berkeley était Postgres. Lors de l'ajout des fonctionnalités SQL en 1995, il fut renommé Postgres95. Ce nom fut changé à la fin de 1996 en PostgreSQL. Des millions d'exemplaires du SGBD PostgreSQL sont installés comme serveurs, serveurs Web et serveurs d'application. Ce SGBD est très avancé, c'est un SGBD Relationnel-Objet (ORDBMS). PostgreSQL peut stocker plus de types de données que les types traditionnels entier, caractères, etc. - L'utilisateur peut créer des types, des fonctions, de l'héritage de type etc. (La Version 7.0 rendra ces fonctions avancées encore plus puissantes). PostgreSQL fonctionne sur Solaris, SunOS, HPUX, AIX, Linux, Irix, Digital Unix, BSDi, NetBSD, FreeBSD, SCO unix, NEXTSTEP, Unixware et toutes sortes d'unix. Un portage pour Windows 95/NT est en cours de réalisation. <itemize> <item> Titre : PostgreSQL SQL RDBMS Database (Système de Gestion de Base de Données Relationnelle Objet) <item> Version actuelle : 6.2.1 patch level 3 <item> Age : PostgreSQL a 12 ans. En développement depuis 1985 <item> Auteurs : Développé par des millions d'universités/compagnies sur internet au cours des 12 dernières ANNEES </itemize> <sect>Où le trouver? <p> On peut acheter le CDROM Redhat 4.2 qui contient déjà postgresql en paquetage rpm (a la fois en code source et en binaires) chez : <itemize> <item>Linux System Labs Web site : <url url="http://www.lsl.com/"> 6 (U.S. dollars) <item>Cheap Bytes Inc Web site : <url url="http://www.cheapbytes.com/"> 6 (U.S. dollars) </itemize> <p> Distributions uniquement en binaire de PostgreSQL : <itemize> <item>On peut exécuter PostgreSQL sans compiler le source. Récupérer les binaires pour Intel-Linux de l'url<url url="http://www.redhat.com/pub/contrib/i386/"> le fichier se nomme postgresql-6.2-3.i386.rpm. Son format est de type paquetage redhat 'rpm'. Il contient à la fois le source et les binaires de PostgreSQL. <item>Sites binaires pour Solaris, HPUX, AIX, IRIX, Linux : <url url="ftp://ftp.postgresql.org/pub/bindist"> Si vous faites une compilation pour n'importe laquelle des plates-formes envoyer le binaire à ce site, cela peut être utile aux autres. <item>ftp site : récupérer les binaires pour Intel-Linux de <url url="ftp://ftp.redhat.com/pub/contrib/i386/"> le fichier se nomme postgresql-6.2-3.i386.rpm. Son format est de type paquetage redhat 'rpm'. Il contient à la fois le source et les binaires de PostgreSQL.. </itemize> <p> Sites WWW Web : <itemize> <item>Site Web primaire : <url url="http://www.postgresql.org/"> <item>Site Web secondaire : <url url="http://logical.thought.net/postgres95/"> <item> <url url="http://www.itm.tu-clausthal.de/mirrors/postgres95/"> <item> <url url="http://s2k-ftp.cs.berkeley.edu:8000/postgres95/"> <item> <url url="http://xenium.pdi.net/PostgreSQL/"> <item> <url url="http://s2k-ftp.cs.berkeley.edu:8000/postgres95/"> </itemize> <p> Les sites ftp sont indiqués ci-dessous :- <itemize> <item>Primaire FTP : <url url="ftp://ftp.postgresql.org/pub"> <item>Secondaire FTP : <url url="ftp://ftp.chicks.net/pub/postgresql"> <item> <url url="ftp://ftp.emsi.priv.at/pub/postgres/"> <item> <url url="ftp://ftp.itm.tu-clausthal.de/pub/mirrors/postgres95"> <item> <url url="ftp://rocker.sch.bme.hu/pub/mirrors/postgreSQL"> <item> <url url="ftp://ftp.jaist.ac.jp/pub/dbms/postgres95"> <item> <url url="ftp://ftp.luga.or.at/pub/postgres95"> <item> <url url="ftp://postgres95.vnet.net:/pub/postgres95"> <item> <url url="ftp://ftpza.co.za/mirrors/postgres"> <item> <url url="ftp://sunsite.auc.dk/pub/databases/postgresql"> <item> <url url="ftp://ftp.task.gda.pl/pub/software/postgresql"> <item> <url url="ftp://xenium.pdi.net/pub/PostgreSQL"> </itemize> <p> Le code source de PostgreSQL est aussi disponible sur tous les sites miroirs de sunsite.unc (soit environ 1000 sites autour du globe). Il se trouve dans la distribution Linux Red Hat dans le fichier /pub/contrib/i386/postgresql.rpm. <itemize> <item> Pour obtenir la liste des sites miroirs aller à l'url<url url="ftp://sunsite.unc.edu"> </itemize> <sect>PostgreSQL Supporte des Base de Données extrêmement grandes > 200 Gigas <p> Si vous avez besoin d'utiliser des bases de données extrêmement grandes (supérieures a 5 gigaoctets), il est fortement recommandé d'utiliser des machines 64-bit telles que : Digital Alpha cpu, Sun Ultra-sparc 64-bit cpu, Silicon graphics 64-bit cpu, à venir Intel Merced IA-64 cpu, machines HPUX 64bit , IBM 64-bit machines. Si l'on compile PostgreSQL avec un cpu 64-bit il pourra supporter d'énormes bases de Données et de larges requêtes. Les performances de PostgreSQL pour des interrogations sur de grandes tables et de grandes bases de données sera plus rapide de plusieurs ordres de grandeurs que sur des machines à cpu 32-bit . L'avantage des machines 64-bit est qu'elles disposent d'un grand espace d'adressage mémoire et que le système d'exploitation peut gérer de très grands systèmes de fichiers. Cela permet des meilleures performances avec de grandes bases de données, plus de mémoire centrale (RAM), plus de possibilités etc... <sect>PostgreSQL est-il fiable? <p> Le paquetage de "Test de Régression" permet de s'assurer de son bon fonctionnement. Il est inclus (src/test/regress) dans la distribution et permet à l'ordinateur d'effectuer la vérification des opérations SQL standard ainsi que des capacités de PostgreSQL. L'avantage de ce test effectué par l'ordinateur vient du fait que celui-ci peut effectuer plusieurs millions de test SQL très rapidement. La vitesse de l'ordinateur est un milliard de fois plus rapide que celle de l'esprit humain! Le paquetage de tests contient des centaines de programmes de test SQL. Si vous le jugez utile vous pouvez en ajouter beaucoup d'autres. Dans ce cas penser à envoyer ces tests au site PostgreSQL primaire si vous pensez que cela peut être utile aux autres. Le paquetage de Test de Régression permet d'asseoir la confiance des utilisateurs en PostgreSQL et facilite le déploiement rapide de PostgreSQL sur des systèmes en production sans inquiétude majeure. <sect>Outil GUI frontal pour PostgreSQL (Interface Utilisateur Graphique) <p> PostgreSQL est doté d'une librairie d'interface TCL/TK dans la distribution appelée 'pgtcl'. TCL/TK est un outil de développement rapide d'application et un langage de script extrêmement puissant. On développe une fois pour toutes et on utilise sur NT, Win 95, Linux et tous les systèmes Unix! TCL/TK est également largement utilisé comme langage de script sur internet. Ce qui permet de n'avoir qu'un seul langage pour couvrir tous ses besoins - applications et internet. TCL est l'abréviation de 'Tool Command Language' et TK celle de 'Tool Kit'. Il existe un IDE (Environnement de Développement Intégré) pour TCL/TK nommé SpecTCL. Vérifiez la présence de ce paquetage (format rpm) dans la distribution linux Redhat ou dans l'un des sites sunscript indiquées ci-après. TCL/TK est normalement inclus dans tous les cdrom linux. On peut également l'obtenir à partir des sites - <itemize> <item> <url url="http://sunscript.sun.com/"> <item> <url url="http://sunscript.sun.com/TclTkCore/"> <item> <url url="ftp://ftp.sunlabs.com/pub/tcl/tcl8.0a2.tar.Z"> <item>Manuels de référence: de nombreux livres sur TCL/TK sont disponibles sur le marché. <item> Visual TCL <url url="ftp://ftp.redhat.com/pub/contrib/i386/visualtcl*.rpm"> </itemize> <sect>Outils de développement intégrés pour PostgreSQL (Interface Utilisateur Graphique) <p> Essayez les outils de développement suivants utilisable en conjonction avec les pilotes odbc/jdbc. Ils sont similaires à Borland C++ Builder, Borland JBuilder. Vibe est un IDE Java et C++ (Environnement de Développement Intégré) a été nommé IDE de l'année par la revue "Unix Review". Ce produit à 800 US dollars est disponible pour linux au prix extrêmement bas de 79 US dollars pour un durée limitée. Essayez le! C'est le rêve du développeur. <itemize> <item> Des informations complémentaire sur Vibe sont disponibles à <url url="http://www.LinuxMall.com/products/00487.html"> </itemize> Vous pouvez aussi utiliser Borland C++ Builder, JBuilder, PowerBuilder sur Windows95 pour se connecter à PostgreSQL sur une machine unix au travers de pilotes odbc/jdbc. Outils IDE gratuits - Regardez le CDROM de la distribution RedHat. <itemize> <item> FreeBuilder <url url="ftp://ftp.redhat.com/pub/contrib/i386/free*.rpm"> <item> SpecTCL <url url="ftp://ftp.redhat.com/pub/contrib/i386/spec*.rpm"> <item> JccWarrior <url url="ftp://ftp.redhat.com/pub/contrib/i386/jcc*.rpm"> <item> Applixware Tool <url url="http://www.redhat.com"> <item> XWPE X Windows Programming Environment <url url="http://www.rpi.edu/~payned/xwpe/"> <url url="ftp://ftp.redhat.com/pub/contrib/i386/xwpe*.rpm"> <item> XWB X Windows Work Bench <url url="ftp://ftp.redhat.com/pub/contrib/i386/xwb*.rpm"> <item> NEdit <url url="ftp://ftp.redhat.com/pub/contrib/i386/nedit*.rpm"> </itemize> <sect>ODBC Pilotes pour PostgreSQL <p> ODBC signifie 'Open DataBase Connectivity'. C'est un standard répandu pour accéder aux informations des bases de données de différents vendeurs. Le fonctionnement des applications écrites en utilisant les pilotes ODBC est garanti quelle que soient les bases de données utilisées PostgreSQL, Oracle, Sybase, Informix etc.. <itemize> <item> <url url="http://www.openlinksw.com"> Open Link Software Corporation distribue des ODBC pour PostgreSQL et d'autres bases de données. Open Link dispose aussi d'ODBC gratuits (quantité limitée) vérifier auprès d'eux. <item> <url url="http://stud1.tuwien.ac.at/~e9025461/"> C'est le site primaire de PostODBC (PostgreSQL ODBC) . Malheureusement c'est un site particulièrement lent. <item> <url url="http://www.MageNet.com/postodbc/DOC"> Ce miroir est maintenu par Julia Anne Case qui est aussi un développeur PostODBC majeur. </itemize> <p> Il existe aussi un projet intéressant appelé FreeODBC Pack Package . Il n'y a pas de version PostgreSQL, peut-être pouvez vous y participer. <itemize> <item> <url url="http://www.ids.net/~bjepson/freeODBC/"> c'est une version gratuite d'ODBC. </itemize> <sect>Pilotes UDBC pour PostgreSQL <p> UDBC est une version statique de pilote de gestionnaire et de DLL d'ODBC indépendant, pour intégrer le support de la connectivité base de données directement au niveau des applications. <itemize> <item> <url url="http://www.openlinksw.com"> Open Link Software Corporation vends UDBC pour PostgreSQL et autres SGBD. Open Link dispose aussi d'UDBC gratuits (quantité limitée) vérifier auprès d'eux. </itemize> <sect>Pilotes JDBC pour PostgreSQL <p> JDBC signifie 'Java DataBase Connectivity'. Java est un langage de développement indépendant de la plate-forme d'utilisation développé par Sun Microsystems. Les programmeurs Java sont encouragés à écrire leurs applications en utilisant JDBC pour faciliter la portabilité entre différentes plates-formes telles que PostgreSQL, Oracle, informix, etc. Si vous écrivez des applications Java applications vous pouvez obtenir les pilotes JDBC pour PostgreSQL à partir des sites suivants : Le pilote JDBC est inclus dans la distribution PostgreSQL. <itemize> <item> <url url="http://www.demon.co.uk/finder/postgres/index.html"> Sun's Java connectivity to PostgreSQL <item> <url url="ftp://ftp.ai.mit.edu/people/rst/rst-jdbc.tar.gz"> <item> <url url="http://www.openlinksw.com"> Open Link Software Corporation vends JDBC pour PostgreSQL et autres SGBD. Open Link dispose aussi d'JDBC gratuits (quantité limitée) vérifier auprès d'eux. </itemize> <sect>Kanchenjunga - Java RAD Tool for PostgreSQL <p> Kanchenjunga est un Outil de Développement Rapide d'Application Java pour PostgreSQL. On peut utiliser cet outil pour développer rapidement une application JAVA s'interfaçant à PostgreSQL. <itemize> <item> <url url="http://www.man.ac.uk/~whaley/kj/kanch.html"> </itemize> <sect>Classes Java pour PostgreSQL <p> Ces classes pour PostgreSQL seront très utiles au programmeur JAVA. <itemize> <item> <url url="ftp://www.blackdown.org/pub/Java/Java-Postgres95"> <item> <url url="http://www.blackdown.org"> </itemize> <sect> Pilote d'interface de SGBD Perl (Database Interface DBI) pour PostgreSQL <p> <sect1>interface Perl 5 pour PostgreSQL <p> Cette interface est incluse dans la distribution de PostgreSQL. On la trouve dans le répertoire src/pgsql_perl5. <itemize> <item> Email : <htmlurl url="mailto:E.Mergl@bawue.de" name="E.Mergl@bawue.de"> <item> On la trouve aussi dans - <htmlurl url="ftp://ftp.kciLink.com/pub/PostgresPerl-1.3.tar.gz"> <item> Page d'accueil Perl : <htmlurl url ="http://www.perl.com/perl/index.html"> </itemize> <sect1> Qu'est-ce que DBI ??? <p> L'interface de SGBD Perl (Perl Database Interface - DBI) est une interface logicielle d'accès à un SGBD (Application Programming Interface - API) pour le langage PERL. Les spécifications de l'API DBI perl définissent un ensemble de fonctions, de variables et de conventions d'accès à un SGDB cohérent et indépendant du SGBD utilisé. <sect1> Annonce du pilote DBI DBD-Pg-0.63 DBI pour PostgreSQL <p> Sur le site CPAN on trouve DBD-Pg-0.63.tar.gz. Depuis sortie de la dernière version publique, les modifications suivantes ont été effectuées : - - adaptation à PostgreSQL-6.2 : o &dollar sth->rows de même que &dollar sth->execute et &dollar sth->do renvoient le nombre de lignes affectées même pour les instructions non-Select. o ajout du support d'autorisation par mot de passe, lire la page du manuel concernant pg_passwd. - - the data_source parameter of the connect method accepts two additional parameters which are treated as host and port: DBI->connect("dbi:Pg:dbname:host:port", "uid", "pwd") - - support de l'instruction AutoCommit. Lire la documentation de ce module pour évaluer son impact sur vos scripts ! - - prise en compte dans un meilleur style perl du type de donnée bool, Lire la documentation de ce module pour évaluer son impact sur vos scripts ! Pour de plus amples informations voir: <htmlurl url="http://www.perl.com/CPAN"> <htmlurl url="http://www.postgresql.org"> <htmlurl url="http://www.hermetica.com/technologia/DBI"> <sect1> Notes concernant cette version et fichier LISEZ-MOI <p> <tscreen><verb> #--------------------------------------------------------- # # $Id: README,v 1.10 1997/10/05 18:25:55 mergl Exp $ # # Portions Copyright (c) 1994,1995,1996,1997 Tim Bunce # Portions Copyright (c) 1997 Edmund Mergl # #--------------------------------------------------------- ********************************************************** * * * Cette version contient des modifications * * INCOMPATIBLES * * _------------ * * avec les versions précédentes. * * * * Lire la documentation du module * * pour l'attribut AutoCommit * * et le type de donnée bool. * * * ********************************************************** </verb></tscreen> DESCRIPTION : ------------ Ceci est la version 0.63 de DBD-Pg. DBD-Pg est une interface PostgreSQL pour Perl 5 utilisant DBI. Pour des informations complémentaires concernant DBI consulter: <htmlurl url="http://www.fugue.com/dbi/"> COPYRIGHT : ----------- La distribution de ce document est soumise aux conditions de la licence publique générale GNU ou la licence protégeant la création Artistique (Artistic License), ainsi que c'est spécifié dans le fichier LISEZ-MOI perl. SI VOUS AVEZ DES PROBLEMES : --------------------------- Envoyez vos commentaires et vos rapports d'erreur à <htmlurl url="mailto:E.Mergl@bawue.de" name="E.Mergl@bawue.de"> Pensez à inclure les messages affichés par perl -v, et perl -V, la version de PostgreSQL, la version de DBD-Pg, et la version de DBI dans votre rapport d'erreur. CONTRAINTES LOGICIELLES : ------------------------ - compiler, tester et installer Perl 5 (au moins 5.002) - compiler, tester et installer le module DBI (au moins 0.89) - compiler, tester et installer PostgreSQL (au moins 6.2) PLATEFORMES : ------------- Cette version def DBD-Pg a été développée pour Linux 2.0 avec chargement dynamique des extensions perl. Merci de me faire savoir si vous rencontrez des problèmes sur d'autres plates-formes. INSTALLATION : -------------- Dans le fichier Makefile il y a un test la variable d'environnement POSTGRES_HOME ainsi que de quelques arborescences standard, pour trouver le répertoire racine de votre installation Postgres. Taper les commandes suivantes: 1. perl Makefile.PL 2. make 3. make test 4. make install ( de 1. à 3. comme utilisateur normal, pas comme root ! ) TEST : ------ Lancer 'make test'. Noter que l'utilisateur lançant ce script doit avoir été créé avec des droits d'accès lui permettant de créer des bases de données "ET" des utilisateurs !. Ne pas lancer ce script en tant que root!. Si le test échoue avec le message 'login failed', vérifier que l'accès à template1 de la base de données ainsi qu'à pgperltest ne sont pas protégés dans pg_hba.conf. Si vous utilisez la bibliothèque partagée libpq.so vérifiez que votre chargeur dynamique trouve libpq.so. La commande Linux /sbin/ldconfig -v devrait vous renseigner sur l'endroit où se trouve libpq.so. Si ldconfig ne trouve pas libpq.so, soit ajoutez une entrée appropriée dans /etc/ld.so.conf et relancez ldconfig ou ajouter son chemin dans la variable d'environnement LD_LIBRARY_PATH. On aura comme message typique résultant de ce type d'erreur : install_driver(Pg) failed: Can't load './blib/arch/auto/DBD/Pg/Pg.so' for module DBD::Pg: File not found at Quelques distributions Linux ont une installation incomplète de perl. Si vous avez des erreurs de compilation du style "XS_VERSION_BOOTCHECK undeclared", exécutez un 'find .../lib/perl5 -name XSUB.h -print' Si ce fichier n'est pas présent, il est indispensable de recompiler et de réinstaller perl. Utilisateurs SGI : si vous avez un défaut de segmentation, assurez-vous que vous utilisez la version de malloc obtenue avec perl lors de la compilation de perl (ce n'est pas le cas par défaut). "David R. Noble" drnoble@engsci.sandia.gov <htmlurl url="mailto:drnoble@engsci.sandia.gov" name="drnoble@engsci.sandia.gov"> --------------------------------------------------------------------------- <htmlurl url="mailto:E.Mergl@bawue.de" name="E.Mergl@bawue.de"> October 05, 1997 --------------------------------------------------------------------------- <sect1> FAQ pour DBI <p> On trouvera ci-dessous les Questions Fréquemment Posées (FAQ) pour DBI. La page Web d'accueil se trouve à <url url="http://www.hermetica.com/technologia/perl/DBI"> <tscreen><verb> DBI Foire Aux Questions v.0.35 Dernière mise à jour : 20 Juin, 1997 * NAME * SYNOPSIS * VERSION * DESCRIPTION * Information & Sources d'Informations * 1.1 Qu'est-ce que DBI, DBperl, Oraperl and *perl? * 1.2. Où puis-je les trouver? * 1.3. Où puis-je trouver plus d'informations? * Problèmes de compilation * 2.1. Problèmes de compilation ou "échec aux tests!" * Questions de Plates-formes et de Pilotes * 3.1 Quelle est la différence entre ODBC et DBI? * 3.2 DBI est-il supporté sur les plates-formes Windows 95 / NT ? * 3.3 Puis-je accéder à des bases de données Microsoft Access ou SQL-Server avec DBI? * 3.4 Y-a-t'il un DBD pour X? * 3.5 Qu'est-ce que DBM? Et pourquoi dois-je utiliser DBI à sa place? * 3.6 Quand mSQL-2 sera t'il supporté? * 3.7 Quel système de gestion de base de données me recommandez vous? * 3.8 Est-ce que X est supporté dans DBI? * Questions de programmation * 4.1 Est-ce que DBI est d'une quelconque utilité pour la programmation CGI? * 4.2 Comment puis-je obtenir des temps de connexion plus rapides avec DBD::Oracle et CGI? * 4.3 Comment puis-je obtenir des connexions persistantes avec DBI et CGI? * 4.4 ``Quand je lance un script perl à partir de la ligne de commande, çà marche, mais, quand je le lance à partir de C, çà échoue!" Pourquoi? * 5.1 Puis-je faire de l'exécution en parallèle avec DBI? * 5.2 Comment manipuler des données BLOB avec DBI? * 5.3 Comment puis-je invoquer des procédures enregistrées avec DBI? * 5.4 Comment puis-je récupérer les valeurs de retour des procédures enregistrées avec DBI? * 5.5 Comment puis-je créer ou détruire une base de données avec DBI? * 5.6 Comment puis-je enregistrer ou annuler une instruction avec DBI? * 5.7 Comment les valeurs NULL sont-elles prises en compte par DBI? * 5.8 Qu'est-ce que c'est que ces histoires de méthodes func? * Support et formation * Assistance Commerciale * Formation * Autres Références * AUTEUR * COPYRIGHT ---------------------------------------------------------------------------- NAME DBI::FAQ -- Foire Aux Questions pour l'interface de SGBD Perl5 ---------------------------------------------------------------------------- SYNOPSIS perldoc DBI::FAQ ---------------------------------------------------------------------------- VERSION La version actuelle de ce document , du 20 Juin, 1997, porte le numéro 0.35. ---------------------------------------------------------------------------- DESCRIPTION Ce document contient les réponses aux questions les plus fréquemment posées à la fois sur les Mailing Lists DBI et personnellement aux membres de l'équipe de développement DBI. ---------------------------------------------------------------------------- Information de base & Sources d'Information ---------------------------------------------------------------------------- 1.1 Qu'est-ce que c'est que DBI, DBperl, Oraperl and *perl? Pour citer Tim Bunce, l'architecte et l'auteur de DBI : ``DBI est une interface logicielle d'accès aux bases de données (Application Programming Interface -API) pour le langage Perl. Les spécifications DBI API définissent un ensemble de fonctions, de variables et de conventions cohérents d'interfaçage à une base de données indépendant de la base de données utilisée.'' En langage simple, l'interface DBI permet aux utilisateurs d'accéder de manière transparente à de multiples base de données. Ainsi, Si vous vous connectez à une base de données Oracle, Informix, mSQL, Sybase ou n'importe quelle autre, vous n'avez pas besoin de connaître les mécanismes sous-jacents de la couche 3GL. L'API définie par DBI fonctionnera sur tous ces types de bases de données. On obtient un bénéfice du même ordre en ayant la possibilité de se connecter à deux bases de données de différents fournisseurs à l'aide du même script perl, i.e., je veux lire des données d'une base de données Oracle et les insérer dans une Informix à partir du même programme. La couche logicielle DBI permet de le réaliser simplement et efficacement. Voici un diagramme décrivant ce principe : [ Architecture DBI ] DBperl est le nom ancien des spécifications de l'interface. Il est utilisé maintenant pour désigner les modules perl4 d'interfaçage des bases de données tels que oraperl, isqlperl, ingperl et autres. Ces interfaces n'ont pas d'API standard et ne sont généralement pas supportés. Voici une liste des modules DBperl, de leur équivalent DBI correspondants et du support d'information. Notez que les auteurs cités ici ne maintiennent généralement pas le module DBI de la base de données. Les adresses E-mail n'ont pas été vérifiées et ne doivent être utilisées que pour les questions concernant les modules perl4 listés ci-dessous. Les questions sur les pilotes DBI doivent être directement adressées aux listes de diffusion des utilisateurs DBI. Module Name SGBD requis Auteur DBI ----------- ----------------- ------ --- Sybperl Sybase Michael Peppler DBD::Sybase <mpeppler@itf.ch> Oraperl Oracle 6 & 7 Kevin Stock DBD::Oracle <dbi-users@fugue.com> Ingperl Ingres Tim Bunce & DBD::Ingres Ted Lemon <dbi-users@fugue.com> Interperl Interbase Buzz Moschetti DBD::Interbase <buzz@bear.com> Uniperl Unify 5.0 Rick Wargo None <rickers@coe.drexel.edu> Pgperl Postgres Igor Metz DBD::Pg <metz@iam.unibe.ch> Btreeperl NDBM John Conover SDBM? <john@johncon.com> Ctreeperl C-Tree John Conover None <john@johncon.com> Cisamperl Informix C-ISAM Mathias Koerber None <mathias@unicorn.swi.com.sg> Duaperl X.500 Directory Eric Douglas None User Agent Cependant, certains modules DBI possèdent des couches logicielles d'émulation. Ainsi DBD::Oracle est livré avec une couche d'émulation Oraperl, ce qui permet d'exécuter d'anciens scripts oraperl sans modification. La couche logicielle d'émulation traduit les appels oraperl API en appels DBI et les exécute. Voici une table des couches d'émulation : Module Couche d'émulation Etat ------ --------------- ------ DBD::Oracle Oraperl Complète DBD::Informix Isqlperl En cours de développement DBD::Sybase Sybperl Fonctionnelle? ( Nécessite une vérification) DBD::mSQL Msqlperl En version expérimentale avec DBD::mSQL-0.61 L'émulation Msqlperl est un cas particulier. Msqlperl est un pilote perl5 pour les bases de données mSQL , mais il ne se conforme pas aux spécifications DBI. On désapprouve son utilisation en faveur de DBD::mSQL. On peut télécharger Msqlperl à partir du site CPAN via : http://www.perl.com/cgi-bin/cpan_mod?module=Msqlperl ---------------------------------------------------------------------------- 1.2. Où puis-je le trouver? DBI est disponible en premier sur : ftp://ftp.demon.co.uk/pub/perl/db Il faut utiliser le site CPAN (Comprehensive Perl Archive Network) pour récupérer les versions à jour des pilotes, en général absentes des sites miroirs. On peut accéder à CPAN grâce au splendide programme "CPAN multiplexeur" de Tom Christiansen's situé à: http://www.perl.com/CPAN/ Pour des informations plus spécifiques ainsi que pour les URL exactes des pilotes, veuillez consulter la liste des pilotes DBI et les pages concernant les modules sur: http://www.hermetica.com/technologia/perl/DBI ---------------------------------------------------------------------------- 1.3. Où puis-je trouver plus d'informations? Il existe quelques sources d'information sur DBI. Spécifications DBI http://www.hermetica.com/technologia/perl/DBI/doc/dbispec On trouve deux spécifications disponibles à cette adresse: la nouvelle spécification Draft (édition provisoire) DBI qui est un document en évolution rapide à mesure que l'équipe de développement s'approche d'une version stable de l'interface, et l'ancienne spécification historique DBperl à partir de laquelle l'interface DBI actuelle a évolué. Il faut considérer ce dernier document comme ne présentant qu'un intérêt historique et ne pas l'utiliser en tant que manuel de programmation ou document de référence. Il demeure cependant une source d'informations très utile. Documentation POD (Plain Old Documentation) Les PODs sont des morceaux de documentation généralement noyés à l'intérieur des programmes perl qui documentent le code "sur place". Ce sont des ressources très utiles pour les programmeurs et les utilisateurs des modules. Les PODs pour DBI et pour les pilotes deviennent monnaie courante et la documentation pour les modules contenant ces PODs peut être lue avec les commandes suivantes. La Spécification DBI Les PODs pour la spécification DBI peut être lue avec la commande : perldoc DBI Oraperl Les utilisateurs de la couche d'émulation fournie avec DBD::Oracle, peuvent s'informer sur la manière de programmer en utilisant l'interface Oraperl en tapant: perldoc Oraperl Ce qui permettra d'obtenir une copie à jour de la page de manuel originale écrite par Kevin Stock pour perl4. L'API oraperl y est entièrement listée et décrite. DBD::mSQL Les utilisateurs du module DBD::mSQL peuvent lire des informations sur quelques fonctions privées et bizarreries de ce pilote en tapant : perldoc DBD::mSQL Foire Aux Questions (FAQ) Ce document, la Foire Aux Questions, est aussi disponible en tant que documentation POD! Vous pouvez le lire sur votre propre système en tapant : perldoc DBI::FAQ Ceci peut être plus pratique pour ceux qui ne sont pas connectés à l'Internet ou le sont d'une manière peu pratique. Les POD en général On peut lire des informations sur la manière d'écrire des PODs, ainsi que sur la philosophie des PODs en général en tapant : perldoc perlpod Les utilisateurs ayant le module Tk installé seront peut-être intéressés d'apprendre qu'il existe un lecteur de POD basé sur Tk nommé tkpod. Il formate les POD de manière pratique et lisible. Discussions, Cancans et Observations http://www.hermetica.com/technologia/perl/DBI/tidbits Il y a , de temps en temps, une série de discussions de la part de certaines personnes, dans les listes de diffusion sur DBI, qui, pour essayer d'éclaircir un simple point, finissent par transformer en brouillon des documents tout à fait complets. Ces documents sont souvent de qualité variable, mais donnent un aperçu du fonctionnement des interfaces. ``DBI -- L'interface de SGBD en perl5'' C'est un article écrit par Alligator Descartes et Tim Bunce sur la structure de DBI. Il a été publié dans le numéro 5 de ``The Perl Journal''. Il est extrêmement bon. Allez acheter ce magazine. En fait, achetez les tous! Le site WWW de ``The Perl Journal'' est : http://www.tpj.com ``DBperl'' Cet article, publié dans l'édition de novembre 1996 du ``Dr. Dobbs Journal'' traitait de DBperl. L'auteur de cet article n'a apparemment pas contacté un seul membre de l'équipe de développement DBI pour vérifier l'information contenue dans son article. Plusieurs critiques de cet article dans les listes de diffusion des utilisateurs de dbi ont été peu flatteuses, c'est le moins que l'on puisse dire. Le fait que l'article traite de DBperl au lieu de DBI est un indice du manque de fraîcheur de l'information. Cependant, cette référence est donnée par soucis d'exhaustivité. ``The Perl5 Database Interface'' Cette référence est celle d'un livre à écrire par Alligator Descartes (pour lui, c'est moi) publié par O'Reilly et Associés à paraître cet hiver. La table des matières de ce livre devrait contenir : * Introduction + Les Bases de Données + CGI / WWW + perl * Concepts de Base des Bases de données + Types de Bases de Données o Flat File o AnyDBM o RDBMS + Utiliser Quelle Base de Données, pour Quoi faire... * SQL + Pourquoi SQL? + Structuration de l'Information dans les Bases de Données + Extraction des Données d'une Base de Données + Manipulation des Données et des Structures de Données * Architecture DBI * Programmation avec DBI + Initialisation DBI + Identifiants o Identifiants de pilotes o Identifiants de bases de données o Identifiants d'instructions + Connexion and Déconnexion + Gestion des Erreurs + Emission de Requêtes Simples + Exécution d'Instructions Atomiques + Instructions MetaDonnées + Instruction plus dans le style perl + Liaison + Gestion des Transactions + Méthodes utilitaires + Gestion des Attributs et des Variables Dynamiques * DBI et ODBC * Les Pilotes de Bases de Données + DBD::Oracle et oraperl + DBD::Informix et isqlperl + DBD::mSQL et Msqlperl * Etude de Cas + DBI et le WWW + Migration des Données et Stockage + Logiciel d'Administration * Appendice: API Référence / Spécification * Appendice: Ressources Fichiers LISEZMOI Les fichiers LISEZMOI fournis avec chaque pilote contiennent de temps en temps quelques informations utiles (non, vraiment! ) pouvant être pertinentes pour l'utilisateur. S'il vous plaît, lisez-les. Cela rendra nos pauvres existences plus supportables. On peut toutes les trouver depuis la page WWW DBI principale à : http://www.hermetica.com/technologia/perl/DBI Listes de diffusion Il y a trois listes de diffusion pour DBI gérées par Ted Lemon. On peut s'inscrire à toutes et résilier cette inscription à travers le World Wide Web à l'URL : http://www.fugue.com/dbi Les listes où les utilisateurs peuvent participer sont: dbi-announce Cette liste de diffusion est réservée uniquement aux annonces. Très peu de trafic. Les annonces sont généralement postées sur la page WWW DBI principale. Si vous n'arrivez pas à utiliser le formulaire sur la page WWW indiquée ci-dessus, inscrivez-vous à cette liste de la manière suivante : Email: 'dbi-announce-request@fugue.com' avec le mot 'subscribe' dans le corps du message. dbi-dev Cette liste de diffusion est à l'usage des développeurs pour discuter des idées et des concepts de l'interface DBI, API et des mécanismes des pilotes. Seulement utiles pour les développeurs et les personnes intéressées. Trafic faible. Si vous n'arrivez pas à utiliser le formulaire sur la page WWW indiquée ci-dessus, inscrivez-vous à cette liste de la manière suivante : Email: 'dbi-dev-request@fugue.com' with a message body of 'subscribe' dbi-users Cette liste de diffusion est un lieu de discussion générale utilisée pour les rapports d'erreurs, la discussion sur différents problèmes et des demandes de renseignement d'intérêt général. Trafic moyen. Si vous n'arrivez pas à utiliser le formulaire sur la page WWW indiquée ci-dessus, inscrivez-vous à cette liste de la manière suivante : Email: 'dbi-users-request@fugue.com' with a message body of 'subscribe' Archives des Listes de Diffusion Archives des Listes de Diffusion US http://outside.organic.com/mail-archives/dbi-users/ Cette archive, avec recherches par hyper-liens, de ces trois listes de diffusion, avec un peu du trafic beaucoup plus ancien a été mis en place pour permettre une recherche par les utilisateurs. Archives des Listes de Diffusion Européennes http://www.rosat.mpe-garching.mpg.de/mailing-lists/PerlDB-Interest Identique à l'archive US ci-dessus. ---------------------------------------------------------------------------- Problèmes de compilation ---------------------------------------------------------------------------- 2.1. Problèmes de compilation ou "Il échoue aux tests!" En premier lieu, consulter la documentation en ligne concernant ce module, que ce soit DBI lui-même ou un module DBD, et vérifier que ce n'est pas un problème de compilation connu pour votre architecture. On peut trouver ces documents à : http://www.hermetica.com/technologia/perl/DBI Si c'est un problème connu, vous devrez probablement attendre qu'il ait été corrigé. Si vraiment vous avez besoin d'une solution, essayez l'une des solutions suivantes : Essayez de le corriger vous même Cette technique n'est généralement par recommandée aux craintifs. Si vous pensez que vous y êtes arrivé, alors, envoyer un fichier patch (context diff ) à l'auteur en expliquant les points suivants : o Quel était le problème, et, si possible, des jeux d'essai. o Ce que vous avez dû faire pour le corriger. Assurez vous que vous n'oubliez rien. o Donnez des informations concernant la Plate-forme utilisée, les versions : de la Base de Données, de Perl, du module et de DBI. Envoyez un Email à l'auteur SANS RALER! S'il vous plaît, postez votre email à l'adresse indiquée dans les pages WWW du pilote avec lequel vous avez rencontré des problèmes. Ne pas poster directement à une adresse que vous connaissez à moins qu'elle ne corresponde à l'une de celles qui sont indiquées. Nous avons un vrai travail à faire, et nous devons consulter les listes de diffusion traitant des problèmes rencontrés. De plus nous ne pouvons pas forcément avoir accès à <insérez ici le nom de votre plate-forme favorite, celle qui vous cause des lésions cérébrales> et de ce fait vous apporter une quelconque assistance! Désolé de vous paraître dur, mais c'est comme cela! Cependant, vous pouvez tomber sur l'un de ces génies créatifs, qui, à 3 heures du matin résoudra votre problème et vous fournira une rustine en 5 minutes. L'ambiance dans le cercle DBI est que nous apprécions de connaître les problèmes des utilisateurs puisque nous travaillons dans le même environnement. Si vous envisagez d'envoyer un Email à un auteur, essayez de fournir le plus d'informations possible, i.e. : o TOUS les renseignements provenant du fichier LISEZMOI du module posant problème. Je dis bien TOUS. Nous n'ajoutons pas de lignes dans la documentation pour le plaisir, ou pour que les fichiers LISEZMOI se conforment à une quelconque norme de taille. o Si vous disposez d'un vidage mémoire, essayer de générer une trace du contenu de la pile (stack) à partir du vidage mémoire (core dump) en utilisant le module Devel::CoreStack. L'envoyer également. On peut trouver le module Devel::CoreStack sur CPAN à : http://www.perl.com/cgi-bin/cpan_mod?module=Devel::CoreStack o Les numéros de version du Module, de perl, des jeux d'essai, du système d'exploitation ainsi que tout autre information pertinente. Souvenez-vous que, plus vous nous enverrez d'informations plus vite nous pourrons résoudre le problème. Si vous n'envoyez rien, n'attendez rien en retour. Envoyez un Email dans la liste de diffusion des utilisateurs de dbi C'est en général une idée astucieuse de rapporter les problèmes rencontrés dans les listes de diffusion. Les auteurs lisent tous ces listes d'une part et d'autre part vous ne perdez rien à le faire, donc, faites-le. ---------------------------------------------------------------------------- Questions de Plates-formes et de Pilotes ---------------------------------------------------------------------------- 3.1 Quelle est la différence entre ODBC et DBI? Çà, c'est une bonne question! Réponse à rédiger de manière détaillée! ---------------------------------------------------------------------------- 3.2 DBI est-il supporté sur les plates-formes Windows 95 / NT ? Finalement, oui! Jeff Urlwin s'est employé avec constance à porter DBI et DBD::Oracle sur ces plates-formes, et, depuis la disponibilité d'un perl plus stable et d'un portage de MakeMaker, le projet a progressé à pas de géant. Les portages de DBI et de DBD::Oracle pour Win32 ports font maintenant partie intégrante de DBI, donc, la récupération d'une version de DBI supérieure à 0.81 doit donner satisfaction. Pour ce qui est des rustines nécessaires pour DBD::Oracle, veuillez lire la page d'information de portage pour Win32 à : http://www.hermetica.com/technologia/perl/DBI/win32 ---------------------------------------------------------------------------- 3.3 Puis-je accéder aux bases de données Microsoft Access ou SQL-Server avec DBI? Contribution de Tim Bunce et Jeff Urlwin Il existe une couche logicielle d'émulation expérimentale pour le module Win32::ODBC fournie avec DBI-0.79 ( et suivants ). Elle s'appelle DBI::W32ODBC et est, pour le moment, minimale. Vous aurez besoin du module Win32::ODBC disponible à : http://www.roth.net Etant donné son état, les rapports de problèmes, sans correction, ont de bonnes chances d'être ignorés. Vous aurez également besoin du patch kit Win32 DBI tel qu'il est fourni par Jeff Urlwin. Pour trouver l'endroit où il est disponible, lire la réponse à la question précédente. Jeff Urlwin fournit actuellement un gros travail sur la couche logicielle ODBC. Pour en revenir à la question initiale, théoriquement, oui, on peut accéder aux bases de données Microsoft Access ou SQL-Server avec DBI via ODBC! ---------------------------------------------------------------------------- 3.4 Existe-t-il in DBD pour <insérez le nom de votre SGBD favori ici>? Est-il cité dans la liste des pilotes DBI ? http://www.hermetica.com/technologia/perl/DBI/DBD Sinon, non. L'absence complète d'un pilote pour un SGBD donné dans cette page signifie que personne n'a manifesté l'intention d'y travailler. Comme corollaire à l'affirmation ci-dessus, cela signifie que si vous voyez une annonce pour un pilote qui n'est pas dans cette page, il y a une bonne chance que ce soit réellement un pilote DBI, et qu'il puisse ne pas respecter les spécifications. Par conséquent, les questions pour des problèmes concernant ce code ne doivent pas être posées dans les listes de diffusion DBI. ---------------------------------------------------------------------------- 3.5 Qu'est-ce que DBM? Et pourquoi dois-je utiliser DBI à sa place? Extrait de ``DBI - L'Interface de Base de Données pour Perl 5'' : ``A l'origine UNIX était bienheureux avec sa "Base de Données" rustique reposant sur des fichiers, nommée système dbm. Avec dbm vous enregistrez les données dans des fichiers et les retrouvez rapidement. Cependant, il souffre de sérieux inconvénients. Verrouillage des fichiers Les systèmes dbm ne permettent par un verrouillage particulièrement robuste des fichiers, de même qu'il n'y a pas de possibilité de corriger les problèmes survenants lors d'écritures [ dans la base de données ] simultanées. Structures de Données Arbitraires Les systèmes dbm permettent seulement une simple structure de données fixe: paires clé-valeur. Cette valeur peut être un objet complexe, tel qu'une structure [ C ], mais la clé doit être unique. Ce fut une grande limitation dans l'utilité des systèmes dbm. Cependant, les systèmes dbm continuent à offrir des fonctions utiles pour les utilisateurs ayant des ensembles de données simples et des ressources limitées, puisqu'ils sont rapides, robustes et extrêmement bien testés. Les modules Perl pour accéder aux systèmes dbm font maintenant partie intégrante de la distribution Perl via le module AnyDBM_File.'' Pour résumer, DBM est une solution parfaitement satisfaisante pour les bases de données essentiellement en lecture seule, ou pour des ensembles de données simples et réduits. Toutefois, pour des ensembles de données plus importants, sans mentionner un verrouillage des transactions robuste, on recommandera aux utilisateurs de préférer DBI. ---------------------------------------------------------------------------- 3.6 Quand mSQL-2 sera t'il supporté? De même que pour DBD::mSQL-0.61, il y a eu un support pour mSQL-2. Cependant, il n'y a encore aucun réel support pour les nouvelles méthodes func, concernant les index, ajoutées à la bibliothèque de base mSQL. Celles-ci seront prochainement disponibles et seront accessibles à DBD::mSQL au travers de méthodes func privées. Vous pouvez obtenir plus d'informations concernant ces méthodes func privées dans le POD DBD::mSQL en tapant : perldoc DBD::mSQL à condition d'avoir une installation correcte de DBD::mSQL. ---------------------------------------------------------------------------- 3.7 Quel système de gestion de base de données me recommandez vous? C'est un sujet particulièrement épineux pour lequel une réponse objective est délicate dans la mesure où, chaque ensemble de données, chaque usage et chaque configuration du système est différent d'un utilisateur à l'autre. Du point de vue de l'auteur, si l'ensemble de données est relativement petit, donnant des tables de moins de 1 million de lignes, et qu'il y ait moins de 1000 tables dans une base de données, alors mSQL est une solution parfaitement acceptable. Ce SGBD est extrêmement bon marché, est merveilleusement robuste et bénéficie d'un excellent support. Des informations complémentaires sont disponibles sur le site WWW Hughes Technology à : http://www.hughes.com.au Si l'ensemble de données entraîne des tables de plus de 1 million de lignes ou plus de 1000 tables, ou si vous disposez de, soit plus d'argent, soit de machines plus puissantes, je vous recommanderai le RDBMS (SGBDR en français) Oracle7. Le site WWW Oracle's est une excellente source d'information complémentaire. http://www.oracle.com Informix est un autre RDBMS de haut niveau qu'il faut envisager. Il existe plusieurs différences entre Oracle et Informix qui sont trop complexes pour être détaillées dans ce document. On trouvera l'information sur Informix sur leur site WWW à : http://www.informix.com En cas d'utilisation dans des applications en frontal WWW, mSQL peut être un meilleur choix du fait de ses temps de connexion courts entre le script CGI et le SGBD que Oracle RDBMS qui, à chaque connexion, réclame plus de ressources. mSQL est moins gourmand en ressources et plus rapide. Ce point de vue n'est pas forcément partagé par tout le monde et n'est pas sponsorisé ou dicté par une quelconque société. Il est donné tel quel. ---------------------------------------------------------------------------- 3.8 Est-ce que <insérez une fonctionnalité ici> est supporté par DBI? Si l'on suppose que la fonctionnalité en question n'est pas, en standard, spécifique d'un SGBD, alors la réponse sera non. DBI représente un API qui doit fonctionner avec la plupart des SGBD, et n'a pas de fonctionnalité spécifique à un SGDB particulier. Cependant, les auteurs d'un pilote peuvent, s'ils le désirent, ajouter une fonctionnalité spécifique à un SGBD à travers les méthodes func définies dans l'API DBI. Les développeurs de Scripts doivent noter que l'utilisation de cette fonctionnalité au travers de ces méthodes func a de bonnes chances d'en sacrifier la portabilité entre les différents SGDB. ---------------------------------------------------------------------------- Questions de Programmation ---------------------------------------------------------------------------- 4.1 Est-ce que DBI est d'une quelconque utilité pour la programmation CGI? En un mot, oui! DBI est extrêmement utile pour la programmation CGI! En fait, je serais tenté de répondre que la programmation CGI est une des deux principales utilisation de DBI. DBI confère aux programmeurs CGI la possibilité d'offrir des base de données WWW à leurs utilisateurs, ce qui donne à ces utilisateurs la possibilité d'utiliser de grandes quantités de données bien organisées. DBI donne aussi la possibilité , si un site reçoit un trafic trop important pour les performances du serveur, d'améliorer ce serveur de base de données de façon transparente, sans modifier les scripts CGI. ---------------------------------------------------------------------------- 4.2 Comment puis-je obtenir un temps de connexion plus rapide avec DBD::Oracle et CGI CGI? Contribution de John D. Groenveld Le serveur httpd Apache maintient un ensemble de processus fils httpd pour servir les requêtes clients. En utilisant le module mod_perl Apache de Doug MacEachern, l'interpréteur perl est inclus dans le processus fils httpd. Les modules CGI, DBI, et vos autres modules favoris peuvent être chargés au lancement de chaque processus fils. Ces modules ne seront pas rechargés à moins d'être modifiés sur disque. Pour de plus amples informations sur Apache, consultez le site WWW du Projet Apache à : http://www.apache.org Le module mod_perl peut être récupéré de CPAN via : http://www.perl.com/cgi-bin/cpan_mod?module=mod_perl ---------------------------------------------------------------------------- 4.3 Comment puis-je obtenir une connexion persistante avec DBI et CGI? Contribution de by John D. Groenveld En utilisant le module Apache::DBI de Edmund Mergl, les connexions à la base de données sont enregistrées dans une table avec chacun des processus httpd fils. Si votre application utilise une base de données simple utilisateur, cette connexion peut être lancée avec chaque processus fils. Actuellement, les connexions à la base de données ne peuvent pas être partagées entre processus httpd fils. Apache::DBI peut être téléchargé de CPAN via : http://www.perl.com/cgi-bin/cpan_mod?module=Apache::DBI ---------------------------------------------------------------------------- 4.4 ``Quand je lance un script perl de la ligne de commande, çà marche, mais, quand je le lance sous httpd, çà échoue!" Pourquoi? Fondamentalement, il y a une bonne chance que cela provienne du fait que l'utilisateur à partir duquel vous avez lancé la ligne de commande a un ensemble de variables d'environnement correctement configuré, ce sont, dans la cas de DBD::Oracle, des variables telles que $ORACLE_HOME, $ORACLE_SID or TWO_TASK. Le processus httpd s'exécute habituellement sous un utilisateur id ne correspondant pas à un utilisateur, ce qui implique qu'il n'y a pas d'environnement configuré. Tous scripts essayant de s'exécuter dans ces circonstances échoueront. Pour résoudre ce problème, initialisez l'environnement de votre base de données dans un bloc BEGIN ( ) en tête de votre script. Ceci devrait résoudre votre problème. De même, vous devriez regarder votre fichier registre d'erreurs pour y trouver des indices, ainsi que les guides ``Idiot's Guide To Solving Perl / CGI Problems'' et ``Perl CGIProgramming FAQ'' pour avoir des informations complémentaires. Il est peu probable que ce problème concerne DBI. Le guide ``Idiot's Guide To Solving Perl / CGI Problems'' peut être trouvé à : http://www.perl.com/perl/faq/index.html ainsi que ``Perl CGI Programming FAQ''. Lisez ces DEUX documents très soigneusement! ---------------------------------------------------------------------------- 5.1 Puis-je faire de l'exécution en parallèle avec DBI? A la date de ce document ( voir en tête ), non. perl ne permet pas l'exécution en parallèle. Cependant, l'exécution en parallèle doit faire partie de la distribution perl de base à compter de la version 5.005, ce qui sous-entend que le support de l'exécution en parallèle pour DBI devrait suivre rapidement. Pour quelques exemples de code OCI pour Oracle ayant des instructions SELECT avec exécution en parallèle, voir : http://www.hermetica.com/technologia/oracle/oci/orathreads.tar.gz ---------------------------------------------------------------------------- 5.2 Comment manipuler des données BLOB avec DBI? A écrire. ---------------------------------------------------------------------------- 5.3 Comment puis-je invoquer des procédures enregistrées avec DBI? En supposant que vous avez créé une procédure enregistrée à l'intérieur de la base de données cible, eg, une base de données Oracle, vous pouvez utiliser $dbh->do pour exécuter immédiatement cette procédure. Par exemple, $dbh->do( "BEGIN someProcedure END" ); ---------------------------------------------------------------------------- 5.4 Comment puis-je récupérer les valeurs de retour de procédures enregistrées avec DBI? Contribution de Jeff Urlwin $sth = $dbh->prepare( "BEGIN foo(:1, :2, :3); END;" ); $sth->bind_param(1, $a); $sth->bind_param_inout(2, \$path, 2000); $sth->bind_param_inout(3, \$success, 2000); $sth->execute; N'oubliez pas d'effectuer un test d'erreur, strict! ---------------------------------------------------------------------------- 5.5 Comment puis-je créer ou supprimer une base de données avec DBI? La création et la suppression de bases de données sont des concepts qui sont beaucoup trop abstraits pour être supportés par DBI. Par exemple, Oracle ne supporte pas le concept de détruire une base de données du tout! Ainsi, dans Oracle, le serveur de base de données est essentiellement la base de données elle-même alors que dans mSQL, le processus serveur s'exécute tranquillement sans aucune base de données créée. C'est un problème trop hétérogène pour s'y attaquer. Quelques pilotes, cependant, supportent la création et la suppression de bases de données à travers des méthodes func privées. Il vous faut regarder dans la documentation des pilotes que vous utilisez pour vérifier s'ils supportent de tels mécanismes. ---------------------------------------------------------------------------- 5.6 Comment puis-je valider ou annuler une instruction avec DBI? A écrire. ---------------------------------------------------------------------------- 5.7 Comment les valeurs NULL sont-elles prises en compte par DBI? Les valeurs NULL dans DBI sont traitées comme la valeur undef. Des NULLs peuvent être insérés dans les bases de données en tant que NULL, par exemple : $rv = $dbh->do( "INSERT INTO table VALUES( NULL )" ); mais lors d'une interrogation, les NULLs devront être testés comme des undef. C'est un standard pour tous les pilotes. ---------------------------------------------------------------------------- 5.8 Qu'est-ce que c'est que ces histoires de méthodes func? Une méthode func est définie à l'intérieur de DBI comme étant un point d'entrée pour une fonctionnalité d'une base de données spécifique, eg, la possibilité de créer ou supprimer des bases de données. L'invocation de ces méthodes spécifiques aux pilotes est simple. Par exemple, pour invoquer une méthode createDatabase qui n'a qu'un seul argument, on écrira : $rv = $dbh->func( 'argument', 'createDatabase' ); Les développeurs de logiciels doivent cependant noter que ces méthodes func ne sont pas portables entre SGDB. ---------------------------------------------------------------------------- Assistance et formation L'interface aux SGBD Perl5 est un logiciel LIBRE. IL EST DISTRIBUE SANS GARANTIE D'AUCUNE SORTE. Cependant, quelques organisations fournissent soit une assistance technique soit des programmes de formation pour DBI. L'auteur de ce document n'a aucune information sur la qualité de ces services (le traducteur non plus!). Les liens ci-dessous ne sont indiqués qu'à titre de référence. ---------------------------------------------------------------------------- Assistance technique The Perl Clinic The Perl Clinic peut mettre en place des contrats commerciaux d'assistance pour Perl, DBI, DBD::Oracle et Oraperl. Cette assistance est effectuée par la compagnie pour laquelle Tim Bunce, auteur de DBI, travaille. Pour des informations complémentaires sur leurs services, veuillez voir : http://www.perl.co.uk/tpc ---------------------------------------------------------------------------- Formation Aucun programme de formation n'est connu à ce jour. ---------------------------------------------------------------------------- Autres Références Dans cette section, on trouvera des liens WWW divers pouvant présenter un intérêt pour les utilisateurs de DBI. Ils n'ont pas été vérifiés et peuvent mener à des sites inconnus ou à des documents inexistants. http://www-ccs.cs.umass.edu/db.html http://www.odmg.org/odmg93/updates_dbarry.html http://www.jcc.com/sql_stnd.html ---------------------------------------------------------------------------- AUTEUR Alligator Descartes <descarte@hermetica.com> ---------------------------------------------------------------------------- COPYRIGHT Ce document est Copyright (c)1994-1997 Alligator Descartes, avec des parties Copyright (c)1994-1997 leurs auteurs originaux. Ce module est publié selon les conditions d'une licence 'Artistique' que vous pouvez trouver dans la distribution de perl. Ce document est Copyright (c)1997 Alligator Descartes. Tous droits réservés. La permission de distribuer ce document, en entier ou en partie, via email, Usenet, archives ftp ou http est accordée à condition que ce soit gratuitement, on a fait un effort raisonnable pour utiliser les versions les plus actuelles et tous les avis d'attribution et de copyright ont été maintenus ( Se référer aux sections AUTEUR et COPYRIGHT ). Les demandes pour d'autres droits de distribution, y compris l'incorporation dans des produits commerciaux, tels que livres, articles de magazines ou CD-ROMs doit être effectuée auprès de Alligator Descartes <descarte@hermetica.com>. ---------------------------------------------------------------------------- (c) 1995-97 Hermetica Alligator Descartes - Hermetica </verb></tscreen> <sect> PGACCESS - Un GUI pour la gestion dePostgreSQL <p> Il est déjà inclus dans la distribution de PostgreSQL. Pour une copie plus récente, vous pouvez accéder au site web site <itemize> <item> <url url="http://www.flex.ro/pgaccess"> <item> Si vous avez des commentaires, des suggestions pour des améliorations, n'hésitez pas à envoyer un courrier électronique à : <htmlurl url="teo@flex.ro" name="teo@flex.ro"> </itemize> Voici ce que dit la page d'accueil de pgaccess : <tscreen><verb> PgAccess - une interface Tcl/Tk pour PostgreSQL La dernière version de PgAccess est 0.62 , du Samedi 25 Octobre 1997 Je pense qu'il y a eu quelques problèmes au chargement de la bibliothèque libpgtcl. Je vous invite à lire la section spéciale concernant libpgtcl Que fait PgAccess maintenant! Voici quelques images des fenêtres de PgAccess : Fenêtre principale, créateur de tables, vue de table (interrogation), créateur visuel d'interrogation . Tables - Ouverture de tables pour la visualisation, 200 enregistrements maximum ( modifiable dans le menu des préférences ) - redimensionnement d'une colonne en tirant la ligne verticale de la grille ( plus pratique à réaliser à l'intérieur même de la table que dans l'en-tête) - texte encadré dans les cellules - disposition enregistrée pour chacune des tables) - importation/exportation vers des fichiers externes (SDF,CSV) - possibilité de filtres (filtre de saisie, tel que (prix>3.14) - possibilités de tri (saisie manuelle de(s) champ(s) à trier) - édition en ligne - assistant générateur de table amélioré - édition de champ améliorée Requêtes - définition, édition et enregistrement de "requêtes définies par l'utilisateur" - enregistrement de requêtes en tant que vues - exécution des requêtes - visualisation des résultats de requêtes de type select - suppression et changement de nom de requête - NOUVEAU !!! Créateur visuel de requêtes avec possibilités de "glisser/déposer". Pour tous ceux d'entre vous qui ont l'extension pour Netscape Navigator de Tcl/Tk installée, vous pouvez le voir au travail en cliquant ici Séquences - définition de séquences, ainsi que leurs suppression et inspection Fonctions - définition, inspection et suppression de fonctions en langage SQL Sur la liste A FAIRE! - conception des tables (ajout de nouveaux champs, changement de nom, etc.) - définition de fonction - générateur de rapport - langage de script de base Informations complémentaires concernant libgtcl Vous aurez également besoin de la bibliothèque d'interface de PostgreSQL à Tcl, disponible comme moduleTcl/Tk chargeable. Son nom est libpgtcl et le source est situé dans le répertoire PostgreSQL /src/interfaces/libpgtcl. Précisément, vous aurez besoin d'une bibliothèque libpgtcl qui soit "chargeable" à partir de Tcl/Tk. Ce qui est techniquement différent d'un fichier objet chargeable PostgreSQL ordinaire, car libpgtcl est constituée d'un ensemble de fichiers objets. Sous Linux, on l'appelle libpgtcl.so. Vous pouvez télécharger à partir d'ici une version déjà compilée pour les systèmes Linux i386. La seule chose à faire est de copier libpgtcl.so dans le répertoire bibliothèque système (/usr/lib) et c'est tout. Une solution possible est de supprimer dans le source la ligne contenant load libpgtcl.so et de charger pgaccess.tcl non pas avec wish, mais avec pgwish (ou wishpg) le wish qui a été lié avec la bibliothèque libpgtcl! De toute manière, l'application devrait fonctionner sans problèmes </verb></tscreen> <sect>Outil Windows interactif de génération de requête pour PostgreSQL <p> ("Windows Interactive Query Tool" WISQL ou MPSQL) Il est identique au serveur de requête SQL de Microsoft WISQL! Il dispose d'un GUI agréable et d'un historique des commandes. Vous pouvez utiliser le coupé/collé ainsi que d'autres fonctionnalités sympathiques pour accroître votre productivité. <itemize> <item> <url url="http://www.troubador.com/~keidav/index.html"> <item> Email : <htmlurl url="mailto:keidav@whidbey.com" name="keidav@whidbey.com"> <item> <url url="http://www.ucolick.org/~de/"> in file tcl_syb/wisql.html <item> <url url="http://www.troubador.com/~keidav/index.html"> <item>Email : <htmlurl url="mailto:de@ucolick.org" name="de@ucolick.org"> </itemize> <sect>Outil interactif de génération de requête pour PostgreSQL - ISQL <p> ISQL est destiné aux terminaux fonctionnants en mode ligne de commande. C'est inclus dans la distribution et nommé PSQL. Il est très similaire à Sybase ISQL, et à Oracle SQLplus. A l'invite unix tapez la commande 'psql' qui en retour vous affichera le caractère d'attente de commande: psql> . Tapez /h pour obtenir de l'aide sur les commandes utilisables. C'est très convivial et d'utilisation facile. C'est aussi très utile pour écrire des scripts pour les interpréteurs de commandes Bourne, Korn et C-shells. <sect> Mise en place de plusieurs machines PostgreSQL avec un seul moniteur <p> Vous pouvez empiler plusieurs cpu et les connecter à un unique moniteur en utilisant un commutateur pour choisir la connexion avec une unité centrale particulière. Ce qui économise de l'espace et évite l'utilisation de plusieurs écrans(200 US dollars), claviers(60 dollars) et mulots(50 dollars) et évite aussi pas mal de pagaille. Veuillez consulter ces sites : <itemize> <item> <url url="http://www.networktechinc.com/servswt.html"> (120 dollars/PC 8 ports) qui propose 'Server Switches' and 'Video only switches' <item> <url url="http://www.scene.demon.co.uk/qswitch.htm"> <item> <url url="http://www.cybex.com/products/control/4xp.htm"> <item> <url url="http://www.betterbox.com/info.html"> </itemize> Utilisez le moteur de recherche yahoo pour trouver d'autres compagnies en utilisant la clé de recherche 'Server Switches'. On trouvera ci-dessous un extrait du catalogue de networktechnic Inc <tscreen><verb> Commandez maintenant, appelez le 800-742-8324 (appel gratuit à partir des USA) Pour recevoir notre catalogue, veuillez envoyer votre adresse par courrier électronique à : sales@networktechinc.com PILOTEZ PLUSIEURS PC's avec un seul clavier, écran et mulot Ces commutateurs électroniques permettent de piloter jusqu'à 64 PC's avec un unique clavier, écran et mulot. Son microprocesseur interne simule la présence constante du clavier, de l'écran et du mulot pour chacun des PC's connectés. Fonctionnalités et Applications * Clavier, face avant ou commande à distance * utilisation de connecteurs de mulots 9 broches D Serial ou 6 broches miniDIN * utilisation de connecteurs de clavier 5 broches DIN ou 6 broches miniDIN * résolution vidéo 1600x1200 sans dégradation * Utilisation de câbles standards * Boîtier pour bureau ou pour montage en rack Spécifications - Clavier * Tous les connecteurs dont femelles * 5 broches DIN ou 6 broches miniDIN * Permettent un redémarrage (boot) matériel ou logiciel de tous les PC's à chaque instant Contrôles - Boutons en face avant * Le toucher d'un bouton permet la connexion au PC correspondant * L'appui sur un bouton pendant plus de 0.5 secondes entraîne le fonctionnement dans les modes SCAN, BROADCAST ou COMMAND * Les LEDs en face avant indiquent le mode d'opération du clavier * L'appui sur CTRL+* entraîne le fonctionnement en mode COMMAND * Les modes SCAN, BROADCAST ou COMMAND sont disponibles Mulot * 9 broches D serie o Le commutateur NTI émule le mulot Microsoft série pour tous les PC's o 9 broches D mâle pour mulot o 9 broches D femelle pour PC's * 6 broches miniDIN o Le commutateur NTI émule le mulot IBM PS/2 pour tous les PC's o Tous les connecteurs sont femelles Par câble, à distance * Optionnel--doit être acquis séparément * Fonctionnement identique à celui "Boutons en face avant" Information technique * Demander le manuel technique MAN025 Moniteur (écran) - VGA * La bande passante est de 150 MHz * Résolution 1600X1200 sans dégradation * Tous les connecteurs sont des connecteurs femelles Alimentation * 110 ou 220 VAC à 50 ou 60 Hz </verb></tscreen> <sect> Outil Système de suivi de Problème/Projet pour PostgreSQL <p> Se trouve à l'url : <itemize> <item> <url url="http://www.homeport.org/~shevett/pts/"> </itemize> <sect> Conversion de fichiers dbase dbf en fichiers PostgreSQL <p> Le programme dbf2msql fonctionne parfaitement avec mSQL et PostgreSQL. Vous pouvez le trouver à <itemize> <item> <url url="ftp.nerosworld.com/pub/SQL/dbf2sql/"> <item> <url url="ftp://gopher.library.tudelft.nl/pub/misc/dbf2msql-0.4.tar.gz"> </itemize> Ce programme a été écrit par Maarten Boekhold, Faculty of Electrical Engineering TU Delft, NL Computer Architecture and Digital Technique section <htmlurl url="mailto: M.Boekhold@et.tudelft.nl" name="M.Boekhold@et.tudelft.nl"> Vous pouvez également utiliser une méthode python pour lire des fichiers dbf et les charger dans une base de données postgres. <itemize> <item> Voir <url url="http://www.python.org"> </itemize> <sect>PostgreSQL 4GL pour les applications de bases de données web - Le système de développement AppGEN <p> AppGEN peut être téléchargé de <url url="http://www.man.ac.uk/~whaley/ag/appgen.html"> <url url="ftp://ftp.mcc.ac.uk/pub/linux/ALPHA/AppGEN">. On trouvera ci-dessous un extrait de la page d'accueil de AppGEN :- AppGEN est un langage de haut niveau de la quatrième génération ainsi qu'un générateur d'application pour produire des applications destinées au World Wide Web (WWW). Ces applications sont typiquement utilisées à travers l'internet ou dans le cadre d'un réseau intranet d'entreprise. Les applications AppGEN sont implantées en scripts C respectants le standard Common Gateway Interface (CGI) utilisé par la plupart des serveurs Web. Pour utiliser AppGEN il vous faudra disposer de :- PostgresSQL, système de gestion de base de données relationnel Un serveur web compatible CGI tel que HTTPD du NCSA D'un compilateur ansi C tel que GCC AppGEN est constitué des exécutables Unix (Linux) suivants :- <itemize> <item> defgen, qui produit une application cadre, de base, à partir de la structure logique des données. Ces applications sont capables d'ajouter, de mettre à jour, de supprimer et de rechercher les enregistrements d'une base de données tout en conservant automatiquement l'intégrité référentielle de cette base. <item> appgen, le compilateur AppGEN qui compile le code source appgen en code source C CGI exécutable et en documents formatés HTML prêts pour leur déploiement sur un serveur web. <item> dbf2sql, un utilitaire de conversion de fichiers .dbf compatibles dBase III en scripts SQL exécutables. Ce qui permet de migrer les données stockées dans la plupart des bases de données DOS/Windows vers un serveur SQL tel que PostgresSQL. <item>De plus, AppGEN comprend un ensemble de documents HTML , de fichiers GIF et d'applets Java qui sont utilisés, à l'exécution, par le système. Et, naturellement, comme pour tout bon logiciel, la totalité du code source est fournie. </itemize> L'auteur, Andrew Whaley, peut être conctacté à <htmlurl url="mailto: andrew@arthur.smuht.nwest.nhs.uk" name="andrew@arthur.smuht.nwest.nhs.uk"> tous les commentaires ou suggestions concernant ce logiciel seront les bienvenus. <sect>Outil de Conception/Implémentation pour SGBD Web pour PostgreSQL - EARP <p> <url url="http://www.oswego.edu/Earp"> <url url="ftp://ftp.oswego.edu"> dans le répertoire 'pub/unix/earp'. On trouvera ci-dessous un extrait de la page d'accueil de EARP:- Le "Programme de Réponse Facilement Ajustable" ("Easily Adjustable Response Program" - EARP) créé par David Dougherty <sect1> EARP, c'est quoi? <p> EARP est un outil de Conception/Implémentation pour Base De Données Web, réalisé par-dessus le système de gestion de base de données Postgres95. Ses fonctionnalités comprennent: <itemize> <item> Un système de conception visuel. <item> Une interface d'envoi de courrier électronique. (pouvant prendre en charge le courrier entrant et sortant) <item> Un Mécanisme de Sécurité amélioré. <item> Un pilote cgi. </itemize> <sect1> Implantation <p> L'implantation principale de EARP consiste en un binaire CGI qui s'exécute sous le démon http pour fournir l'accès au serveur de base de données. Tous les outils de conception sont intégrés dans le pilote, aucune conception ne se fait sur le web. Les outils eux-mêmes requièrent un navigateur graphique, la compatibilité des objets conçus avec ces outils est indépendante de l'implantation, elle ne dépend uniquement que des préférences de conception individuelles. <sect1> Ce dont vous avez besoin pour faire fonctionner EARP <p> EARP est sensé fonctionner sur une grande variété de plates-formes avec peu de modifications sinon pas du tout. Les plates-formes pour lesquelles le fonctionnement est connu sont les suivantes: <itemize> <item>Solaris 2.5 <item>Linux 1.2.13+ <item>GNU C++ <item>Postgres95 (Version 1.01 / 1.02) <item>netsite server <item>NCSA httpd </itemize> <itemize> <item>GNU C++ <item>Postgres95 (Version 1.01 / 1.02) <item>NCSA httpd <item>Apache httpd </itemize> <sect1> Nouvelles Flash <p> La version courante (1.3) de Earp a été conçue au-dessus de la version de libpq livrée avec Postgres95 v1.01/1.02. Si vous utilisez une version plus récente de Postgres, vous devez vous attendre à ce que le programme nécessite quelques modifications pour fonctionner correctement. Dans la version de développement (Earp 2.0), la prise en charge de libpq est en cours de prise en compte en tant que module, et de ce fait pourra supporter autant de versions de postgres que nous aurons de temps pour écrire ces modules. La version de développement est attendue, pour le public, aux alentours du milieu du printemps(97). <sect1> Comment fonctionne-t-il? <p> Une des fonctionnalités principales de EARP est d'utiliser une approche orientée objet pour produire des pages html qui s'interfacent à la base de données. La plupart des pages sont constituées de plusieurs objets. Chaque objet est produit par une sorte d'outil et reçoit un nom, les objets sont alors liés ensembles et appelés en séquence par l'outil de gestion de pages. Les objets sont également réutilisables à l'intérieur de plusieurs pages. Il existe des outils de base pour HTML, pour les Requêtes, pour la saisie dans des formulaires, le formatage variable des requêtes et des objets en entrée, ainsi que pour lier des objets pour en former de nouveaux. On trouve également des outils plus avancés tels que l'outil de courrier électronique et l'outil de création de requêtes en parallèle. La gestion perfectionnée de la sécurité est une des autres fonctionnalités de EARP. L'accès aux différentes zones du système EARP peut être limité par une grande variété de moyens. Pour faciliter cette sécurité perfectionnée, EARP effectue des contrôles à chaque connexion au système, et détermine à quels "ids" et "groups" appartient l'agent qui se connecte. Les accès aux zones sont définis séparément, et la combinaison des deux permet de décider si l'accès à une certaine zone de Earp est autorisé. De plus , tout ce qui est requis pour réaliser les fonctionnalités de sécurité se trouve dans un serveur http qui effectue une authentification de l'utilisateur minimale (ou meilleure). <sect1> Quelques exemples en ligne <p> Partie intégrante de l'aide au SGBD ICC Help Database, la Page du Catalogue de Recherche est un document EARP qui peut exécuter plusieurs requêtes. Les boîtes de sélection sont générées par le programme EARP à partir de listes dans la base de données. Comme autre exemple de ce que l'on peut faire avec EARP... vous pouvez maintenant voir la Liste des Objets de la Base de Données d'aide. La création de ces trois interfaces m'a pris moins de quinze minutes. <sect1> Où puis-je le trouver? <p> EARP est disponible via un ftp anonyme à <url url="ftp://ftp.oswego.edu"> dans le répertoire 'pub/unix/earp'. La version courante à la date de rédaction de ce texte est 1.3.1 S'il vous plaît, après avoir récupéré et mis en service EARP, envoyez moi un mot pour en décrire le succès ou les échecs. <sect1> Documentation disponible <p> Toute la documentation a été déplacée à la page index "User Docs and Tutorials" (Documentation Utilisateur et Cours). <sect1> L'Histoire d'EARP <p> Earp 0.1 a démarré en tant que programme à l'automne 1995. Je travaillais à la réalisation d'un livre d'or accessible par le web, dynamiquement configurable. A ce moment là, il y avait tout un tas de programmes cgi faisant tous quelque chose de différent et d'utile, agrégés par un peu de colle SSI et un peu de programmation c. Je réalisais alors que je faisais beaucoup de travail répétitif, et que la plupart des choses que je faisais devaient exécuter dans de nombreuses fenêtres à la fois (netscape, emacs, shell, mail) alors que la mise au point était rapidement devenue un cauchemar. A cette époque mon ami et patron Don Michaels me contacta. Il était intéressé par l'automatisation d'une grosse partie de notre support utilisateur et par la tenue d'une base de données gérant l'historique des appels et des réponses. Peu de temps après, j'avais terminé le schéma initial de ce qui est en train de devenir rapidement notre base de données d'aide. Seulement, je rechignais à l'idée de construire une base de données d'aide à partir de ce qui était alors un ensemble très primitif d'utilitaires. Lorsque les cours du printemps 96 débutèrent, je démarrais quand même le projet, principalement sous le coup de l'ennui, mais aussi parce que j'étais dans un cours d'architecture de base de données et que je voulais m'entraîner un peu les méninges. Peu de temps après j'avais un prototype acceptable en état de marche, ce qui rendit Don très heureux car il avait renoncé à l'idée de quelqu'un créant une base de données d'aide pour lui. (Le prototype tourne encore sur l'un de mes serveurs...(juin 96)) Le prototype faisait vraiment quelques choses très intéressantes, mais en avril, j'étais à nouveau découragé... A chaque fois que je désirais modifier quelque chose, j'entrais dans un lent processus de recompilation, ou je tombais sur un fichier texte particulièrement distrayant. Je n'avais aussi aucun moyen d'utiliser le concept de building block si utile dans EARP... J'ai réalisé pas mal d'énormes coupés-collés. Vers la fin de l'année scolaire je fus encore une fois découragé sur le déroulement des choses et décidais que ce dont j'avais besoin, c'était d'un ensemble d'outils plus adaptés à ce que je faisais. De plus, je voulais aussi que mon prototype fonctionne sur un e VRAIE base de données relationnelle et je ne chérissais pas l'idée de recommencer tout ce travail d'accès codés en dur, de liens, et de méthodes de sortie. J'eus un bref moment de répit, si l'on peut dire. Nous soutenions la Conférence SUNY CIT et j'ai tellement été occupé pendant une semaine et demi que je pris du recul par rapport à tout ce que j'avais écrit sur le prototype de base de donnée d'aide excepté sur les idées que j'avais eu quand j'avais écrit la série d'utilitaires initiale et que ce qui m'irritait le plus était l'état actuel des choses. Peu de temps après la conférence, je commençais le prototype de la version actuelle de EARP(may96), en utilisant le SGBD relationnel postgres95 comme support. A la mi-juin, le prototype avait évolué en une suite intégrée de prototypes d'outils tout à fait séduisante, avec comme premier avantage de tous tourner en html, et de stocker leurs données d'initialisation dans la base de donnée. La plus grande partie de la deuxième moitié de juin fut consacrée à la mise au point du code et à l'utilisation de l'interface.( Pendant ces deux semaines j'ai accédé plus de 5000 fois à notre serveur web.) A la fin juin, la plupart des bogues importants étaient chassés de EARP, et il y avait un nombre suffisant d'objets dans la "nouvelle" base de données d'aide que l'on pouvant en faire l'annonce officielle à notre équipe de support. A propos, j'ai également tenu un journal pendant le développement de EARP et Don Michaels et moi présentons un papier décrivant la Base de Données d'Aide à la conférence ACM/SIGUCCS à Chicago en Septembre de cette année. <sect>WWW Web interface pour PostgresSQL - dbengine <p> <url url="http://www.cis-computer.com/dbengine/ "> Un extrait de la page d'accueil de dbengine est donné ci-dessous:- dbengine est une interface Web plug 'n play pour Postgres95 créée par Ingo Ciechowski Version 0.82 alpha Documentation au 11/23/96 A propos de dbengine dbengine est une interface entre le WWW et Postgres95 qui permet un accès simple à n'importe quelle base de données existante en seulement quelques minutes. Ce petit programme Perl program est né après avoir essayé un tas de paquetages disponibles tels que AppGen, PHP-FI et d'autres. Alors, pourquoi ai-je, en quelque sorte, réinventé la roue ? Eh bien, PHP-FI offre une sorte de langage Perl dans vos documents, mais pas le vrai Perl alors que AppGen et wdb-p95 nécessite la création d'un fichier de configuration pour chacune de vos bases de données -- c'est un peu comme si vous deviez apprendre un nouveau métalangage avant de pouvoir commencer à travailler. C'est à ce moment que je commençais à me sentir plus à l'aise avec une petite applet Perl de mon cru... et maintenant mon dbengine est devenu un outil qui, je pense, est prêt à être partagé avec les autres. A la différence des autres outils, vous n'avez pas à apprendre un langage de programmation particulier ou un langage de script pour commencer à utiliser dbengine. De plus, il n'y a pas à créer de fichier de configuration pour chaque base de données, et vous n'avez donc pas besoin de vous familiariser avec sa structure. Cependant - au cas où vous voudriez profiter de toutes les possibilités de dbengine, ce serait une bonne idée de connaître le langage Perl. Le système tout entier peut être configuré à l'aide de simples manipulations d'une base de données complémentaire qui contient les informations de détail sur la manière de visualiser vos accès à la base de données. Vous pouvez même spécifier des Champs Virtuels qui sont calculés en temps réel avant d'être affichés à l'écran. Licence dbengine est un logiciel libre selon les mêmes conditions que Perl. Lisez sa licence si vous n'êtes pas sûr de ce que vous pouvez ou ne pouvez pas faire. La dernière ligne indique que c'est une version plus gentille et plus modérée que celle de la licence GNU -- une de celle qui n'affecte pas votre travail si vous extrayez des parties de dbengine ou du paquetage pour l'inclure dans un produit commercial! <sect>Module Apache Webserver pour PostgreSQL - NeoSoft NeoWebScript <p> Apache est un serveur Web bien connu. On trouvera un module d'interface de PostgreSQL pour le serveur Web Apache à - <url url="http://www.neosoft.com/neowebscript/"> Voici, ci-dessous, un extrait de la page d'accueil de NeoWebScript:- NeoWebScript est un langage de programmation qui permet d'inclure des programmes simples ou compliqués dans des fichiers HTML. Quand une page HTML contenant un script NeoWebScript est appelée, le serveur Web , ayant le NeoWebScript activé, exécute le(s) script(s) inclus, produisant une page Web dont le contenu, personnalisé, a été créé par le programme. NeoWebScript est un moyen rapide, sûre, facile à apprendre de créer des programmes interactifs puissants directement en code HTML dans des pages Web. Avec NeoWebScript, les compteurs, les formulaires de courrier électronique, "graffiti walls", livres d'or et suivi des visiteurs sont aisés, même pour un programmeur débutant. Regardez comment NeoWebScript se défend bien par rapport à PERL et JavaScript. NeoWebScript 2.2 vient de sortir! Le 24 juin 1997, NeoSoft rend disponible la version 2.2 de NeoWebScript 2.2, en l'intégrant avec le nouveau serveur Apache 1.2.0 . Si vous utilisez un serveur web ayant NeoWebScript installé et que vous vouliez commencer à l'utiliser, il y a un tout un tas d'Informations Utilisateur disponibles. Les réponses de bases pour démarrer se trouvent dans la "FAQ Nouvel Utilisateur". Des didacticiels vous guident dans l'apprentissage du langage, alors que des Démonstrations vous apportent des applications toutes faites que vous pouvez télécharger et adapter. Le document "Commandes et les Variables" constitue la référence complète du langage, et celui de Maintenance contient des conseils et des astuces pour vous aider à résoudre tous les problèmes. Au cas où vous souhaiteriez installer NeoWebScript sur votre serveur web, votre webmestre doit lire notre "FAQ Syso" pour se lancer. Le document "Théorie de fonctionnement" explique comment NeoWebScript fonctionne, celui d'Installation est un guide pas à pas des opérations à effectuer. Le guide de Gestion traite de la manière de configurer et de faire fonctionner le serveur, celui de Tests permet de vérifier le fonctionnement correct de NeoWebScript, enfin, celui de Maintenance traite des problèmes de serveur. Hé, attendez une minute direz-vous, combien voulez-vous en contrepartie d'un tel logiciel, hein? Il n'y a aucuns frais pour l'utilisation de NeoWebScript-2.2 que ce soit pour votre ISP, votre intranet, ou votre extranet. Vous pourrez voir un licence complète quand vous vous enregistrerez pour télécharger le logiciel, mais l'essentiel est que nous aimerions recevoir la somme monstrueuse de &dollar 99 si vous désirez l'inclure dans votre propre produit ou l'utiliser dans un serveur commercial (eg. SSL). NeoWebScript est un module pour le serveur web Apache qui vous permet d'inclure , en tant que langage de script, pour vos pages web, le langage de programmation Tcl/Tk . Il a été inventé par Karl Lehenbauer, Directeur Technique chez NeoSoft, et documenté, renforcé et étendu par les programmeurs de NeoSoft et par des rédacteurs techniques. Le serveur Apache est le serveur web le plus populaire au monde, totalisant 42 &percnt des 1 044 163 sites interrogés lors de l'étude "Netcraft Web Server" de Mai 1997. La deuxième plus grande valeur enregistrée concerne les différents serveurs Microsoft, totalisant légèrement plus de 16 &percnt, soit une différence d'environ 270,000 serveurs. Tcl/Tk est un langage de script puissant, libre et multi-plateformes développé par le Dr. John Ousterhout, maintenant "Sun Distinguished Engineer" (n.d.t. : distinction honorifique de la Cie Sun). Selon ses propres termes : "Tcl/Tk permet aux développeurs de logiciels de réaliser un travail dix fois plus rapidement qu'avec des outils basés sur C ou C++. C'est aussi un grand langage de synthèse permettant de faire travailler ensemble des applications existantes en les rendant plus graphiques et orientées Internet." Avec une communauté de développement de plus de 500 000 personnes de par le monde et des milliers d'applications commerciales, Sun vient juste d'annoncer la création d'un nouveau groupe de travail nommé SunScript, pour soutenir cette communauté avec un environnement de développement intégré et pour développer une suite de produits pour établir un lien entre Tcl le Web et Java. Karl Lehenbauer, Fondateur et Directeur Technique de NeoSoft, a participé au développement de Tcl/Tk dès le tout début. Avec Mark Diehkans, ils sont les auteurs de Tcl étendu (Extended Tcl), connu également sous le nom de TclX ou NeoSoft Tcl, qui constitue un ensemble puissant d'extensions au langage. Beaucoup des commandes courantes essentielles de Tcl proviennent de Tcl étendu, et furent introduites dans le langage par le Dr. Ousterhout. NeoSoft Inc., 1770 St. James Place, Suite 500, Houston, TX 77056 USA <sect> HEITML, extension, côté serveur de HTML et langage 4GL pour PostgreSQL <p> Heitml est un autre outil d'interfaçage de postgres avec le monde du world wide web. Pour plus de détails contacter <tscreen><verb> Helmut Emmelmann H.E.I. Informationssyteme GmbH Wimpfenerstrasse 23 Tel. 49-621-795141 68259 Mannheim Germany Fax. 49-621-795161 </verb></tscreen> <itemize> <item> E-mail Mr.Helmut Emmelmann at <htmlurl url="mailto: emmel@h-e-i.de" name="emmel@h-e-i.de"> <item> Heitml site web principal <url url="http://www.heitml.com"> <item> Heitml site web secondaire <url url="http://www.h-e-i.deom"> </itemize> Heitml est à la fois une extension, côté serveur, de HTML et un langage de la quatrième génération (4GL). Avec lui, on peut écrire des applications web dans un style HTML et en utilisant de nouvelles balises de style HTML. heitml (prononcé "H-ail"-TML) est une extension de HTML et un langage de quatrième génération complet permettant aux Applications utilisant le web d'interagir avec des données stockées dans des bases de données SQL, sans mériter l'écriture de scripts CGI complexes. heitml étend HTML côté serveur, convertissant de manière dynamique les fichiers ".hei" au format HTML et ainsi, les rendant compatibles avec n'importe quel butineur web. Il englobe la syntaxe simple et familière de HTML et apporte un large assortiment de Balises et de Bibliothèques prédéveloppées pour prendre en charge les tâches qui auparavant nécessitaient CGI. De même que XML, heitml permet l'utilisation de balises définies par l'utilisateur. Avec heitml les marqueurs définis par l'utilisateur peuvent être traduits en HTML et envoyés à un butineur. heitml est destiné à la fois aux concepteurs HTML et aux programmeurs professionnels. Les concepteurs HTML peuvent utiliser les Balises heitml pour fabriquer des pages web dynamiques, des accès aux bases de données SQL ou créer des applications web complètes. On peut créer des Compteurs, des bases de données d'inscriptions, des formulaires de recherche, des formulaires de courrier électronique ou des menus hiérarchisés en utilisant simplement des Balises de style HTML prédéveloppées que l'on trouve dans les nombreuses Bibliothèques de Composants. Pour les programmeurs, heitml inclut un langage de quatrième génération complet en HTML <tscreen><verb> (e.g. <if>, <while>, et <let> Balises), </verb></tscreen> plus un évaluateur d'expression puissant pour les types de données entiers, réels, booléens chaîne de caractères et tuple. Les tuples ont une référence sémantique comme dans les langages orientés objets modernes et sont stockés sur un tas. Les variables heitml y compris toutes les structures de données complexes stockées sur le tas conservent leur valeur de page en page par l'utilisation du Mode Session. Il vous est possible de définir vos propres balises ou vos balises d'environnement et même de redéfinir les balises HTML. Avec heitml il devient possible de - - - développer des Sites Web de manière structurée et modulaire, tout en réduisant de façon drastique la surcharge due à la maintenance. - - - développer des Sites Web intelligents et interactifs, dont le contenu s'adapte dynamiquement aux besoins de l'utilisateur. - - - de visualiser le contenu de bases de données SQL sans autre programmation que l'utilisation de notre bibliothèque de Balises prédéfinies "dba". - - - de développer des applications de bases de données complexes et de Catalogue d'Achat en utilisant les Variables Session heitml tourne sous Linux avec n'importe quel Serveur Web utilisant l'interface CGI, et il est particulièrement rapide (mis à part la surcharge due à CGI) avec le Serveur Web APACHE (version 1.1.1, 1.1.3, ou 1.2.4) en utilisant l'API apache. Actuellement MSQL (Version 1 et 2), PostgreSQL (Version 6), mysql, et les bases de données yard sont supportés. heitml tourne sous Linux, BSDi, Solaris et SunOS, de même que sous Windows NT avec CGI, ISAPI et ODBC et Windows 95. heitml (sous linux) est libre pour la recherche, et pour une utilisation privée et non commerciale. Les Sites Web commerciaux doivent payer une licence. La version totalement opérationnelle de heitml est disponible pour une période d'essai et peut être téléchargée librement. (Notez, cependant, que chaque page Web ".hei" que vous développerez affichera un message indiquant qu'il s'agit d'une version à usage non commerciale. Après enregistrement, vous recevrez une clé pour effacer ce message sans avoir à réinstaller le programme.) Les nouvelles fonctionnalités de la version 1.2 sont - - - Bibliothèque de Composants pour des Formulaires de Recherche dans un Base de Données, menus hiérarchisés d'ouverture et de fermeture, formulaires de courrier électronique - - - Le Mode Session a été reconçu et amélioré pour conserver toutes les variables (y compris le tas tout entier) au travers des différentes pages. Cela signifie que les données, de n'importe quelle taille sont conservées à l'intérieur d'une session. Ceci offre l'opportunité d'un champ plus large pour créer de nouvelles applications, e.g. stockage complet des résultats d'une interrogation dans la mémoire de la session. - - - Les instructions d'installation, la documentation et les bibliothèques d'exemples ont été augmentées de manière significative, un cours d'autoformation a été ajouté - - - Des balises pour exécuter des commandes shell et pour envoyer des courriers électronique ont été ajoutées - - - Le support du formatage d'impression et de la mise au point. heitml affiche votre code source en couleurs dans votre butineur et signale les erreurs de façon intuitive. En cas d'erreur à l'exécution, toutes les structures de données internes sont affichées dans le butineur en indiquant et préservant leurs positions dans le code source original. - - - Diverses nouvelles variables serveur et fonctions intégrées ont été ajoutées - - - En mode production, heitml collecte maintenant des informations complètes sur les erreurs survenues lors de l'accès, par des utilisateurs, à votre site. <p> Voici ce que dit la page d'accueil de heitml - heitml (prononcer "H-ail"-TML) étend et augmente de façon significative les fonctionnalités de HTML grâce aux balises définissables et aux possibilités complètes de programmation. Ce qui permet de créer simplement des applications au contenu dynamique et orientées bases de données dans le monde HTML, sans CGI et sans scripts externes ou langages de programmation. Cela signifie que vous, en tant qu'auteur HTML, vous pouvez inclure des applications dans vos pages web, simplement, en utilisant quelques nouvelles balises sans CGI et sans programmation. D'un autre côté, comme utilisateur avancé ou comme programmeur vous pouvez créer et programmer de puissantes bibliothèques de balises. Cette approche rend heitml souhaitable à la fois pour les utilisateurs nouveaux de HTML et pour les programmeurs professionnels. heitml tourne sur le serveur web et génère dynamiquement du HTML, aussi heitml est compatible avec les standards internet et avec n'importe quel butineur web. Il permet un accès total aux bases de données tout en évitant à l'utilisateur toute la complexité inutile de CGI. heitml a été développé selon les plus récents critères en matière de construction de compilateurs et de systèmes transactionnels. Les pages heitml sont développées exactement de la même façon que les pages HTML, à l'aide d'un éditeur de texte ou d'un éditeur HTML, et placées comme d'habitude sur le serveur web. Cependant, maintenant, les pages peuvent contenir des balises heitml dynamiques et des accès à des bibliothèques de balises. Vous pouvez utiliser ces balises pour accéder à une base de données, pour créer un contenu dynamique, pour envoyer des courriers électronique, et même pour créer de puissantes applications telles que les bases de données d'inscriptions ou de systèmes d'achats. Les nouveaux venus à HTML et les programmeurs professionnels seront stupéfaits de la vitesse et de la facilités avec lesquelles il peuvent concevoir des applications passionnantes telle que notre Livre d'Or Interactif sans nécessiter la complexité et l'apprentissage difficiles des scripts CGI, simplement en utilisant les outils fournis dans notre bibliothèque dba. heitml est accompagné d'un large éventail de bibliothèques de balises, pour créer des livres d'or, des applications de maintenance de bases de données, des formulaires puissants de courrier électronique ou de structuration de votre site web à l'aide de menus hiérarchiques. Ces outils sont prêts à être utilisés, il suffit simplement d'ajouter les balises correspondantes à votre site web. En tant que programmeur expérimenté, vous pouvez pleinement utiliser l'architecture dynamique persistante de tuple d'heitml : heitml n'est pas simplement un langage de script à typage dynamique, avec évaluateur d'expression, procédures récursives et capacités de passage de paramètres étendues, mais il apporte aussi des possibilités de tuples persistants dynamiques pour conserver automatiquement des données de session de n'importe quelle taille. heitml a tellement de nouvelles possibilités et d'usages que c'est impossible de les décrire tous dans une simple page web. Pour cette raison, nous avons conçu ce site Web de manière à fournir soit une simple vue d'ensemble du produit, soit à fouiller aussi profondément que vous le désirez dans les "tenants et aboutissants" du langage. Quelle que soit l'approche que vous choisirez, nous pensons que vous trouverez que heitml a beaucoup à offrir, et nous espérons que vous serez d'accord pour trouver que réellement "il porte le monde du World Wide Web à un niveau plus élevé!" Le menu, sur le côté gauche de l'écran vous aidera à naviguer dans notre Site Web Site de manière organisée et méthodique, mais vous pouvez aussi utiliser notre Menu Rapide (Quick Menu) pour sauter directement à n'importe quelle page avec un seul clic sur le mulot. Si vous visitez ce Site pour la première fois, nous vous suggérons d'essayer le Livre d'Or Interactif d'heitml pour avoir une démonstration vraiment impressionnante de la façon dont heitml peut rendre vos Pages Web plus interactives. Si vous signez notre Livre d'Or, vous pouvez nous laissez vos commentaires ou nous parler de votre Site Web favori en utilisant les commandes de formatage de HTML. C'est comme si vous créiez votre propre page Web privée et que vous la voyiez publiée immédiatement! La section traitant des Fonctionnalités de heitml Features fourni un Sommaire Rapide de ses Fonctionnalités et de ses Avantages, de même que des Pages destinées à répondre aux besoins spécifiques et aux questions des Concepteurs et des Programmeurs. Notre Guide du Langage offre un didacticiel, en ligne, qui montre, de manière pratique, quelques unes des façons dont vous pouvez utiliser heitml pour développer, améliorer et simplifier vos Pages Web et vos Applications. Le document Référence du Langage est destiné à ceux qui cherchent une information spécifique sur la syntaxe, la structure, et l'utilisation des différents éléments du langage. Cependant, ce pourrait être une bonne idée pour tout le monde de lire la Page concernant la Conception Générale qui offre une vue d'ensemble sur les types de problèmes spécifiques pour lesquels heitml a été conçu afin d'y apporter une solution. Naturellement, vous voudrez savoir si heitml tourne sur le Système d'Exploitation spécifique, le Serveur Web, ou le SGBD SQL que vous utilisez, vous trouverez toutes ces informations dans notre section des Plates-formes Supportées. Enfin, nous vous invitons à Télécharger une copie d'essai du programme pour l'utiliser sur votre propre système. Nous sommes sûrs que vous apprécierez cette "méthode d'essai avant achat", et nous sommes à l'écoute de tout retour d'informations que vous voudrez bien nous donner. (c) 1996-1997 H.E.I. Tous droits réservés. (All Rights Reserved) <sect>PHP/FI Langage de script côté serveur, avec HTML intégré, pour PostgreSQL <p> Outil d'Interfaçage WWW <url url="http://www.vex.net/php"> Pour les questions envoyer un courrier électronique à : <htmlurl url="mailto:rasmus@lerdorf.on.ca" name="rasmus@lerdorf.on.ca"> On trouvera ci-dessous un extrait de la page d'accueil de PHP/FI :- PHP/FI est un langage de script côté serveur, avec langage HTML intégré. Il vous permet d'écrire des scripts simples directement dans vos fichiers .HTML à la manière JavaScript, sauf que, à la différence de JavaScript, PHP/FI n'est pas dépendant du butineur utilisé. JavaScript est un langage, côté client, avec HTML intégré alors que PHP/FI est un langage côté serveur. PHP/FI est similaire, dans son concept, au produit LiveWire Pro pour Netscape. Si vous en avez les moyens, vous utilisez le serveur du commerce Netscape et l'un des systèmes d'exploitation supportés, et vous jetterez probablement un oeil sur LiveWire Pro. Si vous préférez un logiciel libre, évoluant rapidement, qui est disponible avec la totalité de son code source, vous apprécierez probablement PHP/FI. <sect1> Fonctionnalités principales <p> Support de CGI Standard, FastCGI et du module Apache. Comme programme CGI standard, PHP/FI peut être installé sur n'importe quelle machine Unix sur laquelle tourne n'importe quel serveur web Unix. Avec le support du nouveau standard FastCGI, PHP/FI peut trouver avantage des gains de vitesse apportés par ce mécanisme. Comme module Apache, PHP/FI devient une alternative extrêmement puissante et brillante à la programmation CGI. <itemize> <item> Enregistrement des accès Avec les possibilités d'enregistrement des accès de PHP/FI, les utilisateurs peuvent entretenir leur propre compteur d'accès et l'enregistrer. Il n'utilise en aucune façon les fichiers de d'enregistrement des connexions du système central, et il permet un suivi des accès en temps réel. Le Script du Visualisateur de Connexions fournit un résumé rapide des accès à un ensemble de pages possédées par un utilisateur individuel. De plus, le paquetage peut être configuré pour générer un pied de page, sur chaque page, qui montre l'information sur les accès. Regardez au bas de cette page pour en avoir un exemple. <item> Contrôle d'accès Un écran de configuration intégré, basé sur le web, permet la configuration du contrôle des accès. Il est possible de créer des règles d'accès pour toutes ou quelques unes des pages web possédées par une certaine personne qui met diverses restrictions sur qui peut voir ces pages et comment elles seront vues. Les pages peuvent être protégées par un mot de passe, complètement interdites, à connexion désactivée et l'accès basé sur le domaine du client, le butineur, l'adresse de courrier électronique ou même le document auquel on se réfère. <item> Support de Postgres Postgres est un SGBDR (RDBMS) avancé libre. PHP/FI supporte les requêtes Postgres95 et PostgreSQL SQL incluses directement dans les fichiers .html. <item> RFC-1867 Support du téléchargement de fichier Le téléchargement de fichier est une nouvelle fonctionnalité de Netscape 2.0. Il permet aux utilisateurs de télécharger des fichiers vers le serveur web. PHP/FI réalise le décodage Mime réel pour faire ce travail et fournit aussi le cadre additionnel pour faire quelque chose d'utile avec le fichier téléchargé une fois que celui-ci a été reçu. <item> Contrôle d'authentification basé sur HTTP PHP/FI peut être utilisé pour créer des mécanismes d'authentification personnalisés basés sur HTTP pour le serveur web Apache. <item> Variables, Tableaux, Tableaux associatifs PHP/FI supporte des variables typées, des tableaux et même des tableaux associatifs à la Perl. Ils peuvent être passés d'une page web à l'autre en utilisant les méthodes GET ou POST. <item> Conditions, Boucles Tant que (While) PHP/FI possède un langage de script aux fonctionnalités complètes de style C. Vous disposez des instructions de tests conditionnels if/then/elseif/else/endif ainsi que des boucles while et des instructions switch/case pour contrôler l'ordre logique et la manière dont les pages html doivent être affichées. <item> Expressions Régulières étendues Les expressions régulières sont très utilisées pour le filtrage, le remplacement de séquences et les manipulations générales de chaînes de caractères. PHP/FI supporte toutes les opérations communes sur les expressions régulières. <item> Contrôle de l'En-tête HTTP brute La possibilité d'envoyer à partir de pages web des en-têtes HTTP brutes personnalisées en fonction d'une condition est essentielle pour créer un site web de haut niveau. Un usage fréquent est l'envoi d'un emplacement: en-tête URL pour rediriger le client appelant vers une autre URL. Il peut aussi être utilisé pour stopper le stockage ou manipuler la dernière mise à jour de l'en tête de pages. <item> Création d'images GIF à la volée PHP/FI prend en compte la bibliothèque d'image GD de Thomas Boutell ce qui offre la possibilité de générer des images GIF à la volée. <item> Prise en charge du mode sécurité ("Safe Mode") ISP PHP/FI prend en charge un "Mode de Sécurité" exceptionnel qui permet d'avoir de multiples utilisateurs exécutant des scripts PHP en toute sécurité sur le même serveur. <item> C'est Libre! Pour finir, et c'est un point essentiel. Le paquetage est entièrement libre. Il est sous les conditions de la licence GPL qui vous permet d'utiliser ce logiciel pour n'importe quel objectif, commercial ou autre. Reportez-vous au document de la Licence Publique GNU pour des renseignements détaillés. </itemize> <sect1> Crédits <p> * De grandes parties de ce code ont été développées à et pour l'université de Toronto. De grands Mercis à Lee Oattes du Département de Développement des Réseaux à l'université pour ses critiques constructives permanentes. * Le code de prise en charge de Postgres95 a été écrit par Adam Sussman <htmlurl url="mailto: asussman@vidya.com" name="asussman@vidya.com"> * d'autres, innombrables, ont participé aux tests et à la mise au point du paquetage. PHP/FI Version 2.0 <sect1> Bref Historique <p> PHP a commencé sa vie comme simple petite enveloppe cgi écrite en Perl. Je l'ai écrit en un après-midi, dans une période entre deux contrats, alors que j'avais besoin d'un outil rapide pour avoir une idée de la personne qui était en train de lire mon curriculum vitae en ligne. Je n'avais eu l'intention de le voir utiliser en dehors de mon propre usage. Le serveur web sur lequel j'avais mon curriculum vitae était extrêmement surchargé et avait des problèmes constants de création de processus. Je réécris le petit programme Perl en C pour me débarrasser de la surcharge considérable générée par la création d'un processus d'exécution du programme Perl à chaque fois que mon curriculum vitae était consulté. Par la suite d'autres personnes, sur le même serveur web, prirent connaissance de mon petit programme et me demandèrent s'ils pouvaient l'utiliser. Alors, comme cela devait arriver, ils commencèrent à me demander plus de fonctionnalités. J'ajoutais plus de fonctionnalités et finalement constituais une semi-distribution en y incluant une documentation, une liste de diffusion et une FAQ. Le nom de ce paquetage était "Outils pour une Page d'Accueil Personnelle" (Personal Home Page Tools), nom qui devint plus tard "Kit de Construction de Page d'Accueil Personnelle" (Personal Home Page Construction Kit). A la même époque, je commençais à m'amuser avec les bases de données et j'écrivis un outil pour inclure facilement des requêtes SQL dans des pages web. C'était fondamentalement un autre petit programme CGI qui analysait les requêtes SQL et facilitait la création de formulaires et de tables basés sur ces requêtes. Cet outil fut appelé FI "Interpréteur de Formulaire" (Form Interpreter). La version 2.0 PHP/FI est une réécriture complète de ces deux paquetages combinés pour former un simple programme. il a maintenant évolué au point de devenir un simple langage de programmation intégré dans les fichiers HTML. L'acronyme original, PHP, lui est resté. Il n'est plus réellement approprié. PHP/FI est aujourd'hui plus utilisé pour mettre en place des sites web entiers que pour de petites pages d'accueil personnelles. Quel que soit son nom, il élimine le besoin de recourir à de nombreux petits programmes cgi Perl en permettant d'insérer de simples scripts directement dans vos fichiers HTML. Ceci améliore les performances globales de vos pages web puisque la surcharge due au lancement de processus Perl successifs a été éliminée. La gestion de larges sites web a également été facilitée en plaçant tous les composants d'une page web dans un fichier html unique. En incluant le support de différentes bases de données, il devient trivial de développer des pages web mettant en oeuvre des bases de données. Nombreux sont ceux qui trouvent que cette intégration est plus facile à gérer que d'essayer de créer des fichiers HTML et CGI séparés. Tout au long de cette documentation, toute référence à PHP, FI ou PHP/FI traite de la même chose. La différence entre PHP et FI est seulement conceptuelle. Les deux sont construits à partir de la même distribution du code source. Lorsque je construit le paquetage sans aucun support de connexion d'accès ou de restriction d'accès, je nomme mon binaire FI. Quand je le construit avec ces options, je l'appelle PHP. <sect1> Bon, que puis-je faire avec PHP/FI? <p> La première chose que vous allez noter, si vous faites tourner une page par l'intermédiaire de PHP/FI, c'est qu'il ajoute un pied de page vous informant du nombre d'accès à votre page (si vous incluez le support des connexions d'accès dans votre binaire). C'est seulement un tout petit exemple de ce que PHP/FI peut faire pour vous. Il joue également le rôle très important d'interpréteur de formulaire cgi, d'où la partie FI de son nom. Par exemple si vous créez un formulaire dans l'une de vos pages web, vous avez besoin de quelque chose pour traiter l'information contenue dans ce formulaire. Même si vous désirez simplement passer l'information à une autre page web, vous aurez besoin d'un programme cgi pour le faire. PHP/FI facilite grandement le processus de prise en charge des données du formulaire pour en faire quelque chose. <sect1> Un simple exemple <p> Supposons que vous ayez le formulaire : <tscreen><verb> <FORM ACTION="/cgi-bin/php.cgi/~userid/display.html" METHOD=POST> <INPUT TYPE="text" name="name"> <INPUT TYPE="text" name="age"> <INPUT TYPE="submit"> <FORM> </verb></tscreen> Votre fichier display.html doit contenir quelque chose du genre : < ?echo "Hi &dollar name, vous avez &dollar âge ans!<p>" > C'est aussi simple que cela! PHP/FI crée automatiquement une variable pour chaque champ de saisie de votre formulaire. Vous pouvez alors utiliser ces variables dans le fichier ACTION URL. L'étape suivante, après avoir vu comment utiliser ces variables, est de commencer à jouer avec quelques balises de gestion du déroulement logique de vos pages. Par exemple, si vous voulez afficher différents messages dépendants de des informations entrées par l'utilisateur, vous pouvez utiliser la logique si/alors (if/else). Dans notre exemple ci-dessus, on peut afficher différentes choses dépendant de l'âge entré par l'utilisateur en modifiant notre fichier display.html en : <tscreen><verb> <? if($age>50); echo "Hi $name, vous êtes un fossile!<p>"; elseif($age>30); echo "Hi $name, vous êtes très vieux!<p>"; else; echo "Hi $name."; endif; > </verb></tscreen> PHP/FI fournit un langage de script très puissant qui peut faire beaucoup plus que ce qui est exposé dans l'exemple ci-dessus. Regardez la section sur le langage de Script PHP/FI pour des informations complémentaires. Vous pouvez également utiliser PHP/FI pour configurer qui a le droit d'accéder à vos pages. Ceci est effectué en utilisant l'écran de configuration inclus. Par son intermédiaire , vous pourrez, par exemple, spécifier que seulement les gens appartenant à un certain domaine seront autorisés à voir vos pages, vous pouvez également créer une règle protégeant certaines pages par un mot de passe. Voir la section Contrôle d'Accès pour plus de détails. PHP/FI est également capable de recevoir des fichiers téléchargés par n'importe quel butineur conforme à la norme RFC-1867. Cette fonctionnalité permet aux gens de télécharger également des fichiers de texte ou binaire. Avec le contrôle de PHP/FI et les fonctions logiques, vous disposez d'un contrôle total sur qui est autorisé à télécharger un fichier et sur ce que l'on peut faire de ce fichier une fois téléchargé. Voir la section Téléchargement de fichier pour de plus amples détails. PHP/FI supporte le paquetage Postgres95. Il supporte les requêtes SQL incluses dans vos fichiers .HTML. Consultez la section Support Postgres95 pour plus d'informations. PHP/FI supporte également le paquetage du SGBD mysql. Il supporte les requêtes SQL incluses dans vos fichiers .HTML. Consultez la section Support mysql pour plus d'informations. <sect1> Redirection CGI <p> Notes Apache 1.0.x Une bonne manière de faire tourner PHP/FI est d'utiliser un module de redirection cgi avec le serveur Apache. Veuillez noter que vous n'avez pas à vous soucier des modules de redirection si vous utilisez la version module Apache de PHP/FI. Deux de ces modules de redirection sont disponibles. L'un est développé par Dave Andersen <htmlurl url="mailto:angio@aros.net" name="angio@aros.net"> et est disponible à ftp://ftp.aros.net/pub/util/apache/mod_cgi_redirect.c et l'autre arrive inclus avec Apache et est appelé mod_actions.c. Ces deux modules sont extrêmement similaires. Ils diffèrent très légèrement dans leur utilisation. Les deux ont été testés et fonctionnent avec PHP/FI. Mise en garde importante: à la date de cette rédaction (Apr.20/96), la version courante officielle (1.0.5) a de sévères limitations qui empêchent les requêtes de redirection cgi d'avoir des données ??? post-method data associées. J'ai étudié ce problèmes et l'ai résolu dans ma version d'Apache. Il y a un colmatage officiel dans les Fichiers Archives de la Page d'Accueil. Une autre mise en garde particulièrement importante au sujet d'Apache 1.0.x est qu'il n'aligne pas correctement les types doubles sur la plupart des architectures. Vous découvrirez d'étranges erreurs de bus provenant de votre httpd en utilisant mod_php. Comme solution, soit vous passez à la version Apache 1.1, soit vous éditez le fichier source Apache alloc.c. Dans ce fichier vous trouverez le morceau de code suivant : union align { /* Types which are likely to have the longest RELEVANT alignment * restrictions... we don't do much with doubles. */ char *cp; void (*f)(); long l; FILE *fp; }; Il vous faudra ajouter un type double à ce source et recompiler votre serveur Apache. Le morceau de code correct est : union align { /* Types which are likely to have the longest RELEVANT alignment * restrictions... we don't do much with doubles. */ char *cp; void (*f)(); long l; FILE *fp; double d; }; Regardez dans la documentation Apache sur la manière d'ajouter un module. En général vous ajoutez le nom de module dans un fichier appelé Configuration. La ligne à ajouter si vous voulez utiliser le module mod_actions est : Module action_module mod_actions.o Si vous envisagez d'utiliser le module mod_cgi_redirect.c ajoutez cette ligne : Module cgi_redirect_module mod_cgi_redirect.o Puis compilez votre httpd et installez-le. Pour configurer la redirection cgi il vous faudra soit créer un nouveau type mime dans votre fichier mime.types soit utiliser la commande AddType dans votre fichier srm.conf pour ajouter le type mime. Le type mime à ajouter doit être quelque chose comme : application/x-httpd-php phtml Si vous vous apprêtez à utiliser le module mod_actions.c il vous faudra ajouter la ligne suivante dans votre fichier srm.conf: Action application/x-httpd-php /cgi-bin/php.cgi Si vous vous apprêtez à utiliser mod_cgi_redirect.c vous devrez ajouter cette ligne à srm.conf : CgiRedirect application/x-httpd-php /cgi-bin/php.cgi N'essayez pas d'utiliser en même temps mod_actions.c et mod_cgi_redirect.c . Une fois que vous avez l'un de ces modules de redirection cgi installé et configuré correctement, vous pouvez spécifier que vous voulez qu'un fichier soit filtré par php/fi en mettant simplement l'extension .phtml au fichier. De plus, si vous ajoutez index.phtml à votre ligne de configuration DirectoryIndex dans votre fichier srm.conf alors la page de plus haut niveau d'un répertoire sera automatiquement filtrée par php si vous appelez votre fichier index index.phtml. HTTPD Netscape Vous pouvez rediriger automatiquement les requêtes pour des fichiers ayant une extension donnée de façon à ce qu'ils soient pris en compte par PHP/FI en utilisant le module de Redirection du Serveur CGI Netscape. Ce module est disponible dans le Fichier Archives de la Page d'Accueil de the PHP/FI. Le fichier LIZSEZ_MOI (README) dans le paquetage explique clairement comment le configurer pour l'utiliser avec PHP/FI. HTTPD NCSA Actuellement NCSA ne supporte pas les modules, donc, pour effectuer une redirection cgi avec ce serveur, il vous faudra modifier le code source de votre serveur. Un colmatage pour faire cela avec NCSA 1.5 est disponible dans le fichier archives de PHP/FI. <sect1> Lancer PHP/FI à partir de la ligne de commande <p> Si vous fabriquez la version CGI de PHP/FI, vous pouvez l'utiliser simplement à partir de la ligne de commande, en tapant: php.cgi nom_de_fichier où nom_de_fichier est le fichier que vous voulez filtrer. Vous pouvez également créer des scripts PHP/FI autonomes en faisant ressembler la première ligne de votre script à quelque chose comme : <tscreen><verb> #!/usr/local/bin/php.cgi -q </verb></tscreen> L'option "-q" supprime l'impression des en-têtes HTTP. Vous pouvez vous passer de cette option si vous le désirez. <sect>Interface Python pour PostgreSQL <p> PyGres95 est une interface pour PostgreSQL. Il est disponible à <url url="ftp://ftp.via.ecp.fr/pub/python/contrib/Database/PyGres95-1.0b.tar.gz "> On trouvera ci-dessous un extrait de la page d'accueil de PyGres95:- PyGres - v1.0b : module Postgres95 pour Python PyGres95, version 1.0b Une interface Python pour la base de données Postgres95. Ecrit par Pascal Andre, <htmlurl url="mailto:andre@chimay.via.ecp.fr" name="andre@chimay.via.ecp.fr"> Postgres95 est un SGBD dérivé de Postgres4.2. Il est conforme à (pour la plupart) ANSI SQL et offre beaucoup de possibilités intéressantes (Liens dynamiques C pour les fonctions ou les définitions de types, temps de réponse, ...). Ce paquetage est protégé par un copyright de l'Université de Californie (Regents of the University of California), et est diffusable librement. Python est un langage de programmation interprété. Il est orienté objet et facile d'utilisation (syntaxe légère, simple et instructions simples), et dispose de nombreuses extensions pour construire des GUIs, des interfaces WWW,... Un butineur web "intelligent" (à la HotJava) est actuellement en cours de développement (november 1995), et cela devrait ouvrir de nombreuses portes aux programmeurs. Python est protégé par un copyright de Stichting Mathematisch Centrum, Amsterdam, Pays-Bas, et est diffusable librement. PyGres95 est un module python d'interface à la base de données Postgres95 . Il comprend une bibliothèque de requêtes Postgres95 permettant une utilisation facile des fonctionnalités puissantes de Postgres95 en coopération avec tous les autres modules python. Il a été développé sur un système Linux 1.3/ELF, mais a été testé sur une plate-forme Solaris 2.4. De toutes façons, il devrait fonctionner sur toute plate-forme où python et postgres95 sont disponibles. <sect1> Où le trouver ... ? <p> Les sites principaux des différents paquetages sont : <itemize> <item> Python : <url url="ftp.python.org:/pub/python"> <item> Postgres95 : <url url="ftp.s2k-ftp.cs.berkeley.edu:/pub/postgres95"> <item> PyGres95 : <url url="ftp.via.ecp.fr:/pub/python/contrib"> </itemize> Vous devriez cependant essayer de trouver un site miroir proche de votre propre site. Consultez les sources d'information pour trouver ces sites. PyGres95 devrait se trouver dans les répertoires contrib des sites Python et Postgres95. <sect1> Information et support <p> Si vous avez besoin d'informations concernant ces paquetages veuillez consulter leurs sites web: <itemize> <item> Python : <url url="http://www.python.org/"> <item> Postgres95 : <url url="http://epoch.cs.berkeley.edu:8000/postgres95/index.html"> <item> PyGres95 : <url url="http://www.via.ecp.fr/via/products/pygres.html"> </itemize> Pour un support : <itemize> <item> Python : newsgroup comp.lang.python <item> Postgres95 : mailing list (see package documentation for information) <item> PyGres95 : contact me <htmlurl url="mailto:andre@via.ecp.fr" name="andre@via.ecp.fr"> pour des rapports d'erreurs, des idées et des remarques </itemize> J'essaierai de répondre dans la mesure où mon temps libre me le permettra. <sect>Passerelle entre PostgreSQL et WWW - WDB-P95 <p> WDB-P95 - Une interface Web interface aux bases de données Postgres95. C'est à <url url="http://www.eol.ists.ca/~dunlop/wdb-p95/"> Voici un extrait de la page d'accueil de WDB-P95 :- Version 1.4b2 bêta - Créée par J. Douglas Dunlop A propos de wdb-p95 C'est une version modifiée de wdb-1.3a2 qui fournit une passerelle WWW à Postgres95. Cette version nécessite également un Butineur capable de prendre en compte les Tables HTML pour avoir une sortie tabulée. Ceci n'est pas requis pour le wdb original et on peut facilement y revenir. (Je voulais seulement les tables parce que je n'étais pas d'accord avec les commandes < et >!) Vous pouvez essayer ma Bande CASI et ma Requête d'Image. Vous pouvez jeter un coup d'oeil au Fichier de Définition de Formulaire (FDF) que j'ai utilisé pour créer la Bande CASI et également la Requête d'Image, qui comprends une jointure (JOIN) de 2 tables. Cette version contient tous les fichiers nécessaires pour installer et faire tourner WDB-P95 en tant qu'interface à vos bases de données Postgres95 . Le portage de ce système pour une autre base de données devrait être relativement facile - à condition qu'elle supporte le SQL standard et possède une interface Perl. <sect1> Le serveur Postgres95, pgperl, et httpd doivent-ils résider sur le même hôte? <p> Non - Le serveur Postgres95 n'a pas à être sur le même hôte. Comme WDB-P95 est appelé par le démon http, ils doivent résider sur le même hôte. - Et comme WDB-P95 a été écrit pour utiliser Pg.pm - pgperl doit être sur le même hôte également. Pgperl a été écrit en utilisant la bibliothèque libpq, donc, il sera capable d'accéder à n'importe quel serveur Postgres95 n'importe où sur le réseau, juste comme n'importe quel autre client Postgres95. Comme illustré ci-dessous {WWW Client (Netscape)} => {HTTP Server (NCSA's http) + WDB-P95 + pgperl + libpq}=> {Postgres95 server} Les parenthèses () représentent les machines. Chaque machine peut être d'un type différent : NT, SUN, HP, ... mais il faut que vous ayez la bibliothèque d'interface libpq pour le type de machine sur lequel vous envisagez d'utiliser WDB-P95, puisqu'il vous faut compiler pgperl. (Le système a été conçu pour utiliser les tables HTML donc un client WWW récent est meilleur) <sect1> Nouvelle Version <p> Les nouvelles versions du logiciel et des pages ci-dessus sont toujours disponibles à partir de la page d'Accueil de WDB-P95. <url url="http://www.eol.ists.ca/~dunlop/wdb-p95/"> Pour les questions et pour s'inscrire aux listes de diffusion contacter <htmlurl url="mailto:dunlop@eol.ists.ca" name="dunlop@eol.ists.ca"> <sect>Interface au langage "C" pour PostgreSQL <p> Elle est incluse dans la distribution et s'appelle 'libpq'. Elle est similaire aux bibliothèques OCI Oracle, DB-lib Sybase, ou CLI Informix. <sect>Interface au langage "C++" pour PostgreSQL <p> Elle est incluse dans la distribution et est nommée 'libpq++'. <sect>ESQL/C pour PostgreSQL <p> C'est un précompilateur C intégré pour PostgreSQL ESQL/C comme Pro*C d'Oracle, et ESQL/C d'Informix : <itemize> <item> <url url="ftp://ftp.lysator.liu.se/pub/linus"> <item>Email : <htmlurl url="mailto:linus@epact.se" name="linus@epact.se"> </itemize> ESQL/C pour PostgreSQLest une interface de programmation d'application SQL (API) qui permet au programmeur C de créer des applications personnalisées avec des possibilités de gestion de base de données. ESQL/C pour PostgreSQL vous permet d'utiliser un langage de troisième génération avec lequel vous êtes familiarisé tout en profitant des avantages d'un Langage de Requêtes Structuré (SQL). ESQL/C est composé des éléments logiciels suivants: <itemize> <item> Les bibliothèques ESQL/C de fonctions C fournissent les accès au serveur de base de données. <item> Les fichiers d'en-tête ESQL/C apportent les définitions des structures de données, les constantes et les macros utiles dans un programme ESQL/C. <item> Le préprocesseur ESQL/C, qui est un préprocesseur de code source qui transforme un fichier C contenant des instructions SQL en fichier exécutable. </itemize> <sect>Opérateurs Bit-par-Bit pour PostgreSQL <p> Les opérateurs Bit-par-Bit ont été écrits par Nicolas Moldavsky <htmlurl url="nico@overnet.com.ar" name="nico@overnet.com.ar"> Ce sont des fonctions "C" qui implantent les opérateurs bit-par-bit (AND, OR, XOR, bit complement) dans pgsql. Si quelqu'un désire les utiliser, il peut les récupérer par ftp anonyme de <itemize> <item> <url url="ftp://ftp.overnet.com.ar/pub/utils/linux/bitpgsql.tgz"> </itemize> De plus, il y a un "Makefile" qui marche bien sous Linux. <sect>Les Codes Kanji Japonais pour PostgreSQL <p> Sont très utiles pour les Japonais. On les trouvera au site suivant : <url url="ftp://ftp.sra.co.jp/pub/cmd/postgres/"> <sect>Portage de PostgreSQL Port pour Windows 95/Windows NT <p> Un portage pour Windows 95/Windows NT est en cours de réalisation. Ce portage de fait en utilisant gcc, gmake pour Win NT/95. Le programme gnu-win32 est utilisé pour compiler le code source sous win32. GNU gcc est disponible pour win32. Consultez ce site - <itemize> <item> <url url="http://www.cygnus.com/misc/gnu-win32"> </itemize> Récupérez-y le fichier cdk.exe (fichier auto-extractible pour gnu-win32) Le portage peut également être réalisé en utilisant l'outil "Emulateur Unix sous NT" (Unix-Emulator on NT) suivant de <itemize> <item> <url url="http://www.softway.com"> </itemize> <sect>Listes de Diffusion et Groupes de Discussion <p> Il y a un groupe de discussion pour PostgreSQL à news.postgresql.org Veuillez suivre les étapes suivantes pour vous inscrire <tscreen><verb> 1. Choisir : Fenêtre | Netscape News 2. Choisir : Fichier | Open News Host 3. Taper news.postgresql.org dans la boîte de dialogue. 4. Le nom du groupe de discussion est comp.databases.postgresql.questions. Pour l'ajouter, cliquez avec le bouton de droite sur news.postgresql.org, et choisir : Add Newsgroup. Taper alors le nom du groupe de discussion dans la boîte de dialogue. Le groupe de discussion sera ajouté à la liste dans l'écran de gauche. 5. Les noms des Groupes de Discussion seront listés dans l'écran de gauche. Tous les messages, dans les groupes sélectionnés, seront affichés dans l'écran de droite. </verb></tscreen> Regardez les Titres des Listes de Diffusion sur la page web principale à : <url url="http://www.postgresql.org/"> <itemize> <item>Envoyez vos questions par courrier électronique à: <htmlurl url="mailto:pgsql-questions@postgresql.org" name="pgsql-questions@postgresql.org"> <item> Développeurs <htmlurl url="mailto:pgsql-hackers@postgresql.org" name="pgsql-hackers@postgresql.org"> <item> Questions spécifiques à un portage <htmlurl url="mailto:pgsql-ports@postgresql.org" name="pgsql-ports@postgresql.org"> <item> Questions concernant la documentation <htmlurl url="mailto:pgsql-docs@postgresql.org" name="pgsql-docs@postgresql.org"> </itemize> Vous recevrez une réponse, par courrier électronique, dans la journée qui suit!! Vous pouvez également vous inscrire aux listes de diffusion. Pour vous inscrire ou vous radier d'une liste, envoyez un courrier à <itemize> <item> <htmlurl url="mailto:pgsql-questions-request@postgresql.org" name="pgsql-questions-request@postgresql.org"> <item> <htmlurl url="mailto:pgsql-hackers-request@postgresql.org" name="pgsql-hackers-request@postgresql.org"> <item> <htmlurl url="mailto:pgsql-ports-request@postgresql.org" name="pgsql-ports-request@postgresql.org"> <item> <htmlurl url="mailto:pgsql-docs-request@postgresql.org" name="pgsql-docs-request@postgresql.org"> </itemize> Le corps du message doit uniquement contenir la simple ligne <p> subscribe <p> (ou) <p> unsubscribe Il y a aussi des listes de diffusion qui sont archivées au format html à l'endroit suivant - <itemize> <item> <url url="ftp://ftp.postgresql.org"> dans le répertoire /pub/majordomo </itemize> <sect>Livres et Documentations <p> On trouve dans la distribution <itemize> <item> Le 'Guide Utilisateur' pour PostgreSQL, <item> Le 'Guide de Réalisation' détaillant la constitution interne de PostgreSQL. <item> Les manuels "en ligne". <item> Le manuels en ligne au format HTML. <item> Egalement les manuels au format Postscript pour faire des éditions papier. </itemize> Documents de Référence: Ouvrages de référence utiles : <itemize> <item> "Understanding the New SQL: A Complete Guide" (Comprendre le Nouveau SQL: Un Guide Complet)- by Jim Melton and Alan R.Simon Morgan Kaufman Publisher. C'est un des meilleurs livres sur SQL. <item> "A Guide to THE SQL STANDARD" (Un Guide du STANDARD SQL) - by C.J.Date Addison-Wesley Publishing company. C'est également un bon livre </itemize> <tscreen><verb> Stephen Cannan and Gerard Otten SQL - The Standard Handbook , Novembre 1992 (SQL - Le Manuel Standard) McGraw-Hill Book Company Europe , Berkshire, SL6 2QL, England Martin Gruber, Technical Editor: Joe Celko SQL Instant Référence , 1993 (SQL Référence Immédiate) SYBEX Inc. 2021 Challenger Drive Alameda, CA 94501 </verb></tscreen> Des centaines d'autres titres concernant SQL sont disponibles! Vérifiez-le dans une librairie. <sect>Support Technique pour PostgreSQL <p> <itemize> <item>Vous pouvez envoyer par courrier électronique les questions ou problèmes techniques auxquels vous devez faire face à : <htmlurl url="mailto:pgsql-questions@postgresql.org" name="pgsql-questions@postgresql.org"> </itemize> et vous recevrez par courrier électronique une réponse dans la journée qui suit. Dans un futur proche, l'organisation PostgreSQL vendra un support technique aux petites et grandes compagnies, les revenus de cette activité serviront à entretenir plusieurs sites miroirs (web and ftp) partout dans le monde. Ces revenus pourront aussi servir à créer une documentation imprimée, des guides, des livres pour aider les clients. Les profits seront également à organiser des conférences annuelles où les clients et professionnels pourront trouver et échanger des idées et des papiers techniques. Ceci devrait aider l'organisation PostgreSQL à se tenir debout. <sect>Aspects Economiques et Commerciaux <p> Les bases de données commerciales paient de nombreuses taxes telles que des taxes fédérales, d'état, sur les ventes, sur les salariées, la sécurité sociale, les taxes pour les soins médicaux, des Indemnités pour les employés, des coûts de marketing et de publicité. Tous ces coûts ne sont pas destinés directement au développement de la base de donnée. Quand vous achetez une base de données commerciale une partie du montant est destiné aux taxes, aux dépenses de recherche et développement ( R&D ). Donc la valeur réelle pour la base de données est beaucoup plus faible. De plus les bases de données commerciales doivent payer pour leurs immeubles/biens et pour l'achat de machines Unix, leur installation et leur maintenance. Tous ces coûts sont répercutés sur les clients. PostgreSQL possède l'avantage, sur les bases de données commerciales, de ne pas supporter de taxes puisque développée sur l'internet. Un très grand nombre de personnes contribuent à son développement. Par exemple, dans un cas hypothétique, s'il y a un million de compagnies aux U.S.A et que chacune contribue pour environ &dollar 10 (en valeur de logiciel pour PostgreSQL) alors, chaque compagnie recevra dix millions de dollars!! C'est cela la magie du développement sur internet. <p> Actuellement, le code source de PostgreSQL est constitué d'environ 200 000 lignes de code "C" et "C++". Si le coût de chaque ligne de code "C" est évalué à &dollar 10, alors le coût total de PostgreSQL, tel qu'il est aujourd'hui est de &dollar 2 000 000 (deux millions de dollars!!). <p> De nombreuses compagnies ont déjà développé de grandes quantités de code "C", "C++" maison. Donc, en prenant le code source de PostgreSQL et en collaborant avec les autres compagnies sur internet, cela leur bénéficierait beaucoup en leur faisant économiser du temps et des efforts. <sect> Spécifications ANSI/ISO SQL - SQL 1992, SQL 1998 <p> <sect1> Documents du standard National et International ANSI/ISO SQL <p> Ces documents sont situés à l'endroit indiqué ci-dessous. Il y a deux documents, le premier et le second, veuillez lire les deux. <itemize> <item> Aller à l'endroit indiqué ci-dessous <url url="ftp://ftp.postgresql.org/pub/incoming/ANSI-ISO-SQL-SPECIFICATIONS"> Et cliquer sur les deux fichiers nommés CLICK_ME_FIRST.html et CLICK_ME_SECOND.html <item> <url url="http://www.naiua.org/std-orgs.html"> <item> <url url="http://www.ansi.org/docs"> cliquer sur le fichier cat_c.html et effectuer une recherche de "Database SQL" <item> Standard SQL92 <url url="http://www.jcc.com"> et cliquer sur le fichier sql_stnd.html </itemize> <sect1> Syntaxe de l' ANSI/ISO SQL 1992 <p> <tscreen><verb> Ce fichier contient la grammaire en BNF du langage, arborescence explorée d'abord en profondeur, réalisée le 27-AOUT-1992 11:03:41.64. La version spécifique de BNF donnée ici est : ANSI et SQL2-seulement. <SQL terminal character> ::= <SQL language character> | <SQL embedded language character> <SQL language character> ::= <simple Latin letter> | <digit> | <SQL special character> <simple Latin letter> ::= <simple Latin upper case letter> | <simple Latin lower case letter> <simple Latin upper case letter> ::= A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z <simple Latin lower case letter> ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 <SQL special character> ::= <space> | <double quote> | <percent> | <ampersand> | <quote> | <left paren> | <right paren> | <asterisk> | <plus sign> | <comma> | <minus sign> | <period> | <solidus> | <colon> | <semicolon> | <less than operator> | <equals operator> | <greater than operator> | <question mark> | <underscore> | <vertical bar> <space> ::= !! <EMPHASIS>(space character in character set in use) <double quote> ::= " <percent> ::= % <ampersand> ::= & <quote> ::= ' <left paren> ::= ( <right paren> ::= ) <asterisk> ::= * <plus sign> ::= + <comma> ::= , <minus sign> ::= - <period> ::= . <solidus> ::= / <colon> ::= : <semicolon> ::= ; <less than operator> ::= < <equals operator> ::= = <greater than operator> ::= > <question mark> ::= ? <underscore> ::= _ <vertical bar> ::= | <SQL embedded language character> ::= <left bracket> | <right bracket> <left bracket> ::= [ <right bracket> ::= ] <token> ::= <nondelimiter token> | <delimiter token> <nondelimiter token> ::= <regular identifier> | <key word> | <unsigned numeric literal> | <national character string literal> | <bit string literal> | <hex string literal> <regular identifier> ::= <identifier body> <identifier body> ::= <identifier start> [ ( <underscore> | <identifier part> )... ] <identifier start> ::= <EMPHASIS>(!! See the Syntax Rules) <identifier part> ::= <identifier start> | <digit> <key word> ::= <reserved word> | <non-reserved word> <reserved word> ::= ABSOLUTE | ACTION | ADD | ALL | ALLOCATE | ALTER | AND | ANY | ARE | AS | ASC | ASSERTION | AT | AUTHORIZATION | AVG | BEGIN | BETWEEN | BIT | BIT_LENGTH | BOTH | BY | CASCADE | CASCADED | CASE | CAST | CATALOG | CHAR | CHARACTER | CHAR_LENGTH | CHARACTER_LENGTH | CHECK | CLOSE | COALESCE | COLLATE | COLLATION | COLUMN | COMMIT | CONNECT | CONNECTION | CONSTRAINT | CONSTRAINTS | CONTINUE | CONVERT | CORRESPONDING | COUNT | CREATE | CROSS | CURRENT | CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP | CURRENT_USER | CURSOR | DATE | DAY | DEALLOCATE | DEC | DECIMAL | DECLARE | DEFAULT | DEFERRABLE | DEFERRED | DELETE | DESC | DESCRIBE | DESCRIPTOR | DIAGNOSTICS | DISCONNECT | DISTINCT | DOMAIN | DOUBLE | DROP | ELSE | END | END-EXEC | ESCAPE | EXCEPT | EXCEPTION | EXEC | EXECUTE | EXISTS | EXTERNAL | EXTRACT | FALSE | FETCH | FIRST | FLOAT | FOR | FOREIGN | FOUND | FROM | FULL | GET | GLOBAL | GO | GOTO | GRANT | GROUP | HAVING | HOUR | IDENTITY | IMMEDIATE | IN | INDICATOR | INITIALLY | INNER | INPUT | INSENSITIVE | INSERT | INT | INTEGER | INTERSECT | INTERVAL | INTO | IS | ISOLATION | JOIN | KEY | LANGUAGE | LAST | LEADING | LEFT | LEVEL | LIKE | LOCAL | LOWER | MATCH | MAX | MIN | MINUTE | MODULE | MONTH | NAMES | NATIONAL | NATURAL | NCHAR | NEXT | NO | NOT | NULL | NULLIF | NUMERIC | OCTET_LENGTH | OF | ON | ONLY | OPEN | OPTION | OR | ORDER | OUTER | OUTPUT | OVERLAPS | PAD | PARTIAL | POSITION | PRECISION | PREPARE | PRESERVE | PRIMARY | PRIOR | PRIVILEGES | PROCEDURE | PUBLIC | READ | REAL | REFERENCES | RELATIVE | RESTRICT | REVOKE | RIGHT | ROLLBACK | ROWS | SCHEMA | SCROLL | SECOND | SECTION | SELECT | SESSION | SESSION_USER | SET | SIZE | SMALLINT | SOME | SPACE | SQL | SQLCODE | SQLERROR | SQLSTATE | SUBSTRING | SUM | SYSTEM_USER | TABLE | TEMPORARY | THEN | TIME | TIMESTAMP | TIMEZONE_HOUR | TIMEZONE_MINUTE | TO | TRAILING | TRANSACTION | TRANSLATE | TRANSLATION | TRIM | TRUE | UNION | UNIQUE | UNKNOWN | UPDATE | UPPER | USAGE | USER | USING | VALUE | VALUES | VARCHAR | VARYING | VIEW | WHEN | WHENEVER | WHERE | WITH | WORK | WRITE | YEAR | ZONE <non-reserved word> ::= ADA | C | CATALOG_NAME | CHARACTER_SET_CATALOG | CHARACTER_SET_NAME | CHARACTER_SET_SCHEMA | CLASS_ORIGIN | COBOL | COLLATION_CATALOG | COLLATION_NAME | COLLATION_SCHEMA | COLUMN_NAME | COMMAND_FUNCTION | COMMITTED | CONDITION_NUMBER | CONNECTION_NAME | CONSTRAINT_CATALOG | CONSTRAINT_NAME | CONSTRAINT_SCHEMA | CURSOR_NAME | DATA | DATETIME_INTERVAL_CODE | DATETIME_INTERVAL_PRECISION | DYNAMIC_FUNCTION | FORTRAN | LENGTH | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH | MESSAGE_TEXT | MORE | MUMPS | NAME | NULLABLE | NUMBER | PASCAL | PLI | REPEATABLE | RETURNED_LENGTH | RETURNED_OCTET_LENGTH | RETURNED_SQLSTATE | ROW_COUNT | SCALE | SCHEMA_NAME | SERIALIZABLE | SERVER_NAME | SUBCLASS_ORIGIN | TABLE_NAME | TYPE | UNCOMMITTED | UNNAMED <unsigned numeric literal> ::= <exact numeric literal> | <approximate numeric literal> <exact numeric literal> ::= <unsigned integer> [ <period> [ <unsigned integer> ] ] | <period> <unsigned integer> <unsigned integer> ::= <digit>... <approximate numeric literal> ::= <mantissa> E <exponent> <mantissa> ::= <exact numeric literal> <exponent> ::= <signed integer> <signed integer> ::= [ <sign> ] <unsigned integer> <sign> ::= <plus sign> | <minus sign> <national character string literal> ::= N <quote> [ <character representation>... ] <quote> [ ( <separator>... <quote> [ <character representation>... ] <quote> )... ] <character representation> ::= <nonquote character> | <quote symbol> <nonquote character> ::= !! <EMPHASIS>(See the Syntax Rules.) <quote symbol> ::= <quote><quote> <separator> ::= ( <comment> | <space> | <newline> )... <comment> ::= <comment introducer> [ <comment character>... ] <newline> <comment introducer> ::= <minus sign><minus sign>[<minus sign>...] <comment character> ::= <nonquote character> | <quote> <newline> ::= !! <EMPHASIS>(implementation-defined end-of-line indicator) <bit string literal> ::= B <quote> [ <bit>... ] <quote> [ ( <separator>... <quote> [ <bit>... ] <quote> )... ] <bit> ::= 0 | 1 <hex string literal> ::= X <quote> [ <hexit>... ] <quote> [ ( <separator>... <quote> [ <hexit>... ] <quote> )... ] <hexit> ::= <digit> | A | B | C | D | E | F | a | b | c | d | e | f <delimiter token> ::= <character string literal> | <date string> | <time string> | <timestamp string> | <interval string> | <delimited identifier> | <SQL special character> | <not equals operator> | <greater than or equals operator> | <less than or equals operator> | <concatenation operator> | <double period> | <left bracket> | <right bracket> <character string literal> ::= [ <introducer><character set specification> ] <quote> [ <character representation>... ] <quote> [ ( <separator>... <quote> [ <character representation>... ] <quote> )... ] <introducer> ::= <underscore> <character set specification> ::= <standard character repertoire name> | <implementation-defined character repertoire name> | <user-defined character repertoire name> | <standard universal character form-of-use name> | <implementation-defined universal character form-of-use name> <standard character repertoire name> ::= <character set name> <character set name> ::= [ <schema name> <period> ] <SQL language identifier> <schema name> ::= [ <catalog name> <period> ] <unqualified schema name> <catalog name> ::= <identifier> <identifier> ::= [ <introducer><character set specification> ] <actual identifier> <actual identifier> ::= <regular identifier> | <delimited identifier> <delimited identifier> ::= <double quote> <delimited identifier body> <double quote> <delimited identifier body> ::= <delimited identifier part>... <delimited identifier part> ::= <nondoublequote character> | <doublequote symbol> <nondoublequote character> ::= <EMPHASIS>(!! See the Syntax Rules) <doublequote symbol> ::= <double quote><double quote> <unqualified schema name> ::= <identifier> <SQL language identifier> ::= <SQL language identifier start> [ ( <underscore> | <SQL language identifier part> )... ] <SQL language identifier start> ::= <simple Latin letter> <SQL language identifier part> ::= <simple Latin letter> | <digit> <implementation-defined character repertoire name> ::= <character set name> <user-defined character repertoire name> ::= <character set name> <standard universal character form-of-use name> ::= <character set name> <implementation-defined universal character form-of-use name> ::= <character set name> <date string> ::= <quote> <date value> <quote> <date value> ::= <years value> <minus sign> <months value> <minus sign> <days value> <years value> ::= <datetime value> <datetime value> ::= <unsigned integer> <months value> ::= <datetime value> <days value> ::= <datetime value> <time string> ::= <quote> <time value> [ <time zone interval> ] <quote> <time value> ::= <hours value> <colon> <minutes value> <colon> <seconds value> <hours value> ::= <datetime value> <minutes value> ::= <datetime value> <seconds value> ::= <seconds integer value> [ <period> [ <seconds fraction> ] ] <seconds integer value> ::= <unsigned integer> <seconds fraction> ::= <unsigned integer> <time zone interval> ::= <sign> <hours value> <colon> <minutes value> <timestamp string> ::= <quote> <date value> <space> <time value> [ <time zone interval> ] <quote> <interval string> ::= <quote> ( <year-month literal> | <day-time literal> ) <quote> <year-month literal> ::= <years value> | [ <years value> <minus sign> ] <months value> <day-time literal> ::= <day-time interval> | <time interval> <day-time interval> ::= <days value> [ <space> <hours value> [ <colon> <minutes value> [ <colon> <seconds value> ] ] ] <time interval> ::= <hours value> [ <colon> <minutes value> [ <colon> <seconds value> ] ] | <minutes value> [ <colon> <seconds value> ] | <seconds value> <not equals operator> ::= <> <greater than or equals operator> ::= >= <less than or equals operator> ::= <= <concatenation operator> ::= || <double period> ::= .. <module> ::= <module name clause> <language clause> <module authorization clause> [ <temporary table declaration>... ] <module contents>... <module name clause> ::= MODULE [ <module name> ] [ <module character set specification> ] <module name> ::= <identifier> <module character set specification> ::= NAMES ARE <character set specification> <language clause> ::= LANGUAGE <language name> <language name> ::= ADA | C | COBOL | FORTRAN | MUMPS | PASCAL | PLI <module authorization clause> ::= SCHEMA <schema name> | AUTHORIZATION <module authorization identifier> | SCHEMA <schema name> AUTHORIZATION <module authorization identifier> <module authorization identifier> ::= <authorization identifier> <authorization identifier> ::= <identifier> <temporary table declaration> ::= DECLARE LOCAL TEMPORARY TABLE <qualified local table name> <table element list> [ ON COMMIT ( PRESERVE | DELETE ) ROWS ] <qualified local table name> ::= MODULE <period> <local table name> <local table name> ::= <qualified identifier> <qualified identifier> ::= <identifier> <table element list> ::= <left paren> <table element> [ ( <comma> <table element> )... ] <right paren> <table element> ::= <column definition> | <table constraint definition> <column definition> ::= <column name> ( <data type> | <domain name> ) [ <default clause> ] [ <column constraint definition>... ] [ <collate clause> ] <column name> ::= <identifier> <data type> ::= <character string type> [ CHARACTER SET <character set specification> ] | <national character string type> | <bit string type> | <numeric type> | <datetime type> | <interval type> <character string type> ::= CHARACTER [ <left paren> <length> <right paren> ] | CHAR [ <left paren> <length> <right paren> ] | CHARACTER VARYING <left paren> <length> <right paren> | CHAR VARYING <left paren> <length> <right paren> | VARCHAR <left paren> <length> <right paren> <length> ::= <unsigned integer> <national character string type> ::= NATIONAL CHARACTER [ <left paren> <length> <right paren> ] | NATIONAL CHAR [ <left paren> <length> <right paren> ] | NCHAR [ <left paren> <length> <right paren> ] | NATIONAL CHARACTER VARYING <left paren> <length> <right paren> | NATIONAL CHAR VARYING <left paren> <length> <right paren> | NCHAR VARYING <left paren> <length> <right paren> <bit string type> ::= BIT [ <left paren> <length> <right paren> ] | BIT VARYING <left paren> <length> <right paren> <numeric type> ::= <exact numeric type> | <approximate numeric type> <exact numeric type> ::= NUMERIC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ] | DECIMAL [ <left paren> <precision> [ <comma> <scale> ] <right paren> ] | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ] | INTEGER | INT | SMALLINT <precision> ::= <unsigned integer> <scale> ::= <unsigned integer> <approximate numeric type> ::= FLOAT [ <left paren> <precision> <right paren> ] | REAL | DOUBLE PRECISION <datetime type> ::= DATE | TIME [ <left paren> <time precision> <right paren> ] [ WITH TIME ZONE ] | TIMESTAMP [ <left paren> <timestamp precision> <right paren> ] [ WITH TIME ZONE ] <time precision> ::= <time fractional seconds precision> <time fractional seconds precision> ::= <unsigned integer> <timestamp precision> ::= <time fractional seconds precision> <interval type> ::= INTERVAL <interval qualifier> <interval qualifier> ::= <start field> TO <end field> | <single datetime field> <start field> ::= <non-second datetime field> [ <left paren> <interval leading field precision> <right paren> ] <non-second datetime field> ::= YEAR | MONTH | DAY | HOUR | MINUTE <interval leading field precision> ::= <unsigned integer> <end field> ::= <non-second datetime field> | SECOND [ <left paren> <interval fractional seconds precision> <right paren> ] <interval fractional seconds precision> ::= <unsigned integer> <single datetime field> ::= <non-second datetime field> [ <left paren> <interval leading field precision> <right paren> ] | SECOND [ <left paren> <interval leading field precision> [ <comma> <interval fractional seconds precision> ] <right paren> ] <domain name> ::= <qualified name> <qualified name> ::= [ <schema name> <period> ] <qualified identifier> <default clause> ::= DEFAULT <default option> <default option> ::= <literal> | <datetime value function> | USER | CURRENT_USER | SESSION_USER | SYSTEM_USER | NULL <literal> ::= <signed numeric literal> | <general literal> <signed numeric literal> ::= [ <sign> ] <unsigned numeric literal> <general literal> ::= <character string literal> | <national character string literal> | <bit string literal> | <hex string literal> | <datetime literal> | <interval literal> <datetime literal> ::= <date literal> | <time literal> | <timestamp literal> <date literal> ::= DATE <date string> <time literal> ::= TIME <time string> <timestamp literal> ::= TIMESTAMP <timestamp string> <interval literal> ::= INTERVAL [ <sign> ] <interval string> <interval qualifier> <datetime value function> ::= <current date value function> | <current time value function> | <current timestamp value function> <current date value function> ::= CURRENT_DATE <current time value function> ::= CURRENT_TIME [ <left paren> <time precision> <right paren> ] <current timestamp value function> ::= CURRENT_TIMESTAMP [ <left paren> <timestamp precision> <right paren> ] <column constraint definition> ::= [ <constraint name definition> ] <column constraint> [ <constraint attributes> ] <constraint name definition> ::= CONSTRAINT <constraint name> <constraint name> ::= <qualified name> <column constraint> ::= NOT NULL | <unique specification> | <references specification> | <check constraint definition> <unique specification> ::= UNIQUE | PRIMARY KEY <references specification> ::= REFERENCES <referenced table and columns> [ MATCH <match type> ] [ <referential triggered action> ] <referenced table and columns> ::= <table name> [ <left paren> <reference column list> <right paren> ] <table name> ::= <qualified name> | <qualified local table name> <reference column list> ::= <column name list> <column name list> ::= <column name> [ ( <comma> <column name> )... ] <match type> ::= FULL | PARTIAL <referential triggered action> ::= <update rule> [ <delete rule> ] | <delete rule> [ <update rule> ] <update rule> ::= ON UPDATE <referential action> <referential action> ::= CASCADE | SET NULL | SET DEFAULT | NO ACTION <delete rule> ::= ON DELETE <referential action> <check constraint definition> ::= CHECK <left paren> <search condition> <right paren> <search condition> ::= <boolean term> | <search condition> OR <boolean term> <boolean term> ::= <boolean factor> | <boolean term> AND <boolean factor> <boolean factor> ::= [ NOT ] <boolean test> <boolean test> ::= <boolean primary> [ IS [ NOT ] <truth value> ] <boolean primary> ::= <predicate> | <left paren> <search condition> <right paren> <predicate> ::= <comparison predicate> | <between predicate> | <in predicate> | <like predicate> | <null predicate> | <quantified comparison predicate> | <exists predicate> | <unique predicate> | <match predicate> | <overlaps predicate> <comparison predicate> ::= <row value constructor> <comp op> <row value constructor> <row value constructor> ::= <row value constructor element> | <left paren> <row value constructor list> <right paren> | <row subquery> <row value constructor element> ::= <value expression> | <null specification> | <default specification> <value expression> ::= <numeric value expression> | <string value expression> | <datetime value expression> | <interval value expression> <numeric value expression> ::= <term> | <numeric value expression> <plus sign> <term> | <numeric value expression> <minus sign> <term> <term> ::= <factor> | <term> <asterisk> <factor> | <term> <solidus> <factor> <factor> ::= [ <sign> ] <numeric primary> <numeric primary> ::= <value expression primary> | <numeric value function> <value expression primary> ::= <unsigned value specification> | <column reference> | <set function specification> | <scalar subquery> | <case expression> | <left paren> <value expression> <right paren> | <cast specification> <unsigned value specification> ::= <unsigned literal> | <general value specification> <unsigned literal> ::= <unsigned numeric literal> | <general literal> <general value specification> ::= <parameter specification> | <dynamic parameter specification> | <variable specification> | USER | CURRENT_USER | SESSION_USER | SYSTEM_USER | VALUE <parameter specification> ::= <parameter name> [ <indicator parameter> ] <parameter name> ::= <colon> <identifier> <indicator parameter> ::= [ INDICATOR ] <parameter name> <dynamic parameter specification> ::= <question mark> <variable specification> ::= <embedded variable name> [ <indicator variable> ] <embedded variable name> ::= <colon><host identifier> <host identifier> ::= <Ada host identifier> | <C host identifier> | <COBOL host identifier> | <Fortran host identifier> | <MUMPS host identifier> | <Pascal host identifier> | <PL/I host identifier> <Ada host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.) <C host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.) <COBOL host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.) <Fortran host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.) <MUMPS host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.) <Pascal host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.) <PL/I host identifier> ::= !! <EMPHASIS>(See the Syntax Rules.) <indicator variable> ::= [ INDICATOR ] <embedded variable name> <column reference> ::= [ <qualifier> <period> ] <column name> <qualifier> ::= <table name> | <correlation name> <correlation name> ::= <identifier> <set function specification> ::= COUNT <left paren> <asterisk> <right paren> | <general set function> <general set function> ::= <set function type> <left paren> [ <set quantifier> ] <value expression> <right paren> <set function type> ::= AVG | MAX | MIN | SUM | COUNT <set quantifier> ::= DISTINCT | ALL <scalar subquery> ::= <subquery> <subquery> ::= <left paren> <query expression> <right paren> <query expression> ::= <non-join query expression> | <joined table> <non-join query expression> ::= <non-join query term> | <query expression> UNION [ ALL ] [ <corresponding spec> ] <query term> | <query expression> EXCEPT [ ALL ] [ <corresponding spec> ] <query term> <non-join query term> ::= <non-join query primary> | <query term> INTERSECT [ ALL ] [ <corresponding spec> ] <query primary> <non-join query primary> ::= <simple table> | <left paren> <non-join query expression> <right paren> <simple table> ::= <query specification> | <table value constructor> | <explicit table> <query specification> ::= SELECT [ <set quantifier> ] <select list> <table expression> <select list> ::= <asterisk> | <select sublist> [ ( <comma> <select sublist> )... ] <select sublist> ::= <derived column> | <qualifier> <period> <asterisk> <derived column> ::= <value expression> [ <as clause> ] <as clause> ::= [ AS ] <column name> <table expression> ::= <from clause> [ <where clause> ] [ <group by clause> ] [ <having clause> ] <from clause> ::= FROM <table reference> [ ( <comma> <table reference> )... ] <table reference> ::= <table name> [ [ AS ] <correlation name> [ <left paren> <derived column list> <right paren> ] ] | <derived table> [ AS ] <correlation name> [ <left paren> <derived column list> <right paren> ] | <joined table> <derived column list> ::= <column name list> <derived table> ::= <table subquery> <table subquery> ::= <subquery> <joined table> ::= <cross join> | <qualified join> | <left paren> <joined table> <right paren> <cross join> ::= <table reference> CROSS JOIN <table reference> <qualified join> ::= <table reference> [ NATURAL ] [ <join type> ] JOIN <table reference> [ <join specification> ] <join type> ::= INNER | <outer join type> [ OUTER ] | UNION <outer join type> ::= LEFT | RIGHT | FULL <join specification> ::= <join condition> | <named columns join> <join condition> ::= ON <search condition> <named columns join> ::= USING <left paren> <join column list> <right paren> <join column list> ::= <column name list> <where clause> ::= WHERE <search condition> <group by clause> ::= GROUP BY <grouping column reference list> <grouping column reference list> ::= <grouping column reference> [ ( <comma> <grouping column reference> )... ] <grouping column reference> ::= <column reference> [ <collate clause> ] <collate clause> ::= COLLATE <collation name> <collation name> ::= <qualified name> <having clause> ::= HAVING <search condition> <table value constructor> ::= VALUES <table value constructor list> <table value constructor list> ::= <row value constructor> [ ( <comma> <row value constructor> )... ] <explicit table> ::= TABLE <table name> <query term> ::= <non-join query term> | <joined table> <corresponding spec> ::= CORRESPONDING [ BY <left paren> <corresponding column list> <right paren> ] <corresponding column list> ::= <column name list> <query primary> ::= <non-join query primary> | <joined table> <case expression> ::= <case abbreviation> | <case specification> <case abbreviation> ::= NULLIF <left paren> <value expression> <comma> <value expression> <right paren> | COALESCE <left paren> <value expression> ( <comma> <value expression> )... <right paren> <case specification> ::= <simple case> | <searched case> <simple case> ::= CASE <case operand> <simple when clause>... [ <else clause> ] END <case operand> ::= <value expression> <simple when clause> ::= WHEN <when operand> THEN <result> <when operand> ::= <value expression> <result> ::= <result expression> | NULL <result expression> ::= <value expression> <else clause> ::= ELSE <result> <searched case> ::= CASE <searched when clause>... [ <else clause> ] END <searched when clause> ::= WHEN <search condition> THEN <result> <cast specification> ::= CAST <left paren> <cast operand> AS <cast target> <right paren> <cast operand> ::= <value expression> | NULL <cast target> ::= <domain name> | <data type> <numeric value function> ::= <position expression> | <extract expression> | <length expression> <position expression> ::= POSITION <left paren> <character value expression> IN <character value expression> <right paren> <character value expression> ::= <concatenation> | <character factor> <concatenation> ::= <character value expression> <concatenation operator> <character factor> <character factor> ::= <character primary> [ <collate clause> ] <character primary> ::= <value expression primary> | <string value function> <string value function> ::= <character value function> | <bit value function> <character value function> ::= <character substring function> | <fold> | <form-of-use conversion> | <character translation> | <trim function> <character substring function> ::= SUBSTRING <left paren> <character value expression> FROM <start position> [ FOR <string length> ] <right paren> <start position> ::= <numeric value expression> <string length> ::= <numeric value expression> <fold> ::= ( UPPER | LOWER ) <left paren> <character value expression> <right paren> <form-of-use conversion> ::= CONVERT <left paren> <character value expression> USING <form-of-use conversion name> <right paren> <form-of-use conversion name> ::= <qualified name> <character translation> ::= TRANSLATE <left paren> <character value expression> USING <translation name> <right paren> <translation name> ::= <qualified name> <trim function> ::= TRIM <left paren> <trim operands> <right paren> <trim operands> ::= [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source> <trim specification> ::= LEADING | TRAILING | BOTH <trim character> ::= <character value expression> <trim source> ::= <character value expression> <bit value function> ::= <bit substring function> <bit substring function> ::= SUBSTRING <left paren> <bit value expression> FROM <start position> [ FOR <string length> ] <right paren> <bit value expression> ::= <bit concatenation> | <bit factor> <bit concatenation> ::= <bit value expression> <concatenation operator> <bit factor> <bit factor> ::= <bit primary> <bit primary> ::= <value expression primary> | <string value function> <extract expression> ::= EXTRACT <left paren> <extract field> FROM <extract source> <right paren> <extract field> ::= <datetime field> | <time zone field> <datetime field> ::= <non-second datetime field> | SECOND <time zone field> ::= TIMEZONE_HOUR | TIMEZONE_MINUTE <extract source> ::= <datetime value expression> | <interval value expression> <datetime value expression> ::= <datetime term> | <interval value expression> <plus sign> <datetime term> | <datetime value expression> <plus sign> <interval term> | <datetime value expression> <minus sign> <interval term> <interval term> ::= <interval factor> | <interval term 2> <asterisk> <factor> | <interval term 2> <solidus> <factor> | <term> <asterisk> <interval factor> <interval factor> ::= [ <sign> ] <interval primary> <interval primary> ::= <value expression primary> [ <interval qualifier> ] <interval term 2> ::= <interval term> <interval value expression> ::= <interval term> | <interval value expression 1> <plus sign> <interval term 1> | <interval value expression 1> <minus sign> <interval term 1> | <left paren> <datetime value expression> <minus sign> <datetime term> <right paren> <interval qualifier> <interval value expression 1> ::= <interval value expression> <interval term 1> ::= <interval term> <datetime term> ::= <datetime factor> <datetime factor> ::= <datetime primary> [ <time zone> ] <datetime primary> ::= <value expression primary> | <datetime value function> <time zone> ::= AT <time zone specifier> <time zone specifier> ::= LOCAL | TIME ZONE <interval value expression> <length expression> ::= <char length expression> | <octet length expression> | <bit length expression> <char length expression> ::= ( CHAR_LENGTH | CHARACTER_LENGTH ) <left paren> <string value expression> <right paren> <string value expression> ::= <character value expression> | <bit value expression> <octet length expression> ::= OCTET_LENGTH <left paren> <string value expression> <right paren> <bit length expression> ::= BIT_LENGTH <left paren> <string value expression> <right paren> <null specification> ::= NULL <default specification> ::= DEFAULT <row value constructor list> ::= <row value constructor element> [ ( <comma> <row value constructor element> )... ] <row subquery> ::= <subquery> <comp op> ::= <equals operator> | <not equals operator> | <less than operator> | <greater than operator> | <less than or equals operator> | <greater than or equals operator> <between predicate> ::= <row value constructor> [ NOT ] BETWEEN <row value constructor> AND <row value constructor> <in predicate> ::= <row value constructor> [ NOT ] IN <in predicate value> <in predicate value> ::= <table subquery> | <left paren> <in value list> <right paren> <in value list> ::= <value expression> ( <comma> <value expression> )... <like predicate> ::= <match value> [ NOT ] LIKE <pattern> [ ESCAPE <escape character> ] <match value> ::= <character value expression> <pattern> ::= <character value expression> <escape character> ::= <character value expression> <null predicate> ::= <row value constructor> IS [ NOT ] NULL <quantified comparison predicate> ::= <row value constructor> <comp op> <quantifier> <table subquery> <quantifier> ::= <all> | <some> <all> ::= ALL <some> ::= SOME | ANY <exists predicate> ::= EXISTS <table subquery> <unique predicate> ::= UNIQUE <table subquery> <match predicate> ::= <row value constructor> MATCH [ UNIQUE ] [ PARTIAL | FULL ] <table subquery> <overlaps predicate> ::= <row value constructor 1> OVERLAPS <row value constructor 2> <row value constructor 1> ::= <row value constructor> <row value constructor 2> ::= <row value constructor> <truth value> ::= TRUE | FALSE | UNKNOWN <constraint attributes> ::= <constraint check time> [ [ NOT ] DEFERRABLE ] | [ NOT ] DEFERRABLE [ <constraint check time> ] <constraint check time> ::= INITIALLY DEFERRED | INITIALLY IMMEDIATE <table constraint definition> ::= [ <constraint name definition> ] <table constraint> [ <constraint attributes> ] <table constraint> ::= <unique constraint definition> | <referential constraint definition> | <check constraint definition> <unique constraint definition> ::= <unique specification> even in SQL3) <unique specification> <left paren> <unique column list> <right paren> <unique column list> ::= <column name list> <referential constraint definition> ::= FOREIGN KEY <left paren> <referencing columns> <right paren> <references specification> <referencing columns> ::= <reference column list> <module contents> ::= <declare cursor> | <dynamic declare cursor> | <procedure> <declare cursor> ::= DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR FOR <cursor specification> <cursor name> ::= <identifier> <cursor specification> ::= <query expression> [ <order by clause> ] [ <updatability clause> ] <order by clause> ::= ORDER BY <sort specification list> <sort specification list> ::= <sort specification> [ ( <comma> <sort specification> )... ] <sort specification> ::= <sort key> [ <collate clause> ] [ <ordering specification> ] <sort key> ::= <column name> | <unsigned integer> <ordering specification> ::= ASC | DESC <updatability clause> ::= FOR ( READ ONLY | UPDATE [ OF <column name list> ] ) <dynamic declare cursor> ::= DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR FOR <statement name> <statement name> ::= <identifier> <procedure> ::= PROCEDURE <procedure name> <parameter declaration list> <semicolon> <SQL procedure statement> <semicolon> <procedure name> ::= <identifier> <parameter declaration list> ::= <left paren> <parameter declaration> [ ( <comma> <parameter declaration> )... ] <right paren> | <parameter declaration>... <parameter declaration> ::= <parameter name> <data type> | <status parameter> <status parameter> ::= SQLCODE | SQLSTATE <SQL procedure statement> ::= <SQL schema statement> | <SQL data statement> | <SQL transaction statement> | <SQL connection statement> | <SQL session statement> | <SQL dynamic statement> | <SQL diagnostics statement> <SQL schema statement> ::= <SQL schema definition statement> | <SQL schema manipulation statement> <SQL schema definition statement> ::= <schema definition> | <table definition> | <view definition> | <grant statement> | <domain definition> | <character set definition> | <collation definition> | <translation definition> | <assertion definition> <schema definition> ::= CREATE SCHEMA <schema name clause> [ <schema character set specification> ] [ <schema element>... ] <schema name clause> ::= <schema name> | AUTHORIZATION <schema authorization identifier> | <schema name> AUTHORIZATION <schema authorization identifier> <schema authorization identifier> ::= <authorization identifier> <schema character set specification> ::= DEFAULT CHARACTER SET <character set specification> <schema element> ::= <domain definition> | <table definition> | <view definition> | <grant statement> | <assertion definition> | <character set definition> | <collation definition> | <translation definition> <domain definition> ::= CREATE DOMAIN <domain name> [ AS ] <data type> [ <default clause> ] [ <domain constraint>... ] [ <collate clause> ] <domain constraint> ::= [ <constraint name definition> ] <check constraint definition> [ <constraint attributes> ] <table definition> ::= CREATE [ ( GLOBAL | LOCAL ) TEMPORARY ] TABLE <table name> <table element list> [ ON COMMIT ( DELETE | PRESERVE ) ROWS ] <view definition> ::= CREATE VIEW <table name> [ <left paren> <view column list> <right paren> ] AS <query expression> [ WITH [ <levels clause> ] CHECK OPTION ] <view column list> ::= <column name list> <levels clause> ::= CASCADED | LOCAL <grant statement> ::= GRANT <privileges> ON <object name> TO <grantee> [ ( <comma> <grantee> )... ] [ WITH GRANT OPTION ] <privileges> ::= ALL PRIVILEGES | <action list> <action list> ::= <action> [ ( <comma> <action> )... ] <action> ::= SELECT | DELETE | INSERT [ <left paren> <privilege column list> <right paren> ] | UPDATE [ <left paren> <privilege column list> <right paren> ] | REFERENCES [ <left paren> <privilege column list> <right paren> ] | USAGE <privilege column list> ::= <column name list> <object name> ::= [ TABLE ] <table name> | DOMAIN <domain name> | COLLATION <collation name> | CHARACTER SET <character set name> | TRANSLATION <translation name> <grantee> ::= PUBLIC | <authorization identifier> <assertion definition> ::= CREATE ASSERTION <constraint name> <assertion check> [ <constraint attributes> ] <assertion check> ::= CHECK <left paren> <search condition> <right paren> <character set definition> ::= CREATE CHARACTER SET <character set name> [ AS ] <character set source> [ <collate clause> | <limited collation definition> ] <character set source> ::= GET <existing character set name> <existing character set name> ::= <standard character repertoire name> | <implementation-defined character repertoire name> | <schema character set name> <schema character set name> ::= <character set name> <limited collation definition> ::= COLLATION FROM <collation source> <collation source> ::= <collating sequence definition> | <translation collation> <collating sequence definition> ::= <external collation> | <schema collation name> | DESC <left paren> <collation name> <right paren> | DEFAULT <external collation> ::= EXTERNAL <left paren> <quote> <external collation name> <quote> <right paren> <external collation name> ::= <standard collation name> | <implementation-defined collation name> <standard collation name> ::= <collation name> <implementation-defined collation name> ::= <collation name> <schema collation name> ::= <collation name> <translation collation> ::= TRANSLATION <translation name> [ THEN COLLATION <collation name> ] <collation definition> ::= CREATE COLLATION <collation name> FOR <character set specification> FROM <collation source> [ <pad attribute> ] <pad attribute> ::= NO PAD | PAD SPACE <translation definition> ::= CREATE TRANSLATION <translation name> FOR <source character set specification> TO <target character set specification> FROM <translation source> <source character set specification> ::= <character set specification> <target character set specification> ::= <character set specification> <translation source> ::= <translation specification> <translation specification> ::= <external translation> | IDENTITY | <schema translation name> <external translation> ::= EXTERNAL <left paren> <quote> <external translation name> <quote> <right paren> <external translation name> ::= <standard translation name> | <implementation-defined translation name> <standard translation name> ::= <translation name> <implementation-defined translation name> ::= <translation name> <schema translation name> ::= <translation name> <SQL schema manipulation statement> ::= <drop schema statement> | <alter table statement> | <drop table statement> | <drop view statement> | <revoke statement> | <alter domain statement> | <drop domain statement> | <drop character set statement> | <drop collation statement> | <drop translation statement> | <drop assertion statement> <drop schema statement> ::= DROP SCHEMA <schema name> <drop behavior> <drop behavior> ::= CASCADE | RESTRICT <alter table statement> ::= ALTER TABLE <table name> <alter table action> <alter table action> ::= <add column definition> | <alter column definition> | <drop column definition> | <add table constraint definition> | <drop table constraint definition> <add column definition> ::= ADD [ COLUMN ] <column definition> <alter column definition> ::= ALTER [ COLUMN ] <column name> <alter column action> <alter column action> ::= <set column default clause> | <drop column default clause> <set column default clause> ::= SET <default clause> <drop column default clause> ::= DROP DEFAULT <drop column definition> ::= DROP [ COLUMN ] <column name> <drop behavior> <add table constraint definition> ::= ADD <table constraint definition> <drop table constraint definition> ::= DROP CONSTRAINT <constraint name> <drop behavior> <drop table statement> ::= DROP TABLE <table name> <drop behavior> <drop view statement> ::= DROP VIEW <table name> <drop behavior> <revoke statement> ::= REVOKE [ GRANT OPTION FOR ] <privileges> ON <object name> FROM <grantee> [ ( <comma> <grantee> )... ] <drop behavior> <alter domain statement> ::= ALTER DOMAIN <domain name> <alter domain action> <alter domain action> ::= <set domain default clause> | <drop domain default clause> | <add domain constraint definition> | <drop domain constraint definition> <set domain default clause> ::= SET <default clause> <drop domain default clause> ::= DROP DEFAULT <add domain constraint definition> ::= ADD <domain constraint> <drop domain constraint definition> ::= DROP CONSTRAINT <constraint name> <drop domain statement> ::= DROP DOMAIN <domain name> <drop behavior> <drop character set statement> ::= DROP CHARACTER SET <character set name> <drop collation statement> ::= DROP COLLATION <collation name> <drop translation statement> ::= DROP TRANSLATION <translation name> <drop assertion statement> ::= DROP ASSERTION <constraint name> <SQL data statement> ::= <open statement> | <fetch statement> | <close statement> | <select statement: single row> | <SQL data change statement> <open statement> ::= OPEN <cursor name> <fetch statement> ::= FETCH [ [ <fetch orientation> ] FROM ] <cursor name> INTO <fetch target list> <fetch orientation> ::= NEXT | PRIOR | FIRST | LAST | ( ABSOLUTE | RELATIVE ) <simple value specification> <simple value specification> ::= <parameter name> | <embedded variable name> | <literal> <fetch target list> ::= <target specification> [ ( <comma> <target specification> )... ] <target specification> ::= <parameter specification> | <variable specification> <close statement> ::= CLOSE <cursor name> <select statement: single row> ::= SELECT [ <set quantifier> ] <select list> INTO <select target list> <table expression> <select target list> ::= <target specification> [ ( <comma> <target specification> )... ] <SQL data change statement> ::= <delete statement: positioned> | <delete statement: searched> | <insert statement> | <update statement: positioned> | <update statement: searched> <delete statement: positioned> ::= DELETE FROM <table name> WHERE CURRENT OF <cursor name> <delete statement: searched> ::= DELETE FROM <table name> [ WHERE <search condition> ] <insert statement> ::= INSERT INTO <table name> <insert columns and source> <insert columns and source> ::= [ <left paren> <insert column list> <right paren> ] <query expression> | DEFAULT VALUES <insert column list> ::= <column name list> <update statement: positioned> ::= UPDATE <table name> SET <set clause list> WHERE CURRENT OF <cursor name> <set clause list> ::= <set clause> [ ( <comma> <set clause> )... ] <set clause> ::= <object column> <equals operator> <update source> <object column> ::= <column name> <update source> ::= <value expression> | <null specification> | DEFAULT <update statement: searched> ::= UPDATE <table name> SET <set clause list> [ WHERE <search condition> ] <SQL transaction statement> ::= <set transaction statement> | <set constraints mode statement> | <commit statement> | <rollback statement> <set transaction statement> ::= SET TRANSACTION <transaction mode> [ ( <comma> <transaction mode> )... ] <transaction mode> ::= <isolation level> | <transaction access mode> | <diagnostics size> <isolation level> ::= ISOLATION LEVEL <level of isolation> <level of isolation> ::= READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE <transaction access mode> ::= READ ONLY | READ WRITE <diagnostics size> ::= DIAGNOSTICS SIZE <number of conditions> <number of conditions> ::= <simple value specification> <set constraints mode statement> ::= SET CONSTRAINTS <constraint name list> ( DEFERRED | IMMEDIATE ) <constraint name list> ::= ALL | <constraint name> [ ( <comma> <constraint name> )... ] <commit statement> ::= COMMIT [ WORK ] <rollback statement> ::= ROLLBACK [ WORK ] <SQL connection statement> ::= <connect statement> | <set connection statement> | <disconnect statement> <connect statement> ::= CONNECT TO <connection target> <connection target> ::= <SQL-server name> [ AS <connection name> ] correspondence with Tony Gordon) [ USER <user name> ] | DEFAULT <SQL-server name> ::= <simple value specification> <connection name> ::= <simple value specification> <user name> ::= <simple value specification> <set connection statement> ::= SET CONNECTION <connection object> <connection object> ::= DEFAULT | <connection name> <disconnect statement> ::= DISCONNECT <disconnect object> <disconnect object> ::= <connection object> | ALL | CURRENT <SQL session statement> ::= <set catalog statement> | <set schema statement> | <set names statement> | <set session authorization identifier statement> | <set local time zone statement> <set catalog statement> ::= SET CATALOG <value specification> <value specification> ::= <literal> | <general value specification> <set schema statement> ::= SET SCHEMA <value specification> <set names statement> ::= SET NAMES <value specification> <set session authorization identifier statement> ::= SET SESSION AUTHORIZATION <value specification> <set local time zone statement> ::= SET TIME ZONE <set time zone value> <set time zone value> ::= <interval value expression> | LOCAL <SQL dynamic statement> ::= <system descriptor statement> | <prepare statement> | <deallocate prepared statement> | <describe statement> | <execute statement> | <execute immediate statement> | <SQL dynamic data statement> <system descriptor statement> ::= <allocate descriptor statement> | <deallocate descriptor statement> | <set descriptor statement> | <get descriptor statement> <allocate descriptor statement> ::= ALLOCATE DESCRIPTOR <descriptor name> [ WITH MAX <occurrences> ] <descriptor name> ::= [ <scope option> ] <simple value specification> <scope option> ::= GLOBAL | LOCAL <occurrences> ::= <simple value specification> <deallocate descriptor statement> ::= DEALLOCATE DESCRIPTOR <descriptor name> <set descriptor statement> ::= SET DESCRIPTOR <descriptor name> <set descriptor information> <set descriptor information> ::= <set count> | VALUE <item number> <set item information> [ ( <comma> <set item information> )... ] <set count> ::= COUNT <equals operator> <simple value specification 1> <simple value specification 1> ::= <simple value specification> <item number> ::= <simple value specification> <set item information> ::= <descriptor item name> <equals operator> <simple value specification 2> <descriptor item name> ::= TYPE | LENGTH | OCTET_LENGTH | RETURNED_LENGTH | RETURNED_OCTET_LENGTH | PRECISION | SCALE | DATETIME_INTERVAL_CODE | DATETIME_INTERVAL_PRECISION | NULLABLE | INDICATOR | DATA | NAME | UNNAMED | COLLATION_CATALOG | COLLATION_SCHEMA | COLLATION_NAME | CHARACTER_SET_CATALOG | CHARACTER_SET_SCHEMA | CHARACTER_SET_NAME <simple value specification 2> ::= <simple value specification> <item number> ::= <simple value specification> <get descriptor statement> ::= GET DESCRIPTOR <descriptor name> <get descriptor information> <get descriptor information> ::= <get count> | VALUE <item number> <get item information> [ ( <comma> <get item information> )... ] <get count> ::= <simple target specification 1> <equals operator> COUNT <simple target specification 1> ::= <simple target specification> <simple target specification> ::= <parameter name> | <embedded variable name> <get item information> ::= <simple target specification 2> <equals operator> <descriptor item name>> <simple target specification 2> ::= <simple target specification> <prepare statement> ::= PREPARE <SQL statement name> FROM <SQL statement variable> <SQL statement name> ::= <statement name> | <extended statement name> <extended statement name> ::= [ <scope option> ] <simple value specification> <SQL statement variable> ::= <simple value specification> <deallocate prepared statement> ::= DEALLOCATE PREPARE <SQL statement name> <describe statement> ::= <describe input statement> | <describe output statement> <describe input statement> ::= DESCRIBE INPUT <SQL statement name> <using descriptor> <using descriptor> ::= ( USING | INTO ) SQL DESCRIPTOR <descriptor name> <describe output statement> ::= DESCRIBE [ OUTPUT ] <SQL statement name> <using descriptor> <execute statement> ::= EXECUTE <SQL statement name> [ <result using clause> ] [ <parameter using clause> ] <result using clause> ::= <using clause> <using clause> ::= <using arguments> | <using descriptor> <using arguments> ::= ( USING | INTO ) <argument> [ ( <comma> <argument> )... ] <argument> ::= <target specification> <parameter using clause> ::= <using clause> <execute immediate statement> ::= EXECUTE IMMEDIATE <SQL statement variable> <SQL dynamic data statement> ::= <allocate cursor statement> | <dynamic open statement> | <dynamic fetch statement> | <dynamic close statement> | <dynamic delete statement: positioned> | <dynamic update statement: positioned> <allocate cursor statement> ::= ALLOCATE <extended cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR FOR <extended statement name> <extended cursor name> ::= [ <scope option> ] <simple value specification> <dynamic open statement> ::= OPEN <dynamic cursor name> [ <using clause> ] <dynamic cursor name> ::= <cursor name> | <extended cursor name> <dynamic fetch statement> ::= FETCH [ [ <fetch orientation> ] FROM ] <dynamic cursor name> <using clause> <dynamic close statement> ::= CLOSE <dynamic cursor name> <dynamic delete statement: positioned> ::= DELETE FROM <table name> WHERE CURRENT OF <dynamic cursor name> <dynamic update statement: positioned> ::= UPDATE <table name> SET <set clause> [ ( <comma> <set clause> )... ] WHERE CURRENT OF <dynamic cursor name> <SQL diagnostics statement> ::= <get diagnostics statement> <get diagnostics statement> ::= GET DIAGNOSTICS <sql diagnostics information> <sql diagnostics information> ::= <statement information> | <condition information> <statement information> ::= <statement information item> [ ( <comma> <statement information item> )... ] <statement information item> ::= <simple target specification> <equals operator> <statement information item name> <statement information item name> ::= NUMBER | MORE | COMMAND_FUNCTION | DYNAMIC_FUNCTION | ROW_COUNT <condition information> ::= EXCEPTION <condition number> <condition information item> [ ( <comma> <condition information item> )... ] <condition number> ::= <simple value specification> <condition information item> ::= <simple target specification> <equals operator> <condition information item name> <condition information item name> ::= CONDITION_NUMBER | RETURNED_SQLSTATE | CLASS_ORIGIN | SUBCLASS_ORIGIN | SERVER_NAME | CONNECTION_NAME | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | CATALOG_NAME | SCHEMA_NAME | TABLE_NAME | COLUMN_NAME | CURSOR_NAME | MESSAGE_TEXT | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH <embedded SQL host program> ::= <embedded SQL Ada program> | <embedded SQL C program> | <embedded SQL COBOL program> | <embedded SQL Fortran program> | <embedded SQL MUMPS program> | <embedded SQL Pascal program> | <embedded SQL PL/I program> <embedded SQL Ada program> ::= !! <EMPHASIS>(See the Syntax Rules.) <embedded SQL C program> ::= !! <EMPHASIS>(See the Syntax Rules.) <embedded SQL COBOL program> ::= !! <EMPHASIS>(See the Syntax Rules.) <embedded SQL Fortran program> ::= !! <EMPHASIS>(See the Syntax Rules.) <embedded SQL MUMPS program> ::= !! <EMPHASIS>(See the Syntax Rules.) <embedded SQL Pascal program> ::= !! <EMPHASIS>(See the Syntax Rules.) <embedded SQL PL/I program> ::= !! <EMPHASIS>(See the Syntax Rules.) <embedded SQL declare section> ::= <embedded SQL begin declare> [ <embedded character set declaration> ] [ <host variable definition>... ] <embedded SQL end declare> | <embedded SQL MUMPS declare> <embedded SQL begin declare> ::= <SQL prefix> BEGIN DECLARE SECTION [ <SQL terminator> ] <SQL prefix> ::= EXEC SQL | <ampersand>SQL<left paren> <SQL terminator> ::= END-EXEC | <semicolon> | <right paren> <embedded character set declaration> ::= SQL NAMES ARE <character set specification> <host variable definition> ::= <Ada variable definition> | <C variable definition> | <COBOL variable definition> | <Fortran variable definition> | <MUMPS variable definition> | <Pascal variable definition> | <PL/I variable definition> <Ada variable definition> ::= <Ada host identifier> [ ( <comma> <Ada host identifier> )... ] : <Ada type specification> [ <Ada initial value> ] <Ada type specification> ::= <Ada qualified type specification> | <Ada unqualified type specification> <Ada qualified type specification> ::= SQL_STANDARD.CHAR [ CHARACTER SET [ IS ] <character set specification> ] <left paren> 1 <double period> <length> <right paren> | SQL_STANDARD.BIT <left paren> 1 <double period> <length> <right paren> | SQL_STANDARD.SMALLINT | SQL_STANDARD.INT | SQL_STANDARD.REAL | SQL_STANDARD.DOUBLE_PRECISION | SQL_STANDARD.SQLCODE_TYPE | SQL_STANDARD.SQLSTATE_TYPE | SQL_STANDARD.INDICATOR_TYPE <Ada unqualified type specification> ::= CHAR <left paren> 1 <double period> <length> <right paren> | BIT <left paren> 1 <double period> <length> <right paren> | SMALLINT | INT | REAL | DOUBLE_PRECISION | SQLCODE_TYPE | SQLSTATE_TYPE | INDICATOR_TYPE <Ada initial value> ::= <Ada assignment operator> <character representation>... <Ada assignment operator> ::= <colon><equals operator> <C variable definition> ::= [ <C storage class> ] [ <C class modifier> ] <C variable specification> <semicolon> <C storage class> ::= auto | extern | static <C class modifier> ::= const | volatile <C variable specification> ::= <C numeric variable> | <C character variable> | <C derived variable> <C numeric variable> ::= ( long | short | float | double ) <C host identifier> [ <C initial value> ] [ ( <comma> <C host identifier> [ <C initial value> ] )... ] <C initial value> ::= <equals operator> <character representation>... <C character variable> ::= char [ CHARACTER SET [ IS ] <character set specification> ] <C host identifier> <C array specification> [ <C initial value> ] [ ( <comma> <C host identifier> <C array specification> [ <C initial value> ] )... ] <C array specification> ::= <left bracket> <length> <right bracket> <C derived variable> ::= <C VARCHAR variable> | <C bit variable> <C VARCHAR variable> ::= VARCHAR [ CHARACTER SET [ IS ] <character set specification> ] <C host identifier> <C array specification> [ <C initial value> ] [ ( <comma> <C host identifier> <C array specification> [ <C initial value> ] )... ] <C bit variable> ::= BIT <C host identifier> <C array specification> [ <C initial value> ] [ ( <comma> <C host identifier> <C array specification> [ <C initial value> ] )... ] <COBOL variable definition> ::= (01|77) <COBOL host identifier> <COBOL type specification> [ <character representation>... ] <period> <COBOL type specification> ::= <COBOL character type> | <COBOL bit type> | <COBOL numeric type> | <COBOL integer type> <COBOL character type> ::= [ CHARACTER SET [ IS ] <character set specification> ] ( PIC | PICTURE ) [ IS ] ( X [ <left paren> <length> <right paren> ] )... <COBOL bit type> ::= ( PIC | PICTURE ) [ IS ] ( B [ <left paren> <length> <right paren> ] )... <COBOL numeric type> ::= ( PIC | PICTURE ) [ IS ] S <COBOL nines specification> [ USAGE [ IS ] ] DISPLAY SIGN LEADING SEPARATE <COBOL nines specification> ::= <COBOL nines> [ V [ <COBOL nines> ] ] | V <COBOL nines> <COBOL nines> ::= ( 9 [ <left paren> <length> <right paren> ] )... <COBOL integer type> ::= <COBOL computational integer> | <COBOL binary integer> <COBOL computational integer> ::= ( PIC | PICTURE ) [ IS ] S<COBOL nines> [ USAGE [ IS ] ] ( COMP | COMPUTATIONAL ) <COBOL binary integer> ::= ( PIC | PICTURE ) [ IS ] S<COBOL nines> [ USAGE [ IS ] ] BINARY <Fortran variable definition> ::= <Fortran type specification> <Fortran host identifier> [ ( <comma> <Fortran host identifier> )... ] <Fortran type specification> ::= CHARACTER [ <asterisk> <length> ] [ CHARACTER SET [ IS ] <character set specification> ] | BIT [ <asterisk> <length> ] | INTEGER | REAL | DOUBLE PRECISION <MUMPS variable definition> ::= ( <MUMPS numeric variable> | <MUMPS character variable> ) <semicolon> <MUMPS numeric variable> ::= <MUMPS type specification> <MUMPS host identifier> [ ( <comma> <MUMPS host identifier> )... ] <MUMPS type specification> ::= INT | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ] | REAL <MUMPS character variable> ::= VARCHAR <MUMPS host identifier> <MUMPS length specification> [ ( <comma> <MUMPS host identifier> <MUMPS length specification> )... ] <MUMPS length specification> ::= <left paren> <length> <right paren> <Pascal variable definition> ::= <Pascal host identifier> [ ( <comma> <Pascal host identifier> )... ] <colon> <Pascal type specification> <semicolon> <Pascal type specification> ::= PACKED ARRAY <left bracket> 1 <double period> <length> <right bracket> OF CHAR [ CHARACTER SET [ IS ] <character set specification> ] | PACKED ARRAY <left bracket> 1 <double period> <length> <right bracket> OF BIT | INTEGER | REAL | CHAR [ CHARACTER SET [ IS ] <character set specification> ] | BIT <PL/I variable definition> ::= (DCL | DECLARE) ( <PL/I host identifier> | <left paren> <PL/I host identifier> [ ( <comma> <PL/I host identifier> )... ] <right paren> ) <PL/I type specification> [ <character representation>... ] <semicolon> <PL/I type specification> ::= ( CHAR | CHARACTER ) [ VARYING ] <left paren><length><right paren> [ CHARACTER SET [ IS ] <character set specification> ] | BIT [ VARYING ] <left paren><length><right paren> | <PL/I type fixed decimal> <left paren> <precision> [ <comma> <scale> ] <right paren> | <PL/I type fixed binary> [ <left paren> <precision> <right paren> ] | <PL/I type float binary> <left paren> <precision> <right paren> <PL/I type fixed decimal> ::= ( DEC | DECIMAL ) FIXED | FIXED ( DEC | DECIMAL ) <PL/I type fixed binary> ::= ( BIN | BINARY ) FIXED | FIXED ( BIN | BINARY ) <PL/I type float binary> ::= ( BIN | BINARY ) FLOAT | FLOAT ( BIN | BINARY ) <embedded SQL end declare> ::= <SQL prefix> END DECLARE SECTION [ <SQL terminator> ] <embedded SQL MUMPS declare> ::= <SQL prefix> BEGIN DECLARE SECTION [ <embedded character set declaration> ] [ <host variable definition>... ] END DECLARE SECTION <SQL terminator> <embedded SQL statement> ::= <SQL prefix> <statement or declaration> [ <SQL terminator> ] <statement or declaration> ::= <declare cursor> | <dynamic declare cursor> | <temporary table declaration> | <embedded exception declaration> | <SQL procedure statement> <embedded exception declaration> ::= WHENEVER <condition> <condition action> <condition> ::= SQLERROR | NOT FOUND <condition action> ::= CONTINUE | <go to> <go to> ::= ( GOTO | GO TO ) <goto target> <goto target> ::= <host label identifier> | <unsigned integer> | <host PL/I label variable> <host label identifier> ::= !!<EMPHASIS>(See the Syntax Rules.) <host PL/I label variable> ::= !!<EMPHASIS>(See the Syntax Rules.) <preparable statement> ::= <preparable SQL data statement> | <preparable SQL schema statement> | <preparable SQL transaction statement> | <preparable SQL session statement> | <preparable implementation-defined statement> <preparable SQL data statement> ::= <delete statement: searched> | <dynamic single row select statement> | <insert statement> | <dynamic select statement> | <update statement: searched> | <preparable dynamic delete statement: positioned> | <preparable dynamic update statement: positioned> <dynamic single row select statement> ::= <query specification> <dynamic select statement> ::= <cursor specification> <preparable dynamic delete statement: positioned> ::= DELETE [ FROM <table name> ] WHERE CURRENT OF <cursor name> <preparable dynamic update statement: positioned> ::= UPDATE [ <table name> ] SET <set clause list> WHERE CURRENT OF <cursor name> <preparable SQL schema statement> ::= <SQL schema statement> <preparable SQL transaction statement> ::= <SQL transaction statement> <preparable SQL session statement> ::= <SQL session statement> <preparable implementation-defined statement> ::= !! <EMPHASIS>(See the Syntax Rules.) <direct SQL statement> ::= <directly executable statement> <semicolon> <directly executable statement> ::= <direct SQL data statement> | <SQL schema statement> | <SQL transaction statement> | <SQL connection statement> | <SQL session statement> | <direct implementation-defined statement> <direct SQL data statement> ::= <delete statement: searched> | <direct select statement: multiple rows> | <insert statement> | <update statement: searched> | <temporary table declaration> <direct select statement: multiple rows> ::= <query expression> [ <order by clause> ] <direct implementation-defined statement> ::= !!<EMPHASIS>(See the Syntax Rules) <SQL object identifier> ::= <SQL provenance> <SQL variant> <SQL provenance> ::= <arc1> <arc2> <arc3> <arc1> ::= iso | 1 | iso <left paren> 1 <right paren> <arc2> ::= standard | 0 | standard <left paren> 0 <right paren> <arc3> ::= 9075 <SQL variant> ::= <SQL edition> <SQL conformance> <SQL edition> ::= <1987> | <1989> | <1992> <1987> ::= 0 | edition1987 <left paren> 0 <right paren> <1989> ::= <1989 base> <1989 package> <1989 base> ::= 1 | edition1989 <left paren> 1 <right paren> <1989 package> ::= <integrity no> | <integrity yes> <integrity no> ::= 0 | IntegrityNo <left paren> 0 <right paren> <integrity yes> ::= 1 | IntegrityYes <left paren> 1 <right paren> <1992> ::= 2 | edition1992 <left paren> 2 <right paren> <SQL conformance> ::= <low> | <intermediate> | <high> <low> ::= 0 | Low <left paren> 0 <right paren> <intermediate> ::= 1 | Intermediate <left paren> 1 <right paren> <high> ::= 2 | High <left paren> 2 <right paren> </verb></tscreen> <sect1> Syntaxe de l'ANSI/ISO SQL 1998 <p> <tscreen><verb> Spécification de la syntaxe SQL ANSI/ISO SQL 1998 également appelé SQL-3 - Voici une copie de SQL3 bnf. SQL3 est un sur-ensemble de SQL-92 [qui est un sur-ensemble de SQL-89 niveau 2]. SQL3 n'est pas encore un standard, alors que SQL-92 en est un. ENTRY LEVEL SQL-92 représente l'état de l'implantation pour la plupart des vendeurs. Il n'y a que peu de différences entre SQL-92 ENTRY LEVEL et SQL-89 Niveau II, mais deux d'entre elles sont très importantes: - Les identificateurs délimités - Le traitement de l'option WITH CHECK sur les vues CASCADE par défaut. Dans SQL-89 la valeur par défaut était [en réalité] LOCAL. pour le langage, et effectuées aux environs du 1-SEP-1993 15:13:55.88. La version BNF spécifique incluse ici correspond à : ANSI et SQL3-seulement. <SQL terminal character> ::= <SQL language character> <SQL language character> ::= <simple Latin letter> | <digit> | <SQL special character> <simple Latin letter> ::= <simple Latin upper case letter> | <simple Latin lower case letter> <simple Latin upper case letter> ::= A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z <simple Latin lower case letter> ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 <SQL special character> ::= <space> | <double quote> | <percent> | <ampersand> | <quote> | <left paren> | <right paren> | <asterisk> | <plus sign> | <comma> | <minus sign> | <period> | <solidus> | <colon> | <semicolon> | <less than operator> | <equals operator> | <greater than operator> | <question mark> | <left bracket> | <right bracket> | <circumflex> | <underscore> | <vertical bar> <space> ::= !! <EMPHASIS>(space character in character set in use) <double quote> ::= " <percent> ::= % <ampersand> ::= & <quote> ::= ' <left paren> ::= ( <right paren> ::= ) <asterisk> ::= * <plus sign> ::= + <comma> ::= , <minus sign> ::= - <period> ::= . <solidus> ::= / <colon> ::= : <semicolon> ::= ; <less than operator> ::= < <equals operator> ::= = <greater than operator> ::= > <question mark> ::= ? <left bracket> ::= [ <right bracket> ::= ] <circumflex> ::= ^ <underscore> ::= _ <vertical bar> ::= | <separator> ::= ( <comment> | <space> | <newline> )... <comment> ::= <simple comment> | <bracketed comment> <simple comment> ::= <simple comment introducer> [ <comment character>... ] <newline> <simple comment introducer> ::= <minus sign><minus sign>[<minus sign>...] <comment character> ::= <nonquote character> | <quote> <nonquote character> ::= !! <EMPHASIS>(See the Syntax Rules.) <newline> ::= !! <EMPHASIS>(implementation-defined end-of-line indicator) <bracketed comment> ::= !! (<EMPHASIS>(See the Syntax Rules)) <bracketed comment introducer> <bracketed comment contents> <bracketed comment terminator> <bracketed comment introducer> ::= <solidus><asterisk> <bracketed comment contents> ::= [ ( <comment character> | <separator> )... ] <bracketed comment terminator> ::= <asterisk><solidus> <token> ::= <nondelimiter token> | <delimiter token> <nondelimiter token> ::= <regular identifier> | <key word> | <unsigned numeric literal> | <national character string literal> | <bit string literal> | <hex string literal> | <user-defined operator symbol> <regular identifier> ::= <identifier body> <identifier body> ::= <identifier start> [ ( <underscore> | <identifier part> )... ] <identifier start> ::= !! <EMPHASIS>(See the Syntax Rules) <identifier part> ::= <identifier start> | <digit> <key word> ::= <reserved word> | <non-reserved word> <reserved word> ::= ABSOLUTE | ACTION | ACTOR | ADD | AFTER | ALIAS | ALL | ALLOCATE | ALTER | AND | ANY | ARE | AS | ASC | ASSERTION | ASYNC | AT | ATTRIBUTES | AUTHORIZATION | AVG | BEFORE | BEGIN | BETWEEN | BIT | BIT_LENGTH | BOOLEAN | BOTH | BREADTH | BY | CASCADE | CASCADED | CASE | CAST | CATALOG | CHAR | CHARACTER | CHAR_LENGTH | CHARACTER_LENGTH | CHECK | CLASS | CLOSE | COALESCE | COLLATE | COLLATION | COLUMN | COMMIT | COMPLETION | CONNECT | CONNECTION | CONSTRAINT | CONSTRAINTS | CONSTRUCTOR | CONTINUE | CONVERT | CORRESPONDING | COUNT | CREATE | CROSS | CURRENT | CURRENT_DATE | CURRENT_PATH | CURRENT_TIME | CURRENT_TIMESTAMP | CURRENT_USER | CURSOR | CYCLE | DATA | DATE | DAY | DEALLOCATE | DEC | DECIMAL | DECLARE | DEFAULT | DEFERRABLE | DEFERRED | DELETE | DEPTH | DESC | DESCRIBE | DESCRIPTOR | DESIGNATOR | DESTROY | DESTRUCTOR | DICTIONARY | DIAGNOSTICS | DISCONNECT | DISTINCT | DOMAIN | DOUBLE | DROP | EACH | ELEMENT | ELSE | END | END-EXEC | EQUALS | ESCAPE | EXCEPT | EXEC | EXECUTE | EXISTS | EXTERNAL | EXTRACT | FACTOR | FALSE | FETCH | FIRST | FLOAT | FOR | FOREIGN | FOUND | FROM | FULL | FUNCTION | GENERAL | GET | GLOBAL | GO | GOTO | GRANT | GROUP | HAVING | HOUR | IDENTITY | IGNORE | IMMEDIATE | IN | INDICATOR | INITIALLY | INNER | INOUT | INPUT | INSENSITIVE | INSERT | INSTEAD | INT | INTEGER | INTERSECT | INTERVAL | INTO | IS | ISOLATION | JOIN | KEY | LANGUAGE | LAST | LEADING | LEFT | LESS | LEVEL | LIKE | LIMIT | LIST | LOCAL | LOWER | MATCH | MAX | MIN | MINUTE | MODIFY | MODULE | MONTH | MOVE | MULTISET | NAMES | NATIONAL | NATURAL | NCHAR | NEW | NEW_TABLE | NEXT | NO | NONE | NOT| NULL | NULLIF | NUMERIC | OCTET_LENGTH | OF | OFF | OID | OLD | OLD_TABLE | ON | ONLY | OPEN | OPERATION | OPERATOR | OPERATORS | OPTION | OR | ORDER | OUT | OUTER | OUTPUT | OVERLAPS | PAD | PARAMETERS | PARTIAL | PATH | PENDANT | POSITION | POSTFIX | PRECISION | PREFIX | PREORDER | PREPARE | PRESERVE | PRIMARY | PRIOR | PRIVATE | PRIVILEGES | PROCEDURE | PROTECTED | PUBLIC | READ | REAL | RECURSIVE | REFERENCES | REFERENCING | RELATIVE | REPRESENTATION | RESTRICT | REVOKE | RIGHT | ROLE | ROLLBACK | ROUTINE | ROW | ROWS | SAVEPOINT | SCHEMA | SCROLL | SEARCH | SECOND | SECTION | SELECT | SENSITIVE | SEQUENCE | SESSION | SESSION_USER | SET | SIMILAR | SIZE | SMALLINT | SOME | SPACE | SPECIFIC | SQL | SQLCODE | SQLERROR | SQLEXCEPTION | SQLSTATE | SQLWARNING | START | STATE | STRUCTURE | SUBSTRING | SUM | SYMBOL | SYSTEM_USER | TABLE | TEMPLATE | TEMPORARY | TERM | TEST | THAN | THEN | THERE | TIME | TIMESTAMP | TIMEZONE_HOUR | TIMEZONE_MINUTE | TO | TRAILING | TRANSACTION | TRANSLATE | TRANSLATION | TRIGGER | TRIM | TRUE | TYPE | UNDER | UNION | UNIQUE | UNKNOWN | UPDATE | UPPER | USAGE | USER | USING | VALUE | VALUES | VARCHAR | VARIABLE | VARIANT | VARYING | VIEW | VIRTUAL | VISIBLE | WAIT | WHEN | WHENEVER | WHERE | WITH | WITHOUT | WORK | WRITE | YEAR | ZONE <non-reserved word> ::= ADA | C | CATALOG_NAME | CHAIN | CHARACTER_SET_CATALOG | CHARACTER_SET_NAME | CHARACTER_SET_SCHEMA | CLASS_ORIGIN | COBOL | COLLATION_CATALOG | COLLATION_NAME | COLLATION_SCHEMA | COLUMN_NAME | COMMAND_FUNCTION | COMMITTED | CONDITION_NUMBER | CONNECTION_NAME | CONSTRAINT_CATALOG | CONSTRAINT_NAME | CONSTRAINT_SCHEMA | CURSOR_NAME | DATA | DATETIME_INTERVAL_CODE | DATETIME_INTERVAL_PRECISION | DYNAMIC_FUNCTION | FORTRAN | HOLD | KEY_MEMBER | KEY_TYPE | LENGTH | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH | MESSAGE_TEXT | MORE | MUMPS | NAME | NULLABLE | NUMBER | PASCAL | PLI | REPEATABLE | RETURNED_LENGTH | RETURNED_OCTET_LENGTH | RETURNED_SQLSTATE | ROUTINE_CATALOG | ROUTINE_NAME | ROUTINE_SCHEMA | ROW_COUNT | SCALE | SCHEMA_NAME | SERIALIZABLE | SERVER_NAME | SPECIFIC_NAME | SUBCLASS_ORIGIN | TABLE_NAME | TYPE | UNCOMMITTED | UNNAMED <unsigned numeric literal> ::= <exact numeric literal> | <approximate numeric literal> <exact numeric literal> ::= <unsigned integer> [ <period> [ <unsigned integer> ] ] | <period> <unsigned integer> <unsigned integer> ::= <digit>... <approximate numeric literal> ::= <mantissa> E <exponent> <mantissa> ::= <exact numeric literal> <exponent> ::= <signed integer> <signed integer> ::= [ <sign> ] <unsigned integer> <sign> ::= <plus sign> | <minus sign> <national character string literal> ::= N <quote> [ <character representation>... ] <quote> [ ( <separator> <quote> [ <character representation>... ] <quote> )... ] <character representation> ::= <nonquote character> | <quote symbol> <quote symbol> ::= <quote><quote> <bit string literal> ::= B <quote> [ <bit>... ] <quote> [ ( <separator> <quote> [ <bit>... ] <quote> )... ] <bit> ::= 0 | 1 <hex string literal> ::= X <quote> [ <hexit>... ] <quote> [ ( <separator> <quote> [ <hexit>... ] <quote> )... ] <hexit> ::= <digit> | A | B | C | D | E | F | a | b | c | d | e | f <user-defined operator symbol> ::= !! <EMPHASIS>(See the Syntax Rules) <delimiter token> ::= <character string literal> | <date string> | <time string> | <timestamp string> | <interval string> | <delimited identifier> | <SQL special character> | <not equals operator> | <greater than or equals operator> | <less than or equals operator> | <concatenation operator> | <double period> | <double colon> | <assignment operator> | <left bracket> | <right bracket> <character string literal> ::= [ <introducer><character set specification> ] <quote> [ <character representation>... ] <quote> [ ( <separator> <quote> [ <character representation>... ] <quote> )... ] <introducer> ::= <underscore> <character set specification> ::= <standard character repertoire name> | <implementation-defined character repertoire name> | <user-defined character repertoire name> | <standard universal character form-of-use name> | <implementation-defined universal character form-of-use name> <standard character repertoire name> ::= <character set name> <character set name> ::= [ <schema name> <period> ] <SQL language identifier> <schema name> ::= [ <catalog name> <period> ] <unqualified schema name> <catalog name> ::= <identifier> <identifier> ::= [ <introducer><character set specification> ] <actual identifier> <actual identifier> ::= <regular identifier> | <delimited identifier> <delimited identifier> ::= <double quote> <delimited identifier body> <double quote> <delimited identifier body> ::= <delimited identifier part>... <delimited identifier part> ::= <nondoublequote character> | <doublequote symbol> <nondoublequote character> ::= !! <EMPHASIS>(See the Syntax Rules) <doublequote symbol> ::= <double quote><double quote> <unqualified schema name> ::= <identifier> <SQL language identifier> ::= <SQL language identifier start> [ ( <underscore> | <SQL language identifier part> )... ] <SQL language identifier start> ::= <simple Latin letter> <SQL language identifier part> ::= <simple Latin letter> | <digit> <implementation-defined character repertoire name> ::= <character set name> <user-defined character repertoire name> ::= <character set name> <standard universal character form-of-use name> ::= <character set name> <implementation-defined universal character form-of-use name> ::= <character set name> <date string> ::= <quote> <date value> <quote> <date value> ::= <years value> <minus sign> <months value> <minus sign> <days value> <years value> ::= <datetime value> <datetime value> ::= <unsigned integer> <months value> ::= <datetime value> <days value> ::= <datetime value> <time string> ::= <quote> <time value> [ <time zone interval> ] <quote> <time value> ::= <hours value> <colon> <minutes value> <colon> <seconds value> <hours value> ::= <datetime value> <minutes value> ::= <datetime value> <seconds value> ::= <seconds integer value> [ <period> [ <seconds fraction> ] ] <seconds integer value> ::= <unsigned integer> <seconds fraction> ::= <unsigned integer> <time zone interval> ::= <sign> <hours value> <colon> <minutes value> <timestamp string> ::= <quote> <date value> <space> <time value> [ <time zone interval> ] <quote> <interval string> ::= <quote> ( <year-month literal> | <day-time literal> ) <quote> <year-month literal> ::= <years value> | [ <years value> <minus sign> ] <months value> <day-time literal> ::= <day-time interval> | <time interval> <day-time interval> ::= <days value> [ <space> <hours value> [ <colon> <minutes value> [ <colon> <seconds value> ] ] ] <time interval> ::= <hours value> [ <colon> <minutes value> [ <colon> <seconds value> ] ] | <minutes value> [ <colon> <seconds value> ] | <seconds value> <not equals operator> ::= <> <greater than or equals operator> ::= >= <less than or equals operator> ::= <= <concatenation operator> ::= || <double period> ::= .. <double colon> ::= :: <assignment operator> ::= := <SQL-client module definition> ::= <module> <module> ::= <module name clause> <module remainder> [ END MODULE ] <module name clause> ::= MODULE [ <module name> ] <module name> ::= <SQL-server module name> | <SQL-client module name> <SQL-server module name> ::= <qualified identifier> <qualified identifier> ::= <identifier> <SQL-client module name> ::= <identifier> <module remainder> ::= [ <module character set specification> ] <language clause> <module authorization clause> [ <module path specification> ] <module contents>... <module character set specification> ::= NAMES ARE <character set specification> <language clause> ::= LANGUAGE <language name> <language name> ::= ADA | C | COBOL | FORTRAN | MUMPS | PASCAL | PLI | SQL <module authorization clause> ::= SCHEMA <schema name> | AUTHORIZATION <module authorization identifier> | SCHEMA <schema name> AUTHORIZATION <module authorization identifier> <module authorization identifier> ::= <authorization identifier> <authorization identifier> ::= <identifier> <module path specification> ::= PATH <schema name list> <schema name list> ::= <schema name> [ ( <comma> <schema name> )... ] <module contents> ::= <global declaration> [ <semicolon> ] | <routine> <global declaration> ::= <declare cursor> | <temporary abstract data type declaration> | <temporary table declaration> | <temporary view declaration> <declare cursor> ::= DECLARE <cursor name> [ <cursor sensitivity> ] [ SCROLL ] CURSOR [ WITH HOLD ] FOR <cursor specification> <cursor sensitivity> ::= SENSITIVE | INSENSITIVE <cursor name> ::= <local qualified name> <local qualified name> ::= [ <local qualifier> <period> ] <qualified identifier> <local qualifier> ::= MODULE <cursor specification> ::= <query expression> [ <order by clause> ] [ <updatability clause> ] <query expression> ::= <possibly updatable query expression> [ <trigger definition>... ] <possibly updatable query expression> ::= <non-join query expression> | <joined table> <non-join query expression> ::= <non-join query term> | <query expression> UNION [ ALL ] [ <corresponding spec> ] <query term> | <query expression> EXCEPT [ ALL ] [ <corresponding spec> ] <query term> <non-join query term> ::= <non-join query primary> | <query term> INTERSECT [ ALL ] [ <corresponding spec> ] <query primary> | <recursive union> <non-join query primary> ::= <simple table> | <left paren> <non-join query expression> <right paren> <simple table> ::= <query specification> | <table value designator> | <explicit table> | <collection expression> <query specification> ::= SELECT [ <set quantifier> ] <select list> <table expression> <set quantifier> ::= DISTINCT | ALL <select list> ::= <asterisk> | <select sublist> [ ( <comma> <select sublist> )... ] <select sublist> ::= <derived column> | <qualifier> <period> <asterisk> <derived column> ::= <value expression> [ <as clause> ] <value expression> ::= <numeric value expression> | <string value expression> | <datetime value expression> | <interval value expression> | <enumerated value expression> | <boolean value expression> | <attributes function> | <abstract data type value expression> | <table value expression> | <collection value expression> <numeric value expression> ::= <term> | <numeric value expression> <plus sign> <term> | <numeric value expression> <minus sign> <term> <term> ::= <factor> | <term> <asterisk> <factor> | <term> <solidus> <factor> <factor> ::= [ <sign> ] <numeric primary> <numeric primary> ::= <value expression primary> | <numeric value function> <value expression primary> ::= <unsigned value specification> | <column reference> | <row reference> | <set function specification> | <table subquery> | <case expression> | <left paren> <value expression> <right paren> | <cast specification> <unsigned value specification> ::= <unsigned literal> | <general value specification> <unsigned literal> ::= <unsigned numeric literal> | <general literal> <general literal> ::= <character string literal> | <national character string literal> | <bit string literal> | <hex string literal> | <datetime literal> | <interval literal> | <enumeration literal> | <boolean literal> | <oid literal> <datetime literal> ::= <date literal> | <time literal> | <timestamp literal> <date literal> ::= DATE <date string> <time literal> ::= TIME <time string> <timestamp literal> ::= TIMESTAMP <timestamp string> <interval literal> ::= INTERVAL [ <sign> ] <interval string> <interval qualifier> <interval qualifier> ::= <start field> TO <end field> | <single datetime field> <start field> ::= <non-second datetime field> [ <left paren> <interval leading field precision> <right paren> ] <non-second datetime field> ::= YEAR | MONTH | DAY | HOUR | MINUTE <interval leading field precision> ::= <unsigned integer> <end field> ::= <non-second datetime field> | SECOND [ <left paren> <interval fractional seconds precision> <right paren> ] <interval fractional seconds precision> ::= <unsigned integer> <single datetime field> ::= <non-second datetime field> [ <left paren> <interval leading field precision> <right paren> ] | SECOND [ <left paren> <interval leading field precision> [ <comma> <interval fractional seconds precision> ] <right paren> ] <enumeration literal> ::= <domain name> <double colon> <enumeration name> <domain name> ::= <schema qualified name> <schema qualified name> ::= [ <schema name> <period> ] <qualified identifier> <enumeration name> ::= <identifier> <boolean literal> ::= TRUE | FALSE <oid literal> ::= OID <oid string> <oid string> ::= <quote> <oid value> <quote> <oid value> ::= <character representation>... <general value specification> ::= <item reference> | USER | CURRENT_USER | SESSION_USER | SYSTEM_USER | CURRENT_PATH | VALUE | <function invocation> | <attribute reference> | <template parameter name> <item reference> ::= <parameter name> [ <indicator parameter> ] <parameter name> ::= <colon> <identifier> <indicator parameter> ::= [ INDICATOR ] <parameter name> <function invocation> ::= <routine invocation> <routine invocation> ::= <routine name> <argument list> <routine name> ::= <local or schema qualified name> <local or schema qualified name> ::= [ <local or schema qualifier> <period> ] <qualified identifier> <local or schema qualifier> ::= <schema name> | MODULE <argument list> ::= <left paren> <positional arguments> <comma> <keyword arguments> <right paren> | <left paren> <positional arguments> <right paren> | <left paren> <keyword arguments> <right paren> | <left paren> <right paren> <positional arguments> ::= <argument> [ ( <comma> <argument> )... ] <argument> ::= <value expression> | <generalized expression> <generalized expression> ::= <value expression> AS <abstract data type name> <abstract data type name> ::= <local or schema qualified name> <attribute name> ::= <identifier> | OID <keyword arguments> ::= <keyword argument> [ ( <comma> <keyword argument> )... ] <keyword argument> ::= <parameter name> <keyword parameter tag> <argument> <keyword parameter tag> ::= => <attribute reference> ::= <value specification> <period> <attribute name> <value specification> ::= <literal> | <general value specification> <literal> ::= <signed numeric literal> | <general literal> <signed numeric literal> ::= [ <sign> ] <unsigned numeric literal> <template parameter name> ::= <colon> <identifier> <column reference> ::= [ <qualifier> <period> ] <column name> <qualifier> ::= <table name> | <correlation name> <table name> ::= <local or schema qualified name> <correlation name> ::= <identifier> <column name> ::= <identifier> | OID <row reference> ::= ROW <qualifier> <set function specification> ::= COUNT <left paren> <asterisk> <right paren> | <general set function> <general set function> ::= <set function type> <left paren> [ <set quantifier> ] <value expression> <right paren> ] <set function type> ::= AVG | MAX | MIN | SUM | COUNT <table subquery> ::= <subquery> <subquery> ::= <left paren> <query expression> <right paren> <case expression> ::= <case abbreviation> | <case specification> <case abbreviation> ::= NULLIF <left paren> <value expression> <comma> <value expression> <right paren> | COALESCE <left paren> <value expression> ( <comma> <value expression> )... <right paren> <case specification> ::= <simple case> | <searched case> <simple case> ::= CASE <case operand> <simple when clause>... [ <else clause> ] END <case operand> ::= <value expression> <simple when clause> ::= WHEN <when operand> THEN <result> <when operand> ::= <value expression> <result> ::= <result expression> | NULL <result expression> ::= <value expression> <else clause> ::= ELSE <result> <searched case> ::= CASE <searched when clause>... [ <else clause> ] END <searched when clause> ::= WHEN <search condition> THEN <result> <search condition> ::= <boolean value expression> <boolean value expression> ::= <boolean term> | <boolean value expression> OR <boolean term> <boolean term> ::= <boolean factor> | <boolean term> AND <boolean factor> <boolean factor> ::= [ NOT ] <boolean primary> <boolean primary> ::= <predicate> | <value expression primary> <predicate> ::= <comparison predicate> | <between predicate> | <in predicate> | <like predicate> | <null predicate> | <quantified comparison predicate> | <exists predicate> | <unique predicate> | <match predicate> | <overlaps predicate> | <similar predicate> | <quantified predicate> | <there is predicate> | <distinct predicate> | <boolean predicate> <comparison predicate> ::= <row value designator> <comp op> <row value designator> <row value designator> ::= <row value designator element> | <left paren> <row value designator list> <right paren> | <row subquery> <row value designator element> ::= <value expression> | <null specification> | <default specification> <null specification> ::= NULL [ <left paren> <null state> <right paren> ] <null state> ::= <identifier> <default specification> ::= DEFAULT <row value designator list> ::= <row value designator element> [ ( <comma> <row value designator element> )... ] <row subquery> ::= <subquery> <comp op> ::= <equals operator> | <not equals operator> | <less than operator> | <greater than operator> | <less than or equals operator> | <greater than or equals operator> <between predicate> ::= <row value designator> [ NOT ] BETWEEN <row value designator> AND <row value designator> <in predicate> ::= <row value designator> [ NOT ] IN <in predicate value> <in predicate value> ::= <table subquery> | <left paren> <in value list> <right paren> <in value list> ::= <value expression> ( <comma> <value expression> )... <like predicate> ::= <match value> [ NOT ] LIKE <pattern> [ ESCAPE <escape character> ] <match value> ::= <character value expression> <character value expression> ::= <concatenation> | <character factor> <concatenation> ::= <character value expression> <concatenation operator> <character factor> <character factor> ::= <character primary> [ <collate clause> ] <character primary> ::= <value expression primary> | <string value function> <string value function> ::= <character value function> | <bit value function> <character value function> ::= <character substring function> | <regular expression substring function> | <fold> | <form-of-use conversion> | <character translation> | <trim function> <character substring function> ::= SUBSTRING <left paren> <character value expression> FROM <start position> [ FOR <string length> ] <right paren> <start position> ::= <numeric value expression> <string length> ::= <numeric value expression> <regular expression substring function> ::= SUBSTRING <left paren> <character value expression> FROM <character value expression> FOR <escape character> <right paren> <escape character> ::= <character value expression> <fold> ::= ( UPPER | LOWER ) <left paren> <character value expression> <right paren> <form-of-use conversion> ::= CONVERT <left paren> <character value expression> USING <form-of-use conversion name> <right paren> <form-of-use conversion name> ::= <schema qualified name> <character translation> ::= TRANSLATE <left paren> <character value expression> USING <translation name> <right paren> <translation name> ::= <schema qualified name> <trim function> ::= TRIM <left paren> <trim operands> <right paren> <trim operands> ::= [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source> <trim specification> ::= LEADING | TRAILING | BOTH <trim character> ::= <character value expression> <trim source> ::= <character value expression> <bit value function> ::= <bit substring function> <bit substring function> ::= SUBSTRING <left paren> <bit value expression> FROM <start position> [ FOR <string length> ] <right paren> <bit value expression> ::= <bit concatenation> | <bit factor> <bit concatenation> ::= <bit value expression> <concatenation operator> <bit factor> <bit factor> ::= <bit primary> <bit primary> ::= <value expression primary> | <string value function> <collate clause> ::= COLLATE <collation name> <collation name> ::= <schema qualified name> <pattern> ::= <character value expression> <null predicate> ::= <row value designator> IS [ NOT ] NULL [ <left paren> <null values specification> <right paren> ] <null values specification> ::= <asterisk> | <null state> <quantified comparison predicate> ::= <row value designator> <comp op> <quantifier> <table subquery> <quantifier> ::= <all> | <some> <all> ::= ALL <some> ::= SOME | ANY <exists predicate> ::= EXISTS <table subquery> <unique predicate> ::= UNIQUE <table subquery> <match predicate> ::= <row value designator> MATCH [ UNIQUE ] [ PARTIAL | FULL ] <table subquery> <overlaps predicate> ::= <row value designator 1> OVERLAPS <row value designator 2> <row value designator 1> ::= <row value designator> <row value designator 2> ::= <row value designator> <row value designator 1> ::= <row value designator> <row value designator 2> ::= <row value designator> <similar predicate> ::= <match value> [ NOT ] SIMILAR TO <similar pattern> [ ESCAPE <escape character> ] <similar pattern> ::= <character value expression> <quantified predicate> ::= <existential clause> <left paren> <search condition> <right paren> | <universal clause> <left paren> <search condition> <right paren> | <quantified comparison predicate> <existential clause> ::= FOR SOME <table reference list> <table reference list> ::= <table reference> [ ( <comma> <table reference> )... ] <table reference> ::= <table name> [ [ AS ] <correlation name> [ <left paren> <derived column list> <right paren> ] ] | <derived table> [ AS ] <correlation name> [ <left paren> <derived column list> <right paren> ] | <joined table> <derived column list> ::= <column name list> <column name list> ::= <column name> [ ( <comma> <column name> )... ] <derived table> ::= <table subquery> <joined table> ::= <cross join> | <qualified join> | <left paren> <joined table> <right paren> <cross join> ::= <table reference> CROSS JOIN <table reference> <qualified join> ::= <table reference> [ NATURAL ] [ <join type> ] JOIN <table reference> [ <join specification> ] <join type> ::= INNER | <outer join type> [ OUTER ] | UNION <outer join type> ::= LEFT | RIGHT | FULL <join specification> ::= <join condition> | <named columns join> | <constraint join> <join condition> ::= ON <search condition> <named columns join> ::= USING <left paren> <join column list> <right paren> <join column list> ::= <column name list> <constraint join> ::= | USING PRIMARY KEY | USING FOREIGN KEY | USING CONSTRAINT <constraint name> <constraint name> ::= <schema qualified name> <universal clause> ::= FOR ALL <table reference list> <there is predicate> ::= <left paren> <there is clause> <where clause> <right paren> <there is clause> ::= THERE IS <table reference list> <where clause> ::= WHERE <search condition> <distinct predicate> ::= <row value designator 1> IS DISTINCT FROM <row value designator 2> <boolean predicate> ::= <boolean value expression> [ IS [ NOT ] <truth value> ] <truth value> ::= TRUE | FALSE | UNKNOWN <cast specification> ::= CAST <left paren> <cast operand> AS <cast target> <right paren> <cast operand> ::= <value expression> | NULL <cast target> ::= <domain name> | <data type> <data type> ::= <predefined type> | <abstract data type name> | <generated type reference> | <template parameter name> | <collection type> <predefined type> ::= <character string type> [ CHARACTER SET <character set specification> ] | <national character string type> | <bit string type> | <numeric type> | <enumerated type> | <boolean type> | <datetime type> | <interval type> <character string type> ::= CHARACTER [ <left paren> <length> <right paren> ] | CHAR [ <left paren> <length> <right paren> ] | CHARACTER VARYING <left paren> <length> <right paren> | CHAR VARYING <left paren> <length> <right paren> | VARCHAR <left paren> <length> <right paren> <length> ::= <unsigned integer> <national character string type> ::= NATIONAL CHARACTER [ <left paren> <length> <right paren> ] | NATIONAL CHAR [ <left paren> <length> <right paren> ] | NCHAR [ <left paren> <length> <right paren> ] | NATIONAL CHARACTER VARYING <left paren> <length> <right paren> | NATIONAL CHAR VARYING <left paren> <length> <right paren> | NCHAR VARYING <left paren> <length> <right paren> <bit string type> ::= BIT [ <left paren> <length> <right paren> ] | BIT VARYING <left paren> <length> <right paren> <numeric type> ::= <exact numeric type> | <approximate numeric type> <exact numeric type> ::= NUMERIC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ] | DECIMAL [ <left paren> <precision> [ <comma> <scale> ] <right paren> ] | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ] | INTEGER | INT | SMALLINT <precision> ::= <unsigned integer> <scale> ::= <unsigned integer> <approximate numeric type> ::= FLOAT [ <left paren> <precision> <right paren> ] | REAL | DOUBLE PRECISION <enumerated type> ::= <left paren> <enumeration name list> <right paren> <enumeration name list> ::= <enumeration name> [ ( <comma> <enumeration name> )... ] <boolean type> ::= BOOLEAN <datetime type> ::= DATE | TIME [ <left paren> <time precision> <right paren> ] [ WITH TIME ZONE ] | TIMESTAMP [ <left paren> <timestamp precision> <right paren> ] [ WITH TIME ZONE ] <time precision> ::= <time fractional seconds precision> <time fractional seconds precision> ::= <unsigned integer> <timestamp precision> ::= <time fractional seconds precision> <interval type> ::= INTERVAL <interval qualifier> <generated type reference> ::= <type template name> <template parameter list> <type template name> ::= <schema qualified name> <template parameter list> ::= <left paren> <template parameter> [ ( <comma> <template parameter> )... ] <right paren> <template parameter> ::= <value specification> | <data type> <collection type> ::= <set type> | <multiset type> | <list type> <set type> ::= SET <left paren> <data type> <right paren> <multiset type> ::= MULTISET <left paren> <data type> <right paren> <list type> ::= LIST <left paren> <data type> <right paren> <numeric value function> ::= <position expression> | <extract expression> | <length expression> <position expression> ::= POSITION <left paren> <character value expression> IN <character value expression> <right paren> <extract expression> ::= EXTRACT <left paren> <extract field> FROM <extract source> <right paren> <extract field> ::= <datetime field> | <time zone field> <datetime field> ::= <non-second datetime field> | SECOND <time zone field> ::= TIMEZONE_HOUR | TIMEZONE_MINUTE <extract source> ::= <datetime value expression> | <interval value expression> <datetime value expression> ::= <datetime term> | <interval value expression> <plus sign> <datetime term> | <datetime value expression> <plus sign> <interval term> | <datetime value expression> <minus sign> <interval term> <interval term> ::= <interval factor> | <interval term 2> <asterisk> <factor> | <interval term 2> <solidus> <factor> | <term> <asterisk> <interval factor> <interval factor> ::= [ <sign> ] <interval primary> <interval primary> ::= <value expression primary> [ <interval qualifier> ] <interval term 2> ::= <interval term> <interval value expression> ::= <interval term> | <interval value expression 1> <plus sign> <interval term 1> | <interval value expression 1> <minus sign> <interval term 1> | <left paren> <datetime value expression> <minus sign> <datetime term> <right paren> <interval qualifier> <interval value expression 1> ::= <interval value expression> <interval term 1> ::= <interval term> <datetime term> ::= <datetime factor> <datetime factor> ::= <datetime primary> [ <time zone> ] <datetime primary> ::= <value expression primary> | <datetime value function> <datetime value function> ::= <current date value function> | <current time value function> | <current timestamp value function> <current date value function> ::= CURRENT_DATE <current time value function> ::= CURRENT_TIME [ <left paren> <time precision> <right paren> ] <current timestamp value function> ::= CURRENT_TIMESTAMP [ <left paren> <timestamp precision> <right paren> ] <time zone> ::= AT <time zone specifier> <time zone specifier> ::= LOCAL | TIME ZONE <interval primary> <length expression> ::= <char length expression> | <octet length expression> | <bit length expression> <char length expression> ::= ( CHAR_LENGTH | CHARACTER_LENGTH ) <left paren> <string value expression> <right paren> <string value expression> ::= <character value expression> | <bit value expression> <octet length expression> ::= OCTET_LENGTH <left paren> <string value expression> <right paren> <bit length expression> ::= BIT_LENGTH <left paren> <string value expression> <right paren> <enumerated value expression> ::= <domain name> <left paren> <value expression> <right paren> | <enumerated primary> <enumerated primary> ::= <value expression primary> <attributes function> ::= ATTRIBUTES <left paren> <abstract data type value expression> <right paren> <abstract data type value expression> ::= <ADT expression> <ADT expression> ::= <ADT term> | <ADT expression> <term operator> <ADT term> <term operator> ::= <ADT operator> <ADT operator> ::= <user-defined operator symbol) <ADT term> ::= <ADT factor> | <ADT term> <factor operator> <ADT factor> <factor operator> ::= <ADT operator> <ADT factor> ::= <ADT primary> | <prefix operator> <ADT primary> | <ADT primary> <postfix operator> <ADT primary> ::= <value expression primary> <prefix operator> ::= <ADT operator> <postfix operator> ::= <ADT operator> <table value expression> ::= <table type> <left paren> [ <value expression> [ ( <comma> <value expression> )... ] ] <right paren> <table type> ::= TABLE | SET | LIST <collection value expression> ::= <set value designator> | <multiset value designator> | <list value designator> <set value designator> ::= SET <left paren> [ <collection list> ] <right paren> <collection list> ::= <collection element> [ ( <comma> <collection element> )... ] <collection element> ::= <value expression> <multiset value designator> ::= MULTISET <left paren> [ <collection list> ] <right paren> <list value designator> ::= LIST <left paren> [ <collection list> ] <right paren> <as clause> ::= [ AS ] <column name> <table expression> ::= <from clause> [ <where clause> ] [ <group by clause> ] [ <having clause> ] <from clause> ::= FROM <table reference> [ ( <comma> <table reference> )... ] <group by clause> ::= GROUP BY <grouping column reference list> <grouping column reference list> ::= <grouping column reference> [ ( <comma> <grouping column reference> )... ] <grouping column reference> ::= <column reference> [ <collate clause> ] <having clause> ::= HAVING <search condition> <table value designator> ::= VALUES <table value designator list> <table value designator list> ::= <row value designator> [ ( <comma> <row value designator> )... ] <explicit table> ::= <table type> <table name> <collection expression> ::= <value expression> <query term> ::= <non-join query term> | <joined table> <corresponding spec> ::= CORRESPONDING [ BY <left paren> <corresponding column list> <right paren> ] <corresponding column list> ::= <column name list> <query primary> ::= <non-join query primary> | <joined table> <recursive union> ::= <left paren> <initial expression> RECURSIVE UNION <correlation name list> [ <left paren> <recursive column list> <right paren> ] <iteration expression> [ <search clause> ] [ <cycle clause> ] [ <limit clause> ] <right paren> <initial expression> ::= <query expression> <correlation name list> ::= <correlation name> [ ( <comma> <correlation name> )... ] <recursive column list> ::= <column name list> <iteration expression> ::= <query expression> <search clause> ::= SEARCH <search order> SET <sequence column> <search order> ::= PREORDER | ( DEPTH | BREADTH ) FIRST BY <sort specification list> <sort specification list> ::= <sort specification> [ ( <comma> <sort specification> )... ] <sort specification> ::= <sort key> [ <collate clause> ] [ <ordering specification> ] <sort key> ::= <value expression> <ordering specification> ::= ASC | DESC <sequence column> ::= <column name> <cycle clause> ::= CYCLE [ <cycle column list> ] SET <cycle mark column> [ TO <cycle mark value> ] <cycle column list> ::= <cycle column> [ ( <comma> <cycle column> )... ] <cycle column> ::= <column name> <cycle mark column> ::= <column name> <cycle mark value> ::= <value expression> <limit clause> ::= [ RETURN | EXCEPTION ] LIMIT <left paren> <value specification> <right paren> <trigger definition> ::= [ CREATE ] TRIGGER [ <trigger name> ] <trigger action time> <trigger event> [ ON <table name> ] [ ORDER <order value> ] [ REFERENCING <old or new values alias list> ] <triggered action> <trigger name> ::= <schema qualified name> <trigger action time> ::= BEFORE | AFTER | INSTEAD OF <trigger event> ::= INSERT | DELETE | UPDATE [ OF <trigger column list> ] <trigger column list> ::= <column name list> <order value> ::= <unsigned integer> <old or new values alias list> ::= <old or new values alias>... <old or new values alias> ::= OLD [ AS ] <old values correlation name> | NEW [ AS ] <new values correlation name> | OLD_TABLE [ AS ] <old values table alias> | NEW_TABLE [ AS ] <new values table alias> <old values correlation name> ::= <correlation name> <new values correlation name> ::= <correlation name> <old values table alias> ::= <identifier> <new values table alias> ::= <identifier> <triggered action> ::= [ FOR EACH ( ROW | STATEMENT ) ] [ WHEN <left paren> <search condition> <right paren> ] <triggered SQL statement> <triggered SQL statement> ::= <SQL procedure statement> <semicolon> <SQL procedure statement> ::= [ ASYNC <left paren> <async statement identifier> <right paren> ] <SQL executable statement> <async statement identifier> ::= <numeric value expression> <SQL executable statement> ::= <SQL schema statement> | <SQL data statement> | <SQL transaction statement> | <SQL connection statement> | <SQL session statement> | <SQL diagnostics statement> <SQL schema statement> ::= <SQL schema definition statement> | <SQL schema manipulation statement> <SQL schema definition statement> ::= <schema definition> | <table definition> | <view definition> | <grant statement> | <role definition> | <grant role statement> | <domain definition> | <null class definition> | <character set definition> | <collation definition> | <translation definition> | <assertion definition> | <trigger definition> | <routine> | <abstract data type definition> | <type template definition> <schema definition> ::= CREATE SCHEMA <schema name clause> [ <schema character set specification> ] [ <schema path specification> ] [ <schema element>... ] <schema name clause> ::= <schema name> | AUTHORIZATION <schema authorization identifier> | <schema name> AUTHORIZATION <schema authorization identifier> <schema authorization identifier> ::= <authorization identifier> <schema character set specification> ::= DEFAULT CHARACTER SET <character set specification> <schema path specification> ::= PATH <schema name list> <schema element> ::= <table definition> | <view definition> | <domain definition> | <null class definition> | <character set definition> | <collation definition> | <translation definition> | <assertion definition> | <trigger definition> | <routine> | <abstract data type definition> | <type template definition> | <grant statement> | <role definition> | <grant role statement> <table definition> ::= CREATE [ <table scope> ] <table type> <table name> [ <constant or updatable> ] ( <table element list> | <subtable clause> ) [ ON COMMIT <table commit action> ROWS ] <table scope> ::= <global or local> TEMPORARY <global or local> ::= GLOBAL | LOCAL <constant or updatable> ::= CONSTANT | UPDATABLE <table element list> ::= <left paren> <table element> [ ( <comma> <table element> )... ] <right paren> <table element> ::= <column definition> | <table constraint definition> | <like clause> <column definition> ::= <column name> ( <data type> | <domain name> ) [ <default clause> ] [ <column constraint definition>... ] [ <collate clause> ] [ <null clause> ] <default clause> ::= ( DEFAULT | <assignment operator> ) <default option> <default option> ::= <literal> | <datetime value function> | USER | CURRENT_USER | SESSION_USER | SYSTEM_USER | NULL [ <left paren> <null state> <right paren> ] | <function invocation> <column constraint definition> ::= [ <constraint name definition> ] <column constraint> [ <constraint attributes> ] <constraint name definition> ::= CONSTRAINT <constraint name> <column constraint> ::= NOT NULL | <unique specification> | <references specification> | <check constraint definition> <unique specification> ::= UNIQUE | PRIMARY KEY <references specification> ::= REFERENCES [ PENDANT ] <referenced table and columns> [ MATCH <match type> ] [ <referential triggered action> ] <referenced table and columns> ::= <table name> [ <left paren> [ <reference column list> ] <right paren> ] <reference column list> ::= <column name list> <match type> ::= FULL | PARTIAL <referential triggered action> ::= <update rule> [ <delete rule> ] | <delete rule> [ <update rule> ] <update rule> ::= ON UPDATE <referential action> <referential action> ::= CASCADE | SET NULL [ <left paren> <null state> <right paren> ] | SET DEFAULT | RESTRICT | NO ACTION <delete rule> ::= ON DELETE <referential action> <check constraint definition> ::= CHECK <left paren> <search condition> <right paren> <constraint attributes> ::= <constraint check time> [ [ NOT ] DEFERRABLE ] | [ NOT ] DEFERRABLE [ <constraint check time> ] <constraint check time> ::= INITIALLY DEFERRED | INITIALLY IMMEDIATE <null clause> ::= NULL IS <null class name> <null class name> ::= <schema qualified name> <null clause> ::= NULL IS <null class name> <table constraint definition> ::= [ <constraint name definition> ] <table constraint> [ <constraint attributes> ] <table constraint> ::= <unique constraint definition> | <referential constraint definition> | <check constraint definition> <unique constraint definition> ::= even in SQL3) <unique specification> [ <left paren> <unique column list> <right paren> ] | UNIQUE ( VALUE ) <unique column list> ::= <column name list> <referential constraint definition> ::= FOREIGN KEY [ <left paren> <referencing columns> <right paren> ] <references specification> <referencing columns> ::= <reference column list> <like clause> ::= LIKE <table name> <subtable clause> ::= UNDER <supertable clause> [ ( , <supertable clause> )... ] <supertable clause> ::= <supertable name> [ WITH ( <member renaming element> [ ( , <member renaming element> )... ] ) ] <supertable name> ::= <table name> <member renaming element> ::= <supertable member name> AS <subtable member name> <supertable member name> ::= <column name> | <routine name> <subtable member name> ::= <column name> | <routine name> <table commit action> ::= PRESERVE | DELETE <view definition> ::= CREATE VIEW <table name> [ <left paren> <view column list> <right paren> ] AS <query expression> [ WITH [ <levels clause> ] CHECK OPTION ] <view column list> ::= <column name list> <levels clause> ::= CASCADED | LOCAL <domain definition> ::= CREATE DOMAIN <domain name> [ AS ] <data type> [ <default clause> ] [ <domain constraint>... ] [ <collate clause> ] [ <null clause> ] <domain constraint> ::= [ <constraint name definition> ] <check constraint definition> [ <constraint attributes> ] <null class definition> ::= CREATE NULL CLASS <null class name> [ AS ] ( <null state list> ) <null state list> ::= <null state> [ ( <comma> <null state> )... ] <character set definition> ::= CREATE CHARACTER SET <character set name> [ AS ] <character set source> <form-of-use specification> [ <collate clause> | <limited collation definition> ] <character set source> ::= GET <existing character set name> [ <plus sign> <character set source> ] | <left paren> <character list> <right paren> <character list> ::= <character specification> [ ( <comma> <character specification> )... ] <character specification> ::= <character string literal> | <ISO 10646 position> | <ISO 10646 character name> <ISO 10646 position> ::= <val> [ <sep> <val> [ <sep> <val> [ <sep> <val> ] ] ] <val> ::= <unsigned numeric literal> <sep> ::= <ampersand> <ISO 10646 character name> ::= !! <EMPHASIS>(See the Syntax Rules) <form-of-use specification> ::= <identifier> <limited collation definition> ::= COLLATION FROM <collation source> <collation source> ::= <collating sequence definition> | <translation collation> | <collation dictionary specification> | <collation routine specification> <collating sequence definition> ::= <external collation> | <schema collation name> | <internal collation source> | DESC <left paren> <collation name> <right paren> | DEFAULT <external collation> ::= EXTERNAL <left paren> <quote> <external collation name> <quote> <right paren> <external collation name> ::= <standard collation name> | <implementation-defined collation name> <standard collation name> ::= <collation name> <implementation-defined collation name> ::= <collation name> <schema collation name> ::= <collation name> <internal collation source> ::= <left paren> <collation options> <right paren> <collation options> ::= <collation option> [ ( <comma> <collation option> )... ] <collation option> ::= USING <left paren> <collating basis> <right paren> | SEQUENCE <left paren> <enumerated collating sequence> <right paren> | MODIFY <left paren> <collating modifiers> <right paren> | WHEN NOT FOUND ( IGNORE | MAX | MIN ) <collating basis> ::= <collating foundation> [ ( <plus sign> <collating foundation> )... ] <collating foundation> ::= <collating sequence definition> <collating sequence definition> [ ( <asterisk> <translation name> )... ] <enumerated collating sequence> ::= <collating chars> [ ( <comma> <collating chars> )... ] <collating chars> ::= <character specification> | <character range> <character range> ::= <character specification> <minus sign> <character specification> <collating modifiers> ::= <collating modifier> [ ( <comma> <collating modifier> )... ] <collating modifier> ::= <collating chars> ( <less than operator> | <greater than operator> | <equals operator> ) <collating chars> <translation collation> ::= TRANSLATION <translation name> [ THEN COLLATION <collation name> ] <collation dictionary specification> ::= DICTIONARY <dictionary name> [ <plus sign> <dictionary name> ] <dictionary name> ::= <quote> <implementation-defined dictionary name> <quote> <implementation-defined dictionary name> ::= !! <EMPHASIS>(See the Syntax Rules) <collation routine specification> ::= ROUTINE <left paren> <implementation-defined routine name> <left paren> <params> <right paren> <right paren> <implementation-defined routine name> ::= !! <EMPHASIS>(See the Syntax Rules) <params> ::= !! <EMPHASIS>(Not yet defined) <params> ::= !! <EMPHASIS>(Not yet defined) <existing character set name> ::= <standard character repertoire name> | <implementation-defined character repertoire name> | <schema character set name> <schema character set name> ::= <character set name> <collation definition> ::= CREATE COLLATION <collation name> FOR <character set specification> FROM <collation source> [ <pad attribute> ] <pad attribute> ::= NO PAD | PAD SPACE <translation definition> ::= CREATE TRANSLATION <translation name> FOR <source character set specification> TO <target character set specification> FROM <translation source> <source character set specification> ::= <character set specification> <target character set specification> ::= <character set specification> <translation source> ::= <translation specification> | <translation routine> <translation specification> ::= <external translation> | IDENTITY | <schema translation name> | <internal translation source> <external translation> ::= EXTERNAL <left paren> <quote> <external translation name> <quote> <right paren> <external translation name> ::= <standard translation name> | <implementation-defined translation name> <standard translation name> ::= <translation name> <implementation-defined translation name> ::= <translation name> <schema translation name> ::= <translation name> <internal translation source> ::= <left paren> <translation options> <right paren> <translation options> ::= <translation option> [ ( <comma> <translation option> )... ] <translation option> ::= USING <left paren> <translation basis> <right paren> | MODIFY <left paren> <translation modifiers> <right paren> <translation basis> ::= <translation definition> [ ( <asterisk> <translation definition> )... ] <translation modifiers> ::= <translation modifier> [ ( <comma> <translation modifier> )... ] <translation modifier> ::= <collating chars> <equals operator> <collating chars> <translation routine> ::= ROUTINE <left paren> <implementation-defined routine name> <left paren> <params> <right paren> <right paren> <assertion definition> ::= CREATE ASSERTION <constraint name> <assertion trigger>... <triggered assertion> [ <constraint attributes> ] <assertion trigger> ::= <immediate assertion trigger> | <deferred assertion trigger> <immediate assertion trigger> ::= AFTER ( <assertion trigger statement> [ ( <comma> <assertion trigger statement> )... ] ON <table name> )... <assertion trigger statement> ::= INSERT | DELETE | UPDATE [ OF <left paren> <assertion column list> <right paren> ] <assertion column list> ::= <column name list> <deferred assertion trigger> ::= BEFORE COMMIT <triggered assertion> ::= CHECK <left paren> <search condition> <right paren> [ FOR [ EACH [ ROW OF ] ] <table name> ] <routine> ::= [ CREATE | DECLARE ] <routine header> <routine name> <parameter list> [ <returns clause> ] [ <caller language clause> ] [ SPECIFIC <specific name> ] <semicolon> <routine body> <semicolon> <routine header> ::= PROCEDURE | [ <function type> ] FUNCTION <function type> ::= CONSTRUCTOR | DESTRUCTOR | DESIGNATOR | ACTOR <parameter list> ::= <left paren> [ <parameter declaration> [ ( <comma> <parameter declaration> )... ] ] <right paren> <parameter declaration> ::= [ <parameter mode> ] [ <parameter name> ] <data type> [ <default clause> ] | <status parameter> <parameter mode> ::= IN | OUT | INOUT <status parameter> ::= SQLSTATE | SQLCODE <returns clause> ::= RETURNS <returns data type> [ <result cast> ] <returns data type> ::= <data type> <result cast> ::= CAST FROM <data type> <caller language clause> ::= <language clause> <specific name> ::= <schema qualified name> <routine body> ::= <SQL routine body> | <external body reference> <SQL routine body> ::= <SQL procedure statement> <external body reference> ::= EXTERNAL [ NAME <external routine name> ] <external routine language clause> [ <variant attribute> ] <external routine name> ::= <identifier> <external routine language clause> ::= <language clause> <variant attribute> ::= VARIANT | NOT VARIANT <abstract data type definition> ::= <distinct type definition> | <explicit abstract data type definition> <distinct type definition> ::= CREATE DISTINCT TYPE <distinct type name> AS <data type> <distinct type name> ::= <abstract data type name> <explicit abstract data type definition> ::= CREATE TYPE <abstract data type name> <abstract data type body> <abstract data type body> ::= [ <oid options> ] [ <subtype clause> ] [ [ <constant or updatable> ] [ <member list> ] ] <oid options> ::= WITH OID [ [ NOT ] VISIBLE ] | WITHOUT OID <subtype clause> ::= UNDER <supertype clause> [ ( <comma> <supertype clause> )... ] <supertype clause> ::= <abstract data type name> [ <component renaming clause> ] <component renaming clause> ::= WITH <left paren> <component renaming element> [ ( , <component renaming element> )... ] <right paren> <component renaming element> ::= <supertype component name> AS <subtype component name> <supertype component name> ::= <component name> <component name> ::= <identifier> <subtype component name> ::= <component name> <member list> ::= <left paren> <member> [ ( <comma> <member> )... ] <right paren> <member> ::= <attribute definition> | <routine declaration> | <operator name list> | <equals clause> | <less-than clause> | <cast clause> | <table constraint definition> <attribute definition> ::= <stored attribute> | <virtual attribute> <stored attribute> ::= [ <encapsulation level> ] <attribute name> [ <constant or updatable> ] ( <data type> | <domain name> ) [ <default clause> ] [ <column constraint definition>... ] [ <collate clause> ] [ <null clause> ] <encapsulation level> ::= PRIVATE | PROTECTED | PUBLIC <virtual attribute> ::= [ <encapsulation level> ] <attribute name> <derivation clause> [ <check constraint definition>... ] [ <collate clause> ] <derivation clause> ::= [ READ ONLY | CONSTANT | UPDATABLE ] <data type> VIRTUAL [ <derivation functions> ] <derivation functions> ::= <get function> [ <set function> ] | <set function> [ <get function> ] <get function> ::= GET WITH <routine name> <set function> ::= SET WITH <routine name> <routine declaration> ::= [ <encapsulation level> ] <routine> <operator name list> ::= OPERATORS <specific routine designator>... <specific routine designator> ::= SPECIFIC <specific name> | <member name> <member name> ::= <routine name> [ <data type list> ] <data type list> ::= <left paren> <data type> [ ( <comma> <data type> )... ] <right paren> <equals clause> ::= EQUALS <equals function specification> <semicolon> <equals function specification> ::= <routine name> | STATE | OID <less-than clause> ::= LESS THAN <less-than function specification> <semicolon> <less-than function specification> ::= <routine name> | NONE <cast clause> ::= CAST <left paren> <operand data type> AS <result data type> WITH <cast function> <right paren> <semicolon> <operand data type> ::= <data type> <result data type> ::= <data type> <cast function> ::= <routine name> <type template definition> ::= CREATE TYPE TEMPLATE <type template name> <template parameter declaration list> <abstract data type body> <template parameter declaration list> ::= <left paren> <template parameter declaration> [ ( <comma> <template parameter declaration>)... ] <right paren> <template parameter declaration> ::= <template parameter name> <template parameter type> <template parameter type> ::= <data type> | TYPE <grant statement> ::= GRANT <privileges> TO <grantee> [ ( <comma> <grantee> )... ] [ WITH GRANT OPTION ] <privileges> ::= ALL SCHEMA PRIVILEGES | <object privileges> ON <object name> <object privileges> ::= ALL PRIVILEGES | <action> [ ( <comma> <action> )... ] <action> ::= SELECT [ <left paren> <privilege column list> <right paren> ] | DELETE | INSERT [ <left paren> <privilege column list> <right paren> ] | UPDATE [ <left paren> <privilege column list> <right paren> ] | REFERENCES [ <left paren> <privilege column list> <right paren> ] | USAGE | TRIGGER | EXECUTE | UNDER <privilege column list> ::= <column name list> <object name> ::= [ <table type> ] <table name> | DOMAIN <domain name> | COLLATION <collation name> | CHARACTER SET <character set name> | TRANSLATION <translation name> | NULL CLASS <null class name> | DATA TYPE <abstract data type name> | MODULE <module name> | TYPE TEMPLATE <type template name> | EXTERNAL ROUTINE <specific routine designator> <grantee> ::= PUBLIC | <authorization identifier> | <role name> <role name> ::= <authorization identifier> <role definition> ::= CREATE ROLE <role name> <grant role statement> ::= GRANT <role granted> [ ( <comma> <role granted> )... ] TO <grantee> [ ( <comma> <grantee> )... ] [ WITH ADMIN OPTION ] <role granted> ::= <role name> <SQL schema manipulation statement> ::= <drop schema statement> | <alter table statement> | <drop table statement> | <drop view statement> | <revoke statement> | <revoke role statement> | <drop role statement> | <alter domain statement> | <drop domain statement> | <drop null class statement> | <drop character set statement> | <drop collation statement> | <drop translation statement> | <drop assertion statement> | <drop trigger statement> | <drop routine statement> | <drop data type statement> | <drop type template statement> <drop schema statement> ::= DROP SCHEMA <schema name> <drop behavior> <drop behavior> ::= CASCADE | RESTRICT <alter table statement> ::= ALTER <table type> <table name> <alter table action> <alter table action> ::= <add column definition> | <alter column definition> | <drop column definition> | <add supertable clause> | <drop supertable clause> | <add table constraint definition> | <drop table constraint definition> <add column definition> ::= ADD [ COLUMN ] <column definition> <alter column definition> ::= ALTER [ COLUMN ] <column name> <alter column action> <alter column action> ::= <set column default clause> | <drop column default clause> | <drop column domain clause> <set column default clause> ::= SET <default clause> <drop column default clause> ::= DROP DEFAULT <drop column domain clause> ::= DROP DOMAIN [ <constraint disposition> [ <constraint name list> ] ] <constraint disposition> ::= KEEP COLUMN CONSTRAINT | DROP COLUMN CONSTRAINT <constraint name list> ::= ALL | <constraint name> [ ( <comma> <constraint name> )... ] <drop column definition> ::= DROP [ COLUMN ] <column name> <drop behavior> <add supertable clause> ::= ADD <supertable clause> <drop supertable clause> ::= DROP <supertable clause> <drop behavior> <add table constraint definition> ::= ADD <table constraint definition> <drop table constraint definition> ::= DROP CONSTRAINT <constraint name> <drop behavior> <drop table statement> ::= DROP <table type> <table name> <drop behavior> <drop view statement> ::= DROP VIEW <table name> <drop behavior> <revoke statement> ::= REVOKE [ GRANT OPTION FOR ] <privileges> FROM <grantee> [ ( <comma> <grantee> )... ] <drop behavior> <revoke role statement> ::= REVOKE <role revoked> [ ( <comma> <role revoked> )... ] FROM <grantee> [ ( <comma> <grantee> )... ] <role revoked> ::= <role name> <drop role statement> ::= DROP ROLE <role name> <alter domain statement> ::= ALTER DOMAIN <domain name> <alter domain action> <alter domain action> ::= <set domain default clause> | <drop domain default clause> | <add domain constraint definition> | <drop domain constraint definition> <set domain default clause> ::= SET <default clause> <drop domain default clause> ::= DROP DEFAULT <add domain constraint definition> ::= ADD <domain constraint> <drop domain constraint definition> ::= DROP CONSTRAINT <constraint name> [ <constraint disposition> ] <drop domain statement> ::= DROP DOMAIN <domain name> <drop behavior> [ <constraint disposition> [ <constraint name list> ] ] <drop null class statement> ::= DROP NULL CLASS <null class name> <drop character set statement> ::= DROP CHARACTER SET <character set name> <drop collation statement> ::= DROP COLLATION <collation name> <drop behavior> <drop translation statement> ::= DROP TRANSLATION <translation name> <drop assertion statement> ::= DROP ASSERTION <constraint name> <drop trigger statement> ::= DROP TRIGGER <trigger name> <drop routine statement> ::= DROP ( PROCEDURE | FUNCTION ) <specific routine designator> <drop behavior> <drop data type statement> ::= DROP DATA TYPE <abstract data type name> <drop behavior> <drop type template statement> ::= DROP TYPE TEMPLATE <type template name> <drop behavior> <SQL data statement> ::= <open statement> | <fetch statement> | <close statement> | <select statement: single row> | <new statement> | <destroy statement> | <SQL data change statement> <open statement> ::= OPEN <cursor name> [ <open cascade option> ] <open cascade option> ::= CASCADE ON | CASCADE OFF <fetch statement> ::= FETCH [ [ <fetch orientation> ] FROM ] <cursor name> INTO <fetch target list> <fetch orientation> ::= NEXT | PRIOR | FIRST | LAST | ( ABSOLUTE | RELATIVE ) <simple value specification> <simple value specification> ::= <item reference> | <literal> <fetch target list> ::= <target specification> [ ( <comma> <target specification> )... ] <target specification> ::= <item reference> | <template parameter name> <close statement> ::= CLOSE <cursor name> <select statement: single row> ::= SELECT [ <set quantifier> ] <select list> INTO <select target list> <table expression> <select target list> ::= <target specification> [ ( <comma> <target specification> )... ] <new statement> ::= NEW <item reference> <destroy statement> ::= DESTROY <object parameter name> <object parameter name> ::= <parameter name> <SQL data change statement> ::= <delete statement: positioned> | <delete statement: searched> | <insert statement> | <update statement: positioned> | <update statement: searched> <delete statement: positioned> ::= DELETE [ FROM <table name> ] WHERE CURRENT OF <cursor name> <delete statement: searched> ::= DELETE FROM <table reference> [ WHERE <search condition> ] <insert statement> ::= INSERT INTO ( <table reference> | CURSOR <cursor name> ) <insert columns and source> [ <insert point> ] <insert columns and source> ::= [ <left paren> <insert column list> <right paren> ] <query expression> | DEFAULT VALUES <insert column list> ::= <column name list> <insert point> ::= <relative insert point> ELEMENT <where clause> <relative insert point> ::= BEFORE | AFTER <update statement: positioned> ::= UPDATE [ <table reference> ] SET [ <update type> ] <set clause list> WHERE CURRENT OF <cursor name> <update type> ::= ALL | SOME | NONE <set clause list> ::= <set clause> [ ( <comma> <set clause> )... ] <set clause> ::= <update target> <equals operator> <row value designator> <update target> ::= <object column> | <left paren> <object column list> <right paren> <object column> ::= <column name> <object column list> ::= <object column> [ ( <comma> <object column> )... ] <update statement: searched> ::= UPDATE <table reference> <update mechanism> [ WHERE <search condition> ] <update mechanism> ::= <update by setting> | <update by moving> <update by setting> ::= SET [ <update type> ] <set clause list> <update by moving> ::= MOVE <insert point> <SQL transaction statement> ::= <start transaction statement> | <set transaction statement> | <set constraints mode statement> | <test completion statement> | <savepoint statement> | <release savepoint statement> | <commit statement> | <rollback statement> <start transaction statement> ::= START TRANSACTION <transaction mode> [ ( <comma> <transaction mode> )...] <transaction mode> ::= <isolation level> | <transaction access mode> | <diagnostics size> <isolation level> ::= ISOLATION LEVEL <level of isolation> <level of isolation> ::= READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE <transaction access mode> ::= READ ONLY | READ WRITE <diagnostics size> ::= DIAGNOSTICS SIZE <number of conditions> <number of conditions> ::= <simple value specification> <set transaction statement> ::= SET [ LOCAL ] TRANSACTION <transaction mode> [ ( <comma> <transaction mode> )... ] <set constraints mode statement> ::= SET CONSTRAINTS <constraint name list> ( DEFERRED | IMMEDIATE ) <test completion statement> ::= ( TEST | WAIT ) ( ALL | ANY | <async statement identifier list> ) COMPLETION <async statement identifier list> ::= <left paren> <async statement identifier> [ ( <comma> <async statement identifier> )... ] <right paren> <savepoint statement> ::= SAVEPOINT <savepoint specifier> <savepoint specifier> ::= <savepoint name> | <simple target specification> <savepoint name> ::= <identifier> <simple target specification> ::= <item reference> <release savepoint statement> ::= RELEASE SAVEPOINT <savepoint specifier> <commit statement> ::= COMMIT [ WORK ] [ AND [ NO ] CHAIN ] <rollback statement> ::= ROLLBACK [ WORK ] [ AND[ NO ] CHAIN ] [ <savepoint clause> ] <savepoint clause> ::= TO SAVEPOINT <savepoint specifier> <SQL connection statement> ::= <connect statement> | <set connection statement> | <disconnect statement> <connect statement> ::= CONNECT TO <connection target> <connection target> ::= <SQL-server name> [ AS <connection name> ] correspondence with Tony Gordon) [ USER <user name> ] | DEFAULT <SQL-server name> ::= <simple value specification> <connection name> ::= <simple value specification> <user name> ::= <simple value specification> <set connection statement> ::= SET CONNECTION <connection object> <connection object> ::= DEFAULT | <connection name> <disconnect statement> ::= DISCONNECT <disconnect object> <disconnect object> ::= <connection object> | ALL | CURRENT <SQL session statement> ::= <set session authorization identifier statement> | <set role statement> | <set local time zone statement> <set session authorization identifier statement> ::= SET SESSION AUTHORIZATION <value specification> <set role statement> ::= SET ROLE ( <role name> | NONE ) <set local time zone statement> ::= SET TIME ZONE <set time zone value> <set time zone value> ::= <interval value expression> | LOCAL <SQL diagnostics statement> ::= <get diagnostics statement> <get diagnostics statement> ::= GET DIAGNOSTICS <sql diagnostics information> <sql diagnostics information> ::= <statement information> | <condition information> <statement information> ::= <statement information item> [ ( <comma> <statement information item> )... ] <statement information item> ::= <simple target specification> <equals operator> <statement information item name> <statement information item name> ::= NUMBER | MORE | COMMAND_FUNCTION | ROW_COUNT | TRANSACTIONS_COMMITTED | TRANSACTIONS_ROLLED_BACK | TRANSACTION_ACTIVE <condition information> ::= EXCEPTION <condition number> <condition information item> [ ( <comma> <condition information item> )... ] <condition number> ::= <simple value specification> <condition information item> ::= <simple target specification> <equals operator> <condition information item name> <condition information item name> ::= CONDITION_NUMBER | RETURNED_SQLSTATE | CLASS_ORIGIN | SUBCLASS_ORIGIN | SERVER_NAME | CONNECTION_NAME | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TRIGGER_CATALOG | TRIGGER_SCHEMA | TRIGGER_NAME | CATALOG_NAME | SCHEMA_NAME | TABLE_NAME | COLUMN_NAME | CURSOR_NAME | ROUTINE_CATALOG | ROUTINE_SCHEMA | ROUTINE_NAME | SPECIFIC_NAME | MESSAGE_TEXT | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH <order by clause> ::= ORDER BY <sort specification list> <updatability clause> ::= FOR ( READ ONLY | UPDATE [ OF <column name list> ] ) <temporary abstract data type declaration> ::= DECLARE TEMPORARY TYPE <abstract data type name> <abstract data type body> <temporary table declaration> ::= DECLARE LOCAL TEMPORARY <table type> <table name> <table element list> [ ON COMMIT <table commit action> ROWS ] <temporary view declaration> ::= DECLARE TEMPORARY VIEW <table name> [ <left paren> <view column list> <right paren> ] AS <query expression> <scalar subquery> ::= <subquery> <regular expression> ::= <regular term> | <regular expression> <vertical bar> <regular term> <regular term> ::= <regular factor> | <regular term> <regular factor> <regular factor> ::= <regular primary> | <regular primary> <asterisk> | <regular primary> <plus sign> <regular primary> ::= <character specifier> | <percent> | <regular character set> | <left paren> <regular expression> <right paren> <character specifier> ::= <non-escaped character> | <escaped character> <non-escaped character> ::= !! <EMPHASIS>(See the Syntax Rules) <escaped character> ::= !! <EMPHASIS>(See the Syntax Rules) <regular character set> ::= <underscore> | <left bracket> <character enumeration>... <right bracket> | <left bracket> <circumflex> <character enumeration>... <right bracket> | <left bracket> <colon> <regular character set identifier> <colon> <right bracket> <character enumeration> ::= <character specifier> | <character specifier> <minus sign> <character specifier> <regular character set identifier> ::= <identifier> <SQL object identifier> ::= <SQL provenance> <SQL variant> <SQL provenance> ::= <arc1> <arc2> <arc3> <arc1> ::= iso | 1 | iso <left paren> 1 <right paren> <arc2> ::= standard | 0 | standard <left paren> 0 <right paren> <arc3> ::= 9075 <SQL variant> ::= <SQL edition> <SQL conformance> <SQL edition> ::= <1987> | <1989> | <1992> <1987> ::= 0 | edition1987 <left paren> 0 <right paren> <1989> ::= <1989 base> <1989 package> <1989 base> ::= 1 | edition1989 <left paren> 1 <right paren> <1989 package> ::= <integrity no> | <integrity yes> <integrity no> ::= 0 | IntegrityNo <left paren> 0 <right paren> <integrity yes> ::= 1 | IntegrityYes <left paren> 1 <right paren> <1992> ::= 2 | edition1992 <left paren> 2 <right paren> <SQL conformance> ::= <low> | <intermediate> | <high> <low> ::= 0 | Low <left paren> 0 <right paren> <intermediate> ::= 1 | Intermediate <left paren> 1 <right paren> <high> ::= 2 | High <left paren> 2 <right paren> </verb></tscreen> <sect1> Extension Temporelle à SQL92 <p> <itemize> <item>Document pour l'Extension Temporelle à SQL-92 <url url="ftp://FTP.cs.arizona.edu/tsql/tsql2/"> <item> Spécification SQL-3 Temporelle <url url="ftp://FTP.cs.arizona.edu/tsql/tsql2/sql3/"> </itemize> Ce répertoire contient les spécifications pour une extension temporelle au standard du langage SQL-92. Ce nouveau langage est appelé TSQL2. Les spécifications du langage présentées ici correspondent à la version finale du langage. La correspondance doit être adressée au bureau du Comité de Conception du Langage TSQL2, Richard T.Snodgrass, Department of Computer Science, University of Arizona, Tucson, AZ 85721, <htmlurl url="mailto:rts@cs.arizona.edu" name="rts@cs.arizona.edu">. Les affiliations et les adresses électroniques des membres du Comité de Conception du langage TSQL2 peuvent être trouvées, dans un chapitre séparé, à la fin des spécifications du langage. Le contenu du répertoire est le suivant : spec.dvi,.ps Spécifications du langage TSQL2, publié en Septembre, 1994 bookspec.ps Spécifications du langage TSQL2, telles qu'elles apparaissent dans le livre sur TSQL2, publié en Septembre, 1995 (voir ci-dessous). sql3 proposition de modification soumise au comités ANSI et ISO SQL3. Un ensemble de commentaires, associés aux spécifications du langage, parle des décisions de conception, fournit des exemples, et traite de la façon dont le langage peut être implanté. Ces commentaires sont, à l'origine, des propositions faites au Comité de Conception du Langage TSQL2. Ils poursuivent actuellement un objectif différent: fournir des exemples de syntaxe, expliquer les nombreuses décisions prises durant la conception du langage, et comparer TSQL2 aux nombreuses autres propositions de langage faites au cours des quinze dernières années. Il faut insister sur le fait que ces commentaires ne font pas partie intégrante des spécifications du langage TSQL2 en lui-même, mais plutôt qu'elles le complètent et constituent un apport. Le mot de la fin est donné par les spécifications de TSQL2 proprement dit. Les commentaires, ainsi que les spécifications du langage, plusieurs index, et d'autres éléments de support ont été publiés dans un livre : Snodgrass, R.T., éditeur, The TSQL2 Temporal Query Language, (Le Langage de Requêtes Temporel TSQL2) Kluwer Academic Publishers, 1995, 674+xxiv pages. Les commentaires d'évaluation sont donnés sous forme abrégée dans le livre; La totalité des commentaires est fournie dans le fichier eval.ps situé dans ce répertoire Le fichier tl2tsql2.pl est un programme prolog qui traduit la logique temporelle autorisée en TSQL2. Ce programme a été écrit par Michael Boehlen <htmlurl url="mailto:boehlen@iesd.auc.dk" name="boehlen@iesd.auc.dk"> Il peut être contacté pour obtenir un papier qui décrit cette traduction. C'est une version tout à fait ancienne du programme. Les nouvelles versions sont disponibles à <url url="http://www.cs.auc.dk/general/DBS/tdb/TimeCenter/Software"> (the TimeDB and Tiger systems). <sect> Didacticiel SQL <p> On peut trouver ce didacticiel SQL à <url url="http://w3.one.net/~jhoffman/sqltut.htm"> Pour les commentaires ou suggestions, envoyer un courrier électronique à <htmlurl url="mailto: jhoffman@one.net" name="jhoffman@one.net"> Vous pouvez également souhaiter jeter un oeil à <url url="http://w3.one.net/~jhoffman/index.html"> John Hoffman suggère de visiter les sites suivants : <url url="http://www.contrib.andrew.cmu.edu/~shadow/sql.html">Référence SQL <url url="http://www.inquiry.com/techtips/thesqlpro/">Demandez le Pro. de SQL <url url="http://www.inquiry.com/techtips/thesqlpro/usefulsites.html">Sites utiles au Pro. du SGBD Relationnel SQL <url url="http://infoweb.magi.com/~steve/develop.html">Les Sites de sources du programmeur SGBD <url url="http://info.itu.ch/special/wwwfiles"> Allez-y et regardez le fichier comp_db.html <url url="http://www.compapp.dcu.ie/databases/f017.html">Ingrédients pour SGBD <url url="http://www.stars.com/Tutorial/CGI/">Création Web <url url="http://wfn-shop.princeton.edu/cgi-bin/foldoc">Dictionnaire d'Informatique <url url="http://www-ccs.cs.umass.edu/db.html">DBMS Lab/Liens SQL FAQ <url url="http://epoch.CS.Berkeley.EDU:8000/sequoia/dba/montage/FAQ"> Allez-y et regardez le fichier SQL_TOC.html <url url="http://chaos.mur.csu.edu.au/itc125/cgi/sqldb.html">SGBD SQL <url url="http://www.it.rit.edu/~wjs/IT/199602/icsa720/icsa720postings.html">Page de Conception de Bases de Données RIT <url url="http://www.pcslink.com/~ej/dbweb.html">Site de liens vers des Bases de Données <url url="http://www.eng.uc.edu/~jtilley/tutorial.html">Didacticiels de programmation sur le Web <url url="http://www.ndev.com/ndc2/support/resources.htp">Ressources pour le Développement <url url="http://ashok.pair.com/sql.htm">Liste de Requêtes <url url="http://jazz.external.hp.com/training/sqltables/main.html">IMAGE SQL Diverses <url url="http://www.eit.com/web/netservices.html">Liste de Ressources Internet Voici, ci-dessous, un extrait de la page d'accueil du didacticiel SQL. <tscreen><verb> Introduction au Langage de Requête Structuré Version 3.31 Cette page contient un didacticiel du Langage de Requête Structuré( Structured Query Language, également connu sous le nom de SQL). Ce didacticiel constitue une nouveauté sur le World Wide Web, car c'est le premier didacticiel SQL complet disponible sur l'Internet. SQL permet l'accès aux données dans les systèmes de gestion de bases de données relationnels tels que Oracle, Sybase, Informix, Microsoft SQL Server, Access, et autres en permettant aux utilisateurs de décrire les données qu'ils désirent obtenir. SQL permet aussi aux utilisateurs de définir l'organisation des données dans la base et de les manipuler. Le but de cette page est de décrire l'utilisation de SQL, et de donner des exemples. C'est le langage ANSI SQL, ou standard SQL, qui sera utilisé dans ce document. Il ne sera pas question ici des fonctionnalités spécifiques à un SGBD particulier, qui seront traitées dans la section "SQL non-standard". Nous vous recommandons d'imprimer cette page afin de pouvoir vous référer facilement aux différents exemples. ---------------------------------------------------------------------------- Table des matières Principes fondamentaux de l'instruction SELECT Sélection Conditionnelle Opérateurs Relationnels Conditions Composées IN & BETWEEN Utilisation de LIKE Jointures Clés Réalisation d'une Jointure Elimination des Doubles Alias & In/Sous-requêtes Fonctions d'Agrégation Vues Création de Nouvelles Tables Modification des Tables Ajout de Données Suppression de Données Mise à Jour des Données Index GROUP BY & HAVING Sous-requêtes Supplémentaires EXISTS & ALL UNION & Jointures Externes SQL Intégré Questions Courantes sur SQL SQL Non-standard Résumé de la Syntaxe Liens Importants ---------------------------------------------------------------------------- Principes fondamentaux de l'instruction SELECT Dans une base de données relationnelle, les données sont stockées dans des tables. Par exemple, une table pourrait mettre en relation le Numéro de Sécurité Sociale, le Nom et l'Adresse: TableAdresseEmploye NSS Prenom Nom Addresse Ville Etat 512687458Joe Smith 83 First Street Howard Ohio 758420012Mary Scott 842 Vine Ave. LosantivilleOhio 102254896Sam Jones 33 Elm St. Paris New York 876512563Sarah Ackerman 440 U.S. 110 Upton Michigan Maintenant, supposons que nous voulions obtenir l'adresse de chaque employé. On utilisera SELECT, comme ceci : SELECT Prenom, Nom, Adresse, Ville, Etat FROM TableAdresseEmploye; Voici le résultat de l'interrogation de notre base de données : Prenom Nom Adresse Ville Etat Joe Smith 83 First Street Howard Ohio Mary Scott 842 Vine Ave. Losantiville Ohio Sam Jones 33 Elm St. Paris New York Sarah Ackerman 440 U.S. 110 Upton Michigan Explication de ce que l'on vient de faire : on vient de rechercher dans toutes les données de la table TableAdresseEmploye les colonnes nommées Prenom, Nom, Adresse, Ville et Etat. Noter que les noms de colonnes et les noms de tables sont sans espaces... ils doivent être saisis en un seul mot; et que l'instruction se termine par un point-virgule (;). La forme générale d'une instruction SELECT, qui permet de retrouver toutes les lignes d'une table est : SELECT NomColonne, NomColonne, ... FROM NomTable; Pour obtenir toutes les colonnes d'une table sans avoir à taper tous les noms de colonne, utiliser : SELECT * FROM NomTable; Chaque Système de Gestion de Base de Données (SGBD) et chaque logiciel de base de données utilisent différentes méthodes pour se connecter à la base de donnée et pour entrer les instructions SQL; consultez le "guru" de votre ordinateur pour qu'il vous aide à vous connecter de façon à pouvoir utiliser SQL. ---------------------------------------------------------------------------- Sélection Conditionnelle Pour étudier plus avant l'instruction SELECT , jetons un oeil à un nouvel exemple de table (exemple uniquement hypothétique) : EmployeeStatisticsTable EmployeeIDNo Salary Benefits Position 010 75000 15000 Manager 105 65000 15000 Manager 152 60000 15000 Manager 215 60000 12500 Manager 244 50000 12000 Staff 300 45000 10000 Staff 335 40000 10000 Staff 400 32000 7500 Entry-Level 441 28000 7500 Entry-Level ---------------------------------------------------------------------------- Opérateurs Relationnels Il y a six Opérateurs Relationnels en SQL, et, après les avoir présentés, nous verrons comment les utiliser : = Egal <> or != (voir le manuel) Différent < Plus Petit Que > Plus Grand Que <= Plus Petit Que ou Egal à >= Plus Grand Que ou Egal à La clause WHERE est utilisée pour spécifier que l'on affichera seulement certaines ligne de la table, selon un critère définit par cette clause WHERE. Ce sera plus clair en prenant une paire d'exemples. Si l'on désire voir les numéros d'identification des employés (EMPLOYEEIDNO) dont le salaire est égal ou supérieur à 50 000, on utilisera la requête suivante : SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE SALARY >= 50000; Noter que le symbole >= (plus grand que ou égal à) est utilisé, puisque l'on désire voir tout ceux qui gagnent plus de 50 000, ou 50 000, sur la même liste. On aura l'affichage : EMPLOYEEIDNO ------------ 010 105 152 215 244 La description de WHERE, SALARY >= 50000, est appelée une condition. On pourrait effectuer le même traitement sur des colonnes de texte : SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE POSITION = 'Manager'; Ceci entraînera l'affichage des Numéros d'Identification de tous les Managers. En général, avec les colonnes contenant du texte, n'utiliser que égal à ou différent de, et assurez vous que tout texte apparaissant dans l'instruction est entouré d'apostrophes ('). ---------------------------------------------------------------------------- Conditions plus complexes: Conditions Composées L'opérateur AND (ET) combine deux ou plusieurs conditions et n'affiche une ligne que si cette ligne satisfait TOUTES les conditions requises (i.e. où toutes les conditions sont réalisées). Par exemple, pour afficher tout le personnel gagnant plus 40 000, écrire : SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE SALARY > 40000 AND POSITION = 'Staff'; L'opérateur OR (OU) combine deux ou plusieurs conditions mais retourne cette ligne si N'IMPORTE LAQUELLE des conditions requises est remplie. Pour visualiser tous ceux qui gagnent moins de 40 000 ou qui reçoivent moins de 10 000 en participation aux bénéfices, utilisez la requête suivante : SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE SALARY < 40000 OR BENEFITS < 10000; Les opérateurs AND et OR peuvent être combinés, par exemple : SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE POSITION = 'Manager' AND SALARY > 60000 OR BENEFITS > 12000; En premier lieu, SQL recherche les lignes pour lesquelles la valeur de la colonne salaire est supérieure à 60 000 et celle de position est égale à Manager, puis, à partir de cette liste de lignes, SQL recherche alors celles qui satisfont à la condition AND (ET) précédente ou à la condition spécifiant que la colonne Indemnités est supérieure à 12 000. En conséquence, SQL n'affiche seulement que cette seconde liste de lignes, en gardant à l'esprit que tous ceux dont les Indemnités sont supérieures à 12 000 en feront partie puisque l'opérateur OR (OU) inclue la ligne si l'une des conditions est vérifiée. Notez en passant que l'opération AND (ET) est effectuée en premier. Pour généraliser ce processus, SQL effectue l(es) opération(s) AND pour déterminer les lignes ou l(es) opération(s) AND sont vérifiées (souvenez-vous bien : toutes les conditions sont vérifiées), puis ces résultats sont utilisés pour tester les conditions OR, et, ne seront affichées que les lignes où les conditions requises par l'opérateur OR seront vérifiées. Pour que les OR's soient effectués avant les AND's, par exemple si vous vouliez voir une liste des employés dont le salaire est élevé (>50 000) OU bénéficiant d'indemnités importantes (>10 000), ET qui soient cadres, utilisez des parenthèses : SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE POSITION = 'Manager' AND (SALARY > 50000 OR BENEFIT > 10000); ---------------------------------------------------------------------------- IN et BETWEEN Une méthode plus facile pour utiliser les conditions composées consiste à utiliser IN ou BETWEEN. Par exemple, si vous désirez une liste des cadres et du personnel : SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE POSITION IN ('Manager', 'Staff'); ou une liste de ceux dont le salaire est supérieur ou égal à 30 000, mais inférieur ou égal à 50 000, utilisez: SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE SALARY BETWEEN 30000 AND 50000; Pour obtenir la liste de ceux qui n'entrent pas dans ces critères, essayez : SELECT EMPLOYEEIDNO FROM EMPLOYEESTATISTICSTABLE WHERE SALARY NOT BETWEEN 30000 AND 50000; De la même façon, NOT IN donne la liste de toutes les lignes exclues de la liste obtenue par l'opérateur IN. ---------------------------------------------------------------------------- Utilisation de LIKE Regardons la table EmployeeStatisticsTable, et disons que l'on veut voir tous les gens dont le nom commence par "L"; essayons : SELECT EMPLOYEEIDNO FROM EMPLOYEEADDRESSTABLE WHERE LASTNAME LIKE 'L%'; Le signe pourcentage (%) est utilisé pour représenter n'importe quel caractère possible (nombre, lettre, ou signe de ponctuation) ou ensemble de caractères qui peut apparaître après le "L". Pour trouver les gens dont le Nom se termine avec "L", utiliser '%L', ou si vous désirez le "L" au milieu du mot, essayez '%L%'. Le symbole '%' peut être utilisé pour n'importe quel caractère, et dont la position est relative par rapport à des caractères donnés. NOT LIKE affiche les lignes qui ne correspondent pas à la description donnée. Il y a d'autres manières d'utiliser LIKE, de même que n'importe lesquelles des conditions composées dont nous venons de parler, bien que cela dépende du SGBD que vous utilisez; comme d'habitude, consultez un manuel ou le gestionnaire ou administrateur de votre système pour en connaître les fonctionnalités, ou simplement, assurez vous que ce que vous essayer de faire est possible et autorisé. Cet avertissement est aussi valable pour les fonctionnalités de SQL exposées ci-dessous. Cette section est donnée à titre d'exemple des requêtes qui peuvent être écrites en SQL. ---------------------------------------------------------------------------- Jointures Dans cette section, nous allons parler uniquement des jointures internes et des equi-jointures, dans la mesure où ce sont les plus utiles. Pour avoir plus d'informations, voyez les liens sur des sites SQL au bas de cette page. On suggère qu'une bonne manière de concevoir une base de données implique que chaque table ne contienne des données qui ne concernent qu'une seule entité, et que des informations détaillées peuvent être obtenues, dans une base de données relationnelle, en utilisant des tables supplémentaires et en effectuant une jointure. Premièrement, jetons un oeil à ces exemples de tables : AntiqueOwners OwnerIDOwnerLastName OwnerFirstName 01 Jones Bill 02 Smith Bob 15 Lawson Patricia 21 Akins Jane 50 Fowler Sam --------------------------------------------------------- Orders OwnerIDItemDesired 02 Table 02 Desk 21 Chair 15 Mirror -------------------------------------- Antiques SellerIDBuyerID Item 01 50 Bed 02 15 Table 15 02 Chair 21 50 Mirror 50 01 Desk 01 21 Cabinet 02 21 Coffee Table 15 50 Chair 01 15 Jewelry Box 02 21 Pottery 21 02 Bookcase 50 01 Plant Stand ---------------------------------------------------------------------------- Clés En premier lieu, nous allons parler du concept de clés. Une clé primaire est une colonne ou en ensemble de colonnes qui identifie de manière unique les autres données d'une ligne donnée. Par exemple, dans la table AntiqueOwners, la colonne OwnerID identifie de manière unique cette ligne. Ceci signifie deux choses: que deux lignes ne peuvent avoir le même OwnerID, et que, même si deux propriétaires les mêmes noms et prénoms la colonne OwnerID garantit que ces deux propriétaires ne seront pas confondus l'un avec l'autre, puisque la colonne OwnerID unique sera utilisée à travers la base de données pour se référer à un propriétaire, plutôt que son nom. Une clé externe est une colonne d'une table qui est clé primaire d'une autre table, ce qui signifie que toutes les données d'une clé externe doivent avoir des données correspondantes dans l'autre table, où cette colonne est la clé primaire. Pour parler SGBD, cette correspondance est connue sous le nom d'intégré référentielle. Par exemple, dans la table Antiques, BuyerID et SellerID sont tous les deux des clés externes à la clé primaire de la table AntiqueOwners (OwnerID; pour les besoins de notre argumentation, on doit d'abord être référencé dans la table AntiqueOwners avant de pouvoir acheter ou vendre quoi que ce soit), puisque, dans les deux tables, les colonnes ID sont utilisées pour identifier les propriétaires, les acheteurs ou les vendeurs, et que OwnerID est la clé primaire de la table AntiqueOwners. En d'autres termes, toutes ces données "ID" sont utilisées pour se référer aux propriétaires, acheteurs et vendeurs sans avoir à utiliser les noms effectifs. ---------------------------------------------------------------------------- Réalisation d'une jointure Le but de ces clés est ainsi de pouvoir mettre en relation les données à travers les tables sans avoir à répéter les données dans chaque tables, --c'est toute la puissance des bases de données relationnelles. Par exemple, on peut trouver les noms de ceux qui ont acheté une chaise sans avoir à lister la totalité du nom de l'acheteur dans la table Antiques... vous pouvez trouver ce nom en mettant en relation ceux qui ont acheté une chaise avec les noms dans la table AntiqueOwners en utilisant le OwnerID, qui met en relation les données dans les deux tables. Pour trouver les noms de ceux qui ont acheté une chaise, utilisez la requête suivante : SELECT OWNERLASTNAME, OWNERFIRSTNAME FROM ANTIQUEOWNERS, ANTIQUES WHERE BUYERID = OWNERID AND ITEM = 'Chair'; Notez ce qui suit au sujet de cette requête... notez que les deux tables mise en jeux dans cette relation sont listées dans la clause FROM de l'instruction. Dans la clause WHERE, notez, en premier lieu, que la partie ITEM = 'Chair' de la clause limite la liste à ceux qui ont acheté (et, dans cet exemple, de ce fait possèdent) une chaise. En second lieu, notez comment les colonnes ID sont mises en relation d'une table à la suivante par l'utilisation de la clause BUYERID = OWNERID. Ne seront listés que les noms de la table AntiqueOwners dont les ID correspondent à travers les tables et dont l'article acheté est une chaise (à cause du AND). Parce que la condition de jointure utilisée est un signe égal, cette jointure est appelée une équi-jointures. le résultat de cette requête donnera deux noms: Smith, Bob et Fowler, Sam. La notation avec un point (.) fait référence à l'utilisation du nom de colonne en suffixe du nom de table pour éviter toute ambiguïté, comme par exemple: SELECT ANTIQUEOWNERS.OWNERLASTNAME, ANTIQUEOWNERS.OWNERFIRSTNAME FROM ANTIQUEOWNERS, ANTIQUES WHERE ANTIQUES.BUYERID = ANTIQUEOWNERS.OWNERID AND ANTIQUES.ITEM = 'Chair'; Cependant, puisque les noms de colonnes sont différents dans chaque table, cela n'était pas nécessaire. ---------------------------------------------------------------------------- DISTINCT et l'Elimination des Doubles Disons que vous ne vouliez seulement que la liste des Identificateurs (ID) et des noms des gens qui ont vendu une antiquité. Evidemment, vous ne désirez une liste où chaque vendeur n'apparaît qu'une fois--vous ne voulez pas savoir combien d'antiquités ont été vendues par une personne, mais uniquement le fait que cette personne en a vendu une (pour les comptages, voir la fonction d'Agrégation ci-dessous). Cela signifie qu'il vous faudra dire à SQL d'éliminer les doubles des lignes des ventes, et de ne seulement lister chaque personne qu'une fois. Pour réaliser cela, utilisez le mot-clé DISTINCT. Premièrement, vous aurez besoin de faire un équi-jointures sur la table AntiqueOwners pour obtenir les données concernant le Nom et le Prénom de la personne. Cependant, gardez à l'esprit que, puisque la colonne SellerID dans la table Antiques est une clé externe de la table AntiqueOwners, un vendeur ne sera listé que s'il y a une ligne dans la table AntiqueOwners contenant les ID et les noms. Nous voulons également éliminer les multiples occurrences du SellerID dans notre liste, donc, nous utiliserons le mot-clé DISTINCT pour les colonnes où les répétitions peuvent se produire. Pour ajouter une difficulté, nous voulons aussi que cette liste soit classée par ordre alphabétique des Noms, puis des Prénoms (à l'intérieur des noms), puis des OwnerID (à l'intérieur des noms et des prénoms). Pour cela, nous utiliserons la clause ORDER BY : SELECT DISTINCT SELLERID, OWNERLASTNAME, OWNERFIRSTNAME FROM ANTIQUES, ANTIQUEOWNERS WHERE SELLERID = OWNERID ORDER BY OWNERLASTNAME, OWNERFIRSTNAME, OWNERID; Dans cet exemple, puisque tout le monde a vendu un article, nous aurons une liste de tous les propriétaires, classés par ordre alphabétique sur les noms. Pour référence ultérieure (au cas où quelqu'un le demande), ce type de jointure est considéré comme appartenant à la catégorie des jointures internes. ---------------------------------------------------------------------------- Alias et In/Sous-requêtes Dans cette section, nous parlerons des Alias, In et de l'utilisation des sous-requêtes, et de la manière de les utiliser dans un exemple de 3-table. En premier lieu, regardez cette requête qui imprime le nom des propriétaires qui ont passé une commande et la nature de cette commande, en ne listant seulement que les commandes qui peuvent être satisfaites (c'est à dire qu'il y a un vendeur qui possède l'article commandé) : SELECT OWN.OWNERLASTNAME Last Name, ORD.ITEMDESIRED Item Ordered FROM ORDERS ORD, ANTIQUEOWNERS OWN WHERE ORD.OWNERID = OWN.OWNERID AND ORD.ITEMDESIRED IN (SELECT ITEM FROM ANTIQUES); Ce qui donne : Last name Item Ordered --------- ------------ Smith Table Smith Desk Akins Chair Lawson Mirror Il y a plusieurs choses à noter à propos de cette requête : 1. Tout d'abord, les mots "Last Name" et "Item Ordered" dans les lignes SELECT donnent les en-têtes du rapport. 2. Les mots OWN et ORD sont des alias; ce sont de nouveaux noms pour les deux tables données dans la clause FROM qui sont utilisés comme préfixes pour toutes les notations point (.) de noms de colonnes dans les requêtes (voir ci-dessus). Ceci élimine les risques ambiguïté, spécialement dans l'équi-jointure de la clause WHERE où les deux tables ont une colonne nommée OwnerID, et cette notation point (.) précise à SQL que nous désignons deux OwnerID différents de deux tables différentes. 3. Notez que la table des commandes (ORDERS) est indiquée la première dans la clause FROM; ceci apporte la certitude que la liste sera réalisée à partir de cette table, et que la table AntiqueOwners est utilisée uniquement pour obtenir les informations détaillées (Last Name / Nom). 4. Plus important, la clause AND dans la clause WHERE (OU) force l'utilisation de la Sous-requête In ("= ANY" ou "= SOME" sont deux utilisations équivalentes de IN). Cela entraîne que la sous-requête est effectuée, retournant une liste de tous les articles (Items) appartenant à la table Antiques, comme s'il n'y avait pas de clause WHERE (OU). Donc, pour lister une ligne de la table ORDERS, le ItemDesired (article_désiré) doit être dans la liste retournée des articles appartenant à la table Antiques, et donc un article ne sera listé que si la commande ne peut être honorée que par un autre propriétaire. On peut se le représenter comme ceci: la sous-requête retourne un ensemble d'articles (Items) auquel chaque ItemDesired (Article_Désiré) dans la table des commandes (ORDERS) est comparé; la condition IN (DANS) n'est vraie que si le ItemDesired appartient à l'ensemble provenant de la table ANTIQUES. 5. Notez également, comme c'est le cas ici, qu'il y a un objet ancien pour chaque demande, ce qui, évidemment, n'est pas toujours le cas... De plus, notez aussi que, lorsque IN, "= ANY", ou "= SOME" est utilisé, ces mots-clés font référence à toutes les lignes qui conviennent, pas aux colonnes... c'est à dire que vous ne pouvez pas mettre de multiples colonnes dans un clause SELECT de sous-requête, pour tenter de faire correspondre la colonne de la clause WHERE externe avec l'une des multiples valeurs de colonnes possibles de la sous-requête; une seule colonne peut être indiquée dans la sous-requête, et la correspondance possible provient de multiples valeurs de lignes, dans cette colonne unique, et non pas l'inverse. Ouf! Ce sera tout sur ce sujet des requêtes SELECT complexes pour l'instant. Maintenait, voyons d'autres instructions SQL. ---------------------------------------------------------------------------- Instructions SQL Diverses Fonctions d'Agrégation Je parlerai de cinq fonctions d'agrégation importantes: SUM, AVG, MAX, MIN, et COUNT. On les appelle fonctions d'agrégation parce qu'elles résument les résultats d'une requête, plutôt que de donner une liste de toutes les lignes. * SUM () donne la somme, pour une colonne donnée, de toutes les lignes qui satisfont aux conditions requises, et où la colonne donnée est numérique. * AVG () donne la moyenne de la colonne donnée. * MAX () donne la plus grande valeur dans la colonne donnée. * MIN () donne la plus petite valeur dans la colonne donnée. * COUNT(*) donne le nombre de lignes qui satisfont aux conditions. En utilisant les tables du début de ce document, regardons trois exemples : SELECT SUM(SALARY), AVG(SALARY) FROM EMPLOYEESTATISTICSTABLE; Cette requête donne la somme des de salaires tous les salariés présents dans la table et le salaire moyen. SELECT MIN(BENEFITS) FROM EMPLOYEESTATISTICSTABLE WHERE POSITION = 'Manager'; Cette requête donne le chiffre de la colonne indemnités le plus faible des employés qui sont Managers, cette valeur est 12 500. SELECT COUNT(*) FROM EMPLOYEESTATISTICSTABLE WHERE POSITION = 'Staff'; Cette requête vous donne le nombre d'employés ayant le statut de cadre (Staff, i.e. 3). ---------------------------------------------------------------------------- Les Vues En SQL, vous pouvez (vérifiez auprès de votre Administrateur de Base de Données, DBA) avoir accès à la création de vues par vous-même. Une vue vous permet d'affecter les résultats d'une requête à une nouvelle table personnelle, que vous pourrez utiliser dans d'autres requêtes, pour laquelle vous donnez le nom de la vue dans votre clause FROM. Quand vous accédez à une vue, la requête qui est définie dans l'instruction de création de la vue est effectuée (généralement), et les résultats de cette requête ont la même allure qu'une autre table dans la requête que vous avez écrit en invoquant la vue. Par exemple, pour créer une vue : CREATE VIEW ANTVIEW AS SELECT ITEMDESIRED FROM ORDERS; Maintenant, écrivons une requête utilisant cette vue comme une table, où la table est seulement une liste de tous les articles désirés (ITEMDESIRED) de la table ORDERS : SELECT SELLERID FROM ANTIQUES, ANTVIEW WHERE ITEMDESIRED = ITEM; Cette table montre tous les Identifiants de Vendeurs (SellerID) de la table ANTIQUES où l'article (Item) dans cette table apparaît dans la vue ANTVIEW, qui consiste justement en tous les Articles Désirés (Items Desired) dans la table ORDERS. La liste est crée en parcourant les articles AntiquesItems un par un jusqu'à ce qu'il y ait correspondance avec la vue ANTVIEW. Les vues peuvent être utilisées pour restreindre les accès à la base de données, ainsi que, dans ce cas, pour simplifier une requête complexe. ---------------------------------------------------------------------------- Création de Nouvelles Tables Toutes les tables, dans une base de données doivent être créées à un certain moment... voyons comment mous pourrions créer la table des commandes (ORDERS) : CREATE TABLE ORDERS (OWNERID INTEGER NOT NULL, ITEMDESIRED CHAR(40) NOT NULL); Cette instruction donne un nom à la table et renseigne le SGBD sur la nature de chaque colonne de la table. Veuillez noter que cette instruction utilise des types de données génériques, et que les types de données peuvent être différents, selon le SGBD que vous utilisez. Comme d'habitude, vérifiez vos conditions locales. Voici quelques types de données génériques courants: * Char(x) - Une colonne de caractères, où x est un nombre indiquant le nombre maximum de caractères permis (taille maximale) de la colonne. * Integer - Une colonne de nombres entiers, positifs ou négatifs. * Decimal(x, y) - Une colonne de nombre décimaux, où x est la taille maximum, en digits, des nombres décimaux dans cette colonne, et y le nombre maximal de digits autorisés après la virgule. Le nombre maximal (4,2) sera 99.99. * Date - Une colonne de date dans un format spécifique au SGBD. * Logical - Une colonne qui ne peut contenir que deux valeurs: VRAI ou FAUX. Autre remarque, l'indication NOT NULL (non nul) signifie que la colonne doit avoir une valeur pour chacune des lignes. Si l'on avait utilisé NULL (nul), cette colonne peut être laissée vide dans certaines lignes. ---------------------------------------------------------------------------- Modification des tables Ajoutons une colonne à la table ANTIQUES pour permettre la saisie du prix d'un article donné : ALTER TABLE ANTIQUES ADD (PRICE DECIMAL(8,2) NULL); On verra plus tard comment les données pour cette nouvelle colonne peuvent être mises à jour ou ajoutées. ---------------------------------------------------------------------------- Ajout de Données Pour insérer des lignes dans une table, faites ce qui suit : INSERT INTO ANTIQUES VALUES (21, 01, 'Ottoman', 200.00); Ceci insère les données dans la table, en tant que nouvelle ligne, colonne par colonne, dans un ordre prédéfinit. Au lieu de cela, changeons cet ordre et laissons le Prix vide: INSERT INTO ANTIQUES (BUYERID, SELLERID, ITEM) VALUES (01, 21, 'Ottoman'); ---------------------------------------------------------------------------- Suppression de données Supprimons cette nouvelle ligne de la base de données : DELETE FROM ANTIQUES WHERE ITEM = 'Ottoman'; Mais s'il y a une autre ligne qui contient 'Ottoman', cette ligne sera également supprimée. Supprimons toutes les lignes (une, dans ce cas) qui contient les données spécifiques que nous avons ajouté plus tôt : DELETE FROM ANTIQUES WHERE ITEM = 'Ottoman' AND BUYERID = 01 AND SELLERID = 21; ---------------------------------------------------------------------------- Mise à Jour des Données Mettons un Prix à jour dans une ligne qui n'en contient pas encore : UPDATE ANTIQUES SET PRICE = 500.00 WHERE ITEM = 'Chair'; Ceci met le Prix de toutes les Chaises (Chair) à 500.00. Comme indiqué ci-dessus, conditions WHERE supplémentaires, utilisation de AND, il faut utiliser ces conditions pour limiter la mise à jour à des lignes spécifiques. De plus, des colonnes supplémentaires peuvent être renseignées en séparant les instructions "égal" par des virgules. ---------------------------------------------------------------------------- Considérations Diverses Index Les Index permettent à un SGBD d'accéder au données plus rapidement (veuillez noter que cette fonctionnalité est non-standard/indisponible sur certains systèmes). Le système crée une structure de donnée interne (l'index) qui entraîne une sélection de lignes beaucoup plus rapide, quand la sélection est basée sur des colonnes indexées. Cet index indique au SGBD où se trouve une certaine ligne dans une table étant donné une valeur de colonne indexée, exactement comme l'index d'un livre vous indique à quelle page un mot donné se trouve. Créons un index pour le OwnerID dans la colonne AntiqueOwners : CREATE INDEX OID_IDX ON ANTIQUEOWNERS (OWNERID); Maintenant sur les noms: CREATE INDEX NAME_IDX ON ANTIQUEOWNERS (OWNERLASTNAME, OWNERFIRSTNAME); Pour être débarrassé d'un index, supprimez le : DROP INDEX OID_IDX; A propos, vous pouvez aussi bien "supprimer" une table (attention!--cela signifie que votre table est détruite). Dans le second exemple, l'index est construit à partir des deux colonnes, agrégées ensembles--un comportement bizarre peut résulter de cette situation... vérifiez dans votre manuel avant d'effectuer une telle opération. Quelques SGBD n'imposent pas l'utilisation de clés primaires; en d'autres termes, l'unicité d'une colonne n'est pas imposée automatiquement. Cela signifie que, par exemple, j'aurais pu essayer d'insérer une autre ligne dans la table AntiqueOwners avec un OwnerID de 02, quelques systèmes me permettent de faire cela, bien qu'il ne le faille pas, puisque cette colonne est supposée être unique dans cette table (chaque valeur de ligne est supposée être différente). Une manière de contourner cela est de créer un index unique sur la colonne que nous souhaitons voir être la clé primaire pour forcer le système à interdire les doubles : CREATE UNIQUE INDEX OID_IDX ON ANTIQUEOWNERS (OWNERID); ---------------------------------------------------------------------------- GROUP BY et HAVING Une utilisation spéciale de la clause GROUP BY est l'association d'une fonction agrégée (spécialement COUNT; qui compte le nombre de lignes dans chaque groupe) avec des groupes de lignes. Premièrement, supposons que la table ANTIQUES possède la colonne Prix (Price)t, et que chaque ligne contienne une valeur dans cette colonne. Nous voulons voir le prix de l'article le plus cher acheté par chaque propriétaire. Il nous faut donc dire à SQL de grouper les achats de chacun des propriétaires, et de nous dire le prix d'achat maximum : SELECT BUYERID, MAX(PRICE) FROM ANTIQUES GROUP BY BUYERID; Maintenant, disons que nous ne voulons voir que le prix maximum si l'achat dépasse 1000, nous devrons utiliser la clause HAVING : SELECT BUYERID, MAX(PRICE) FROM ANTIQUES GROUP BY BUYERID HAVING PRICE > 1000; ---------------------------------------------------------------------------- Sous-requêtes Supplémentaires Un autre usage commun des sous-requêtes amène à l'utilisation des opérateurs pour permettre à une condition WHERE d'inclure la sortie SELECT d'une sous-requête. En premier, demandons la liste des acheteurs ayant acheté un article cher (le prix de cet article est supérieur de 100 au prix moyen de tous les articles achetés) : SELECT OWNERID FROM ANTIQUES WHERE PRICE > (SELECT AVG(PRICE) + 100 FROM ANTIQUES); La sous-requête calcule le Prix moyen, ajoute 100, et, et en utilisant ce chiffre on imprime un OwnerID pour chaque article coûtant plus que ce chiffre. On peut utiliser DISTINCT OWNERID, pour éliminer les doubles. Listons les Noms (Last Names) de ceux qui sont dans la table AntiqueOwners, SEULEMENT s'ils ont acheté un article : SELECT OWNERLASTNAME FROM ANTIQUEOWNERS WHERE OWNERID = (SELECT DISTINCT BUYERID FROM ANTIQUES); Cette sous-requête retourne une liste des acheteurs, et le Nom du propriétaire d'un objet ancien est imprimé seulement si l'identificateur du Propriétaire (Owner's ID) dans la liste obtenue par la sous-requête (appelée quelquefois liste des candidats). Voici un exemple de mise à jour: nous savons que la personne qui a acheté la bibliothèque a un Prénom erroné dans la base de données... Ce devrait être John : UPDATE ANTIQUEOWNERS SET OWNERFIRSTNAME = 'John' WHERE OWNERID = (SELECT BUYERID FROM ANTIQUES WHERE ITEM = 'Bookcase'); Tout d'abord, la sous-requête trouve le BuyerID pour la (les) personne(s) qui a (ont) acheté(s) la bibliothèque, puis la requête externe met à jour son Prénom. Souvenez vous de cette règle à propos des sous-requêtes: quand vous avez une sous-requête faisant partie d'une condition WHERE, la clause SELECT dans la sous-requête doit avoir des colonnes qui correspondent en nombre et en type à celle de la clause WHERE de la requête externe. En d'autres termes, si vous avez "WHERE ColumnName = (SELECT...);", le SELECT ne peut faire référence qu'à une seule colonne, pour pouvoir correspondre à la clause WHERE externe, et elles doivent être du même type (les deux étant soit entiers, soit chaînes de caractères, etc.). ---------------------------------------------------------------------------- EXISTS et ALL EXISTS utilise une sous-requête comme condition, où cette condition est Vraie si la sous-requête retourne au moins une ligne et Fausse si la sous-requête n'en retourne aucune; c'est une fonctionnalité qui n'est pas intuitive et n'est utilisée que dans peu de cas. Cependant, si un client éventuel voulait consulter la liste des propriétaires pour voir s'il y a des chaises (Chairs), essayez : SELECT OWNERFIRSTNAME, OWNERLASTNAME FROM ANTIQUEOWNERS WHERE EXISTS (SELECT * FROM ANTIQUES WHERE ITEM = 'Chair'); S'il y a des Chaises (Chair) dans une colonne de la table ANTIQUES, la sous-requête renverra une ou plusieurs lignes, rendant la clause EXISTS vraie, ce qui amènera SQL à donner une liste des propriétaires dans ANTIQUEOWNERS. S'il n'y avait eu aucune Chaise, la requête externe n'aurait pas renvoyé de ligne. ALL est une autre fonctionnalité peu commune, et en général, on peut réaliser une requête avec ALL de manières différentes et éventuellement plus simples; regardons cet exemple de requête : SELECT BUYERID, ITEM FROM ANTIQUES WHERE PRICE >= ALL (SELECT PRICE FROM ANTIQUES); Ceci va nous retourner l'article de prix le plus élevé (ou plus d'un article s'il y a des ex-aequo), et son acheteur. La sous-requête renvoie la liste de tous les Prix (PRICE) dans la table ANTIQUES, puis la requête externe examine chaque ligne de la table ANTIQUES et si son Prix est supérieur ou égal à chacun (ou ALL, TOUS) des Prix de cette liste, il est affiché, donnant ainsi l'article de prix le plus élevé. La raison pour laquelle ">=" doit être utilisé est que l'article de prix le plus élevé sera égal au prix le plus élevé, puisque cet Article est dans la liste de Prix. ---------------------------------------------------------------------------- UNION et Jointure Externe Il y a des occasions où vous pouvez désirer voir ensembles les résultats de requêtes multiples, leurs sorties étant combinées; pour cela utilisez UNION. Pour fusionner la sortie des deux requêtes suivantes, en affichant l'identificateur de tous les Acheteurs plus tous ceux qui ont passé une Commande : SELECT BUYERID FROM ANTIQUEOWNERS UNION SELECT OWNERID FROM ORDERS; Il faut noter que SQL nécessite que les types de données des listes des clauses SELECT correspondent colonne par colonne. Dans cet exemple, les identificateurs BuyerID et OwnerID sont du même type (entier). Notez également que SQL effectue automatiquement une élimination des doubles quand on utilise la clause UNION (comme si c'étaient deux "ensembles"); dans une requête simple, il faut utiliser la clause DISTINCT. La jointure externe est utilisée quand une requête de jointure est "unifiée", les lignes n'étant pas incluses dans la jointure. Ceci est particulièrement utile si des "balises" de type constante texte sont inclus. D'abord, regardez la requête : SELECT OWNERID, 'is in both Orders & Antiques' FROM ORDERS, ANTIQUES WHERE OWNERID = BUYERID UNION SELECT BUYERID, 'is in Antiques only' FROM ANTIQUES WHERE BUYERID NOT IN (SELECT OWNERID FROM ORDERS); La première requête effectue une jointure pour lister tous les propriétaires qui sont dans les deux tables, et met une balise après l'identificateur (ID) en insérant le texte correspondant à la balise. La clause UNION fusionne cette liste avec la liste suivante. La seconde liste est générée premièrement en listant les identificateurs (ID) qui ne sont pas dans la table ORDERS, c'est à dire en générant une liste des ID exclus de la requête de jointure.. Puis, chaque ligne de la table ANTIQUES est analysée, et, si l'identifiant de l'acheteur (BuyerID) n'est pas dans cette liste d'exclusion, il est listé avec le texte correspondant à sa balise. Il y aurait peut-être une meilleure manière de créer cette liste, mais c'est difficile de générer des balises informationnelles. Ce concept est utile dans des situations où une clé primaire est en relation avec une clé externe, et où la valeur de la clé externe est NULLE (NULL) pour quelques clés primaires. Par exemple, dans une table, la clé primaire est vendeur, et dans une autre table client, avec le vendeur enregistré dans la même ligne. Cependant, si un vendeur n'a pas de clients, le nom de cette personne n'apparaîtra pas dans la table des clients. Une jointure externe sera utilisée pour imprimer une liste de tous les vendeurs, avec leurs clients, que le vendeur ait un client ou pas--c'est à dire qu'il n'y aura pas de client imprimé (valeur logique NULL) si le vendeur n'a pas de client, mais existe dans la table des vendeurs. Autrement, le vendeur sera listé avec chaque client. ASSEZ DE REQUETES!!! Qu'est-ce que vous dites?...Eh bien, maintenant voyons quelque chose de complètement différent... ---------------------------------------------------------------------------- SQL incorporé--un vilain exemple (n'écrivez pas un programme comme cela... il est là UNIQUEMENT à titre d'exemple) /* -Voici un exemple de programme qui utilise le SQL incorporé (Embedded SQL). Le SQL incorporé permet aux programmeurs de se connecter à une base de données et d'inclure du code SQL en plein programme, et ainsi, leurs programmes peuvent utiliser, manipuler, et traiter les données d'une base de données. -Cet exemple de Programme C (qui utilise du SQL incorporé) doit imprimer un rapport. -Les instructions SQL devront être précompilées avant d'effectuer la compilation normale. -Si vous utilisez un langage différent les parties EXEC SQL seront les mêmes (standard), mais le code C qui les entourent devront être modifiées, y compris les déclarations de variables hôtes. -Le SQL incorporé diffère de système à système, aussi, encore une fois, vérifiez la documentation locale, spécialement les déclarations de variables et les procédures de connexion pour lesquelles le réseau, le SGBD, et le système d'exploitation sont cruciaux. */ /***************************************************/ /* CE PROGRAMME N'EST PAS COMPILABLE OU EXECUTABLE */ /* IL EST UNIQUEMENT DONNE A TITRE D'EXEMPLE */ /***************************************************/ #include <stdio.h> /* Section de déclaration des variables hôtes; ce seront les variables utilisées par votre programme, mais également celles utilisées par SQL pour y mettre ou y lire des valeurs,. */ EXEC SQL BEGIN DECLARE SECTION; int BuyerID; char Prenom[100], Nom[100], Item[100]; EXEC SQL END DECLARE SECTION; /* Cette section,insère les variables SQLCA, de façon à pouvoir tester les erreurs. */ EXEC SQL INCLUDE SQLCA; main() ( /* Ceci est une possibilité pour se connecter à la base de données */ EXEC SQL CONNECT UserID/Password; /* Cette partie de code soit vous indique que vous êtes connecté soit teste si un code erreur a été généré, signifiant que la connexion était incorrecte ou impossible. */ if(sqlca.sqlcode) ( printf(Printer, "Erreur de connexion au serveur de base de données.\n"); exit(); ) printf("Connecté au serveur de base de données.\n"); /* Ici, on déclare un "Curseur". C'est utilisé lorsqu'une requête retourne plus d'une ligne, et qu'on doit effectuer un traitement sur chaque ligne obtenue de la requête. Je vais utiliser pour le rapport, chaque ligne obtenue par cette requête. Ensuite, on utilisera "FETCH" (va chercher) pour récupérer les lignes, une par une, mais pour que la requête soit effectivement exécutée, il faut utiliser l'instruction "OPEN". La "Déclaration" (Declare) sert uniquement à construire la requête. */ EXEC SQL DECLARE ItemCursor CURSOR FOR SELECT ITEM, BUYERID FROM ANTIQUES ORDER BY ITEM; EXEC SQL OPEN ItemCursor; /* +-- Insérer ici un test d'erreur similaire au précédent si vous le désirez --+ */ /* L'instruction FETCH insère les valeurs de la ligne suivante respectivement dans chacune des variables hôtes. Cependant un "priming fetch" (technique de programmation) doit être exécuté en premier. Lorsque le curseur n'a plus de données un code (sqlcode) est généré nous permettant de sortir de la boucle. Notez que, pour des raisons de simplicité, on abandonne la boucle pour n'importe quel sqlcode, même s'il correspond à un code erreur. Autrement, il faut effectuer un test d'erreur spécifique. */ EXEC SQL FETCH ItemCursor INTO :Item, :BuyerID; while(!sqlca.sqlcode) ( /* Nous effectuerons également deux traitements pour chaque ligne. Premièrement, augmenter le prix de 5 (rétribution du marchand) et ensuite, lire le nom de l'acheteur pour le mettre dans le rapport. Pour faire cela, j'utiliserai les instructions Update et Select, avant d'imprimer la ligne sur l'écran. La mise à jour suppose, cependant, qu'un acheteur donné n'a acheté qu'un seul article, ou, sinon, le prix sera augmenté de trop nombreuses fois. Sinon, il aurait fallu utiliser une logique "RowID" (consulter la documentation). De plus, notez la présence du signe : (deux points) qui doit être placé devant les noms de variables hôtes quand elles sont utilisées dans des instructions SQL. */ EXEC SQL UPDATE ANTIQUES SET PRICE = PRICE + 5 WHERE ITEM = :Item AND BUYERID = :BuyerID; EXEC SQL SELECT OWNERFIRSTNAME, OWNERLASTNAME INTO :Prenom, :Nom FROM ANTIQUEOWNERS WHERE BUYERID = :BuyerID; printf("%25s %25s %25s", Prenom, Nom, Item); /* Rapport grossier--uniquement à but d'exemple! Aller chercher la ligne suivante */ EXEC SQL FETCH ItemCursor INTO :Item, :BuyerID; ) /* Fermer le curseur, enregistrer les modifications (voir ci-dessous), et quitter le programme. */ EXEC SQL CLOSE DataCursor; EXEC SQL COMMIT RELEASE; exit(); ) ---------------------------------------------------------------------------- Questions courantes sur SQL--Sujets avancés (Consulter les liens FAQ pour en avoir plusieurs autres) 1. Pourquoi ne puis-je pas demander uniquement les trois premières lignes d'une table? --Parce que, dans une base de données relationnelle, les lignes sont insérées sans aucun ordre particulier, c'est à dire que le système les insèrent dans un ordre arbitraire; de ce fait, vous ne pouvez demander des lignes qu'en utilisant des fonctionnalités SQL valides, telles que ORDER BY, etc. 2. Que sont ces DDL et DML dont j'entends parler ? --DDL (Data Definition Language - Langage de Définition de Données) fait référence à (en SQL) l'instruction de Création de Table (Create Table)...DML (Data Manipulation Language - Langage de Manipulation de Données) fait référence aux instructions Select, Update, Insert, et Delete. 3. Les tables des base de données ne sont elles pas simplement des fichiers? --Eh bien, les SGBD stockent les données dans des fichiers déclarés par le gestionnaire du système avant que de nouvelles tables ne soient créées (sur les grands systèmes), mais le système stocke les données dans un format spécial, et peut répartir les données d'une table dans plusieurs fichiers. Dans le monde des bases de données, un ensemble de fichiers créés pour une base de données est appelé un "espace de tables". En général, sur les petits systèmes, tout ce qui concerne une base de données (définitions et toutes les tables de données) est stocké dans un seul fichier. 4. (Question en relation avec la précédente) Les bases de données ne sont elles pas simplement que des tableurs? --Non, et ceci pour deux raisons. Premièrement, les tableurs peuvent avoir des données dans une cellule, mais une cellule est plus qu'une intersection ligne-colonne. Selon votre tableur, une cellule peut aussi contenir des formules et un formatage, ce que les bases de données (actuelles) ne permettent pas. Deuxièmement, les cellules dépendent souvent des données présentes dans d'autres cellules. Dans les bases de données, les "cellules" sont indépendantes, sauf que les colonnes sont en relation logique (heureusement: ensembles, une ligne et une colonne décrivent une entité), et, en dehors des contraintes de clé primaire et de clé externe, chaque ligne d'une table est indépendante des autres. 5. Comment puis-je importer un fichier texte de données dans une base de données? --Eh bien, vous ne pouvez pas le faire directement...il vous faut utiliser un programme utilitaire, tel que le SQL*Loader pour Oracle, ou écrire un programme pour charger les données dans la base de données. Un programme pour réaliser cela lit simplement chaque enregistrement du fichier texte, le sépare en colonnes, et effectue une insertion (INSERT) dans la base de données. 6. Qu'est-ce qu'un schéma? --Un schéma est un ensemble logique de tables, tel que la base de données ANTIQUES ci-dessus...habituellement, on s'y réfère simplement en tant que "base de données", mais une base de données peut contenir plus d'un schéma. Par exemple, un schéma en étoile est un ensemble de tables où une table centrale, de grande taille, contient toutes les informations importantes, et est liée, via des clés externes, à des tables de dimension qui contiennent l'information détaillée, et qui peuvent être utilisées dans une jointure pour créer des rapports détaillés. 7. Quels conseils généraux pourriez vous donner pour rendre mes requêtes SQL et mes bases de données meilleures et plus rapides (optimisées)? o Vous devriez essayer, si vous le pouvez, d'éviter, dans les clauses SELECT, des expressions telles que SELECT ColumnA + ColumnB, etc. L'optimiseur de requêtes de la base de données, partie du SGBD qui détermine la meilleure manière d'extraire les données requises de la base de données elle-même, traite les expressions d'une façon telle que cela demande en général plus de temps pour extraire les données que si les colonnes avaient été sélectionnées normalement, et que l'expression elle-même calculée par programme. o Minimisez le nombre de colonnes incluses dans une clause Group By. o Si vous effectuez une jointure, tâchez d'avoir les colonnes, de cette jointure, indexées (dans les deux tables). o Si vous avez un doute, créez un index. o A moins que vous ne fassiez de multiple comptages ou une requête complexe, utilisez COUNT(*) (le nombre de lignes sera généré par la requête) plutôt que COUNT(Column_Name). 8. Qu'est-ce que la Normalisation? --La Normalisation est une technique de conception de base de données qui suggère qu'un certain critère doit être pris en compte quand on définit l'organisation des tables (prise de décision sur le nombre de colonnes de chaque table, et création de la structure des clés), où l'idée est d'éliminer la redondance à travers les tables des données qui ne sont pas des clés. On parle de la normalisation en s'y référant habituellement en termes de "formes", et j'introduirais ici uniquement les trois premières, bien qu'il soit tout à fait courant d'en utiliser d'autres formes, plus avancées (quatrième, cinquième, Boyce-Codd; consultez la documentation). La Première Forme Normale consiste à placer les données dans des tables séparées où les données dans chaque tables sont de type similaire, et à donner à chaque table une clé primaire. Mettre les données en Seconde Forme Normale consiste à mettre les données dans les tables où elle ne dépendent uniquement que d'une partie de la clé. Par exemple, si j'avais laissé les noms des propriétaires d'objets anciens dans la table des articles, ce n'aurait pas été une seconde forme normale puisque les données auraient été redondantes; le nom aurait dû être répété pour chaque article possédé, donc, les noms ont été placés dans leur propre table. Les noms en eux-mêmes n'ont rien à voir avec les articles, seules les identités des acheteurs et des vendeurs sont concernées. La Troisième Forme Normale consiste à se débarrasser, dans une table, à tout ce qui ne dépend pas uniquement de la clé primaire. On met uniquement l'information qui dépend de la clé, et l'on déplace, dans d'autres tables, tout ce qui est indépendant de la clé primaire, et l'on crée des clés primaires pour les nouvelles tables. Il y a une certaine forme de redondance dans chaque forme, et si les données sont en 3NF (abrégé pour 3ième forme normale), elles sont déjà en 1NF et 2NF. En terme d'organisation des données, organisez vos données de façon que les colonnes qui ne sont pas des clés primaires dépendent seulement de la clé primaire entière. Si vous jetez un oeil sur la base de données en exemple, vous verrez que, lorsque vous naviguez à travers la base de données, c'est au travers de jointures qui utilisent les colonnes de clé commune. Deux autre points importants dans la conception de bases de données sont l'utilisation de noms significatifs, bien choisis, cohérents et logiques pour les tables et les colonnes et l'utilisation de noms significatifs pour la base de données elle-même. Sur le dernier point, ma base de données pèche, puisque j'utilise des codes numériques comme identificateurs. C'est en général bien meilleur d'utiliser, si possible, des clés qui ont, en elles-mêmes, un sens; par exemple, une meilleure clé pourrait consister des quatre premières lettres du nom et de la première initiale du prénom, comme JONEB pour Bill Jones (ou pour éviter les doubles, ajoutez-y des nombres à la fin pour différencier deux ou plusieurs personnes ayant le même nom, ainsi, on pourrait essayer JONEB1, JONEB2, etc.). 9. Quelle est la différence entre une requête simple ligne et une requête multi-lignes et pourquoi est-ce important de connaître cette différence? --Premièrement, pour parler de ce qui est évident, une requête simple ligne est une requête qui retourne une ligne unique comme résultat, et le résultat d'une requête multi-lignes est constitué de plusieurs lignes. Qu'une requête retourne une ligne ou plusieurs dépend complètement de la conception (ou schéma) des tables qui constituent la base de données. Assurez-vous d'inclure suffisamment de conditions, et structurez vos instructions SQL correctement, de façon à obtenir le résultat désiré (soit une ligne, soit plusieurs). Par exemple, si vous vouliez être sûr qu'une requête sur la table AntiqueOwners ne retourne qu'une ligne, employez une condition d'égalité sur la clé primaire, OwnerID. Trois raisons, concernant l'importance de ce sujet, viennent immédiatement à l'esprit. Premièrement, l'obtention de plusieurs lignes alors que vous n'en attendez qu'une, ou vice-versa, peut signifier que la requête est erronée, que la base de données est incomplète, ou simplement que vous découvrez quelque chose de nouveau concernant vos données. Deuxièmement, si vous utilisez une instruction de mise à jour (UPDATE) ou de suppression (DELETE), il vaudrait mieux vous assurer que l'instruction que vous écrivez effectue bien l'opération sur la ligne désirée (ou les lignes)...ou sinon, vous pourriez supprimer ou mettre à jour plus de lignes que vous ne le désirez. Troisièmement, il faut soigneusement penser au nombre de lignes qui seront retournées pour toutes les requêtes rédigées en SQL incorporé. Si vous écrivez une requête simple ligne, une seule instruction SQL peut suffire pour satisfaire à la logique du programme. D'un autre côté, si votre requête retourne de multiples lignes, il vous faudra utiliser l'instruction FETCH, et très certainement quelque chose comme une structure de boucle sera nécessaire dans votre programme pour traiter chaque ligne retournée par la requête. 10. Que sont les relations? --C'est une autre question de conception...le terme "relation" fait habituellement référence aux relations entre clés primaires et externes entre les tables. Ce concept est important parce que, quand les tables d'une base de données relationnelle sont conçues, ces relations doivent être définies parce que cela détermine quelles colonnes sont ou ne sont pas des clés primaires ou externes. Vous avez peut-être entendu parler des diagrammes Entités-Relations, qui sont une représentation graphique des tables dans les schéma de la base de données. Voyez l'exemple de diagramme à la fin de cette section ou consultez quelques sites indiqués ci-dessous concernant ce sujet, car il y a de nombreuses manières de dessiner les diagrammes E-R. Mais d'abord, jetons un oeil à chaque type de relation... Une relation 1-à-1 (ou 1:1, ou 1-1) signifie que vous avez une colonne clé primaire et que chaque clé primaire est en relation avec une clé externe. Par exemple, dans le premier exemple, dans la table des adresses des employés TableAdresseEmploye nous avons une colonne numéro d'identification de l'employé (EmployeeIDNo). Donc, la table TableAdresseEmploye est en relation avec la table EmployeeStatisticsTable (deuxième exemple de table) par l'intermédiaire du numéro EmployeeIDNo. Plus précisément, chaque employé, de la table TableAdresseEmploye possède des statistiques (une ligne de données) dans la table EmployeeStatisticsTable. Même si c'est un exemple inventé, c'est une relation "1-1". Inscrivez en caractères gras le "has" ("a" ou "possède")...quand on décrit une relation, il est important de décrire une relation en utilisant un verbe. Les deux autres types de relations peuvent ou pas utiliser une clé primaire logique et des contraintes par rapport aux clés externes...cela dépend strictement des souhaits du concepteur. La première de ces relations est la relation un-à-plusieurs ("1-M"). Cela signifie que pour chaque valeur d'une colonne dans une table, il y a une ou plusieurs valeurs correspondantes dans une autre table. Des contraintes de clé peuvent être ajoutées au modèle, ou éventuellement une colonne d'identification peut être utilisée pour établir une relation. Un exemple serait que pour chaque OwnerID dans la table AntiqueOwners, il y ait un ou plusieurs (la valeur zéro est également autorisée) articles (Items) achetés dans la table ANTIQUES (verbe: acheter). Finalement, la relation plusieurs-à plusieurs ("M-M") n'utilise généralement pas de clés, et habituellement utilise des identificateurs de colonnes. L'apparition inhabituelle d'une relation "M-M" signifie qu'une colonne, dans une table est en relation avec une autre colonne dans une autre table, et que pour chaque valeur de l'une de ces deux colonnes, il y a une ou plusieurs valeurs correspondantes dans la colonne correspondante de l'autre table (et vice-versa), ou possibilité plus courante, les deux tables ont une relation 1-M avec l'autre (deux relations, une 1-M dans chaque direction). Un [mauvais] exemple de la situation la plus courante consisterait, si vous avez une bases de données de fonctions, à avoir une table possédant une ligne pour chaque employé et sa fonction, et d'avoir une autre table contenant une ligne pour chaque fonction avec un des employés l'occupant. Dans ce cas, vous auriez plusieurs lignes pour chaque employé dans la première table, une pour chaque fonction, et plusieurs lignes pour chaque fonction dans le seconde table, une pour chaque employé ayant cette fonction. Ces tables sont en relation M-M: chaque employé, dans la première table a plusieurs fonctions dans la seconde table, et chaque fonction, dans la seconde table, a plusieurs attributaires dans la première table. Ceci est la partie émergée de l'iceberg concernant ce sujet...consultez les liens ci-dessous pour avoir de plus amples informations et regardez le diagramme ci-dessous donnant un exemple simplifié de diagramme E-R. [Exemple Simplifié de Diagramme Entités-Relations] 11. Quelles sont quelques unes des fonctionnalités importantes, non standard, de SQL (Question extrêmement courante)? --Eh bien, nous allons voir çà dans la section suivante... ---------------------------------------------------------------------------- SQL Non-standard..."A vérifier pour votre site" * INTERSECT et MINUS sont comme des instructions UNION , sauf que INTERSECT produits des lignes qui apparaissent dans les deux requêtes, et que MINUS produit des lignes provenant de la première requête mais pas de la seconde. * Fonctionnalités de la Génération de Rapport: la clause COMPUTE est placée à la fin d'une requête pour placer le résultat d'une fonction agrégée à la fin d'une liste, comme COMPUTE SUM (PRICE); Une autre solution est d'utiliser une logique d'interruption: définir une interruption pour diviser les résultats de la requête en groupes basés sur une colonne, comme BREAK ON BUYERID. Alors, pour sortir un résultat après la liste d'un groupe, utilisez COMPUTE SUM OF PRICE ON BUYERID. Si, par exemple, vous avez utilisé ces trois clauses ("BREAK" en premier, "COMPUTE on break" en second, "COMPUTE overall sum" en troisième), vous obtiendrez un rapport qui regroupera les articles par acheteurs, listera la somme de Prix pour chaque groupe d'articles d'un acheteur, puis, après que tous les groupes aient été listés, listera la somme de tous les Prix, le tout, avec des en-têtes et des lignes générés par SQL. * En plus des fonctions agrégées indiquées ci-dessus, quelques SGBD ont des fonctions supplémentaires qui peuvent être utilisées dans des listes de sélection (SELECT), sauf que ces fonctions (quelques fonctions caractères autorisent des résultats de plusieurs lignes) doivent être utilisées avec une valeur individuelle (pas de groupes), pour des requêtes simple ligne. De plus, les fonctions ne doivent être utilisées qu' avec les types de données appropriés. Voici quelques Fonctions Mathématiques: ABS(X) Valeur A-convertit les nombres négatifs en nombres positifs et laisse les positifs inchangés CEIL(X) X est une valeur décimale qui sera arrondie à la valeur supérieure. FLOOR(X) X est une valeur décimale qui sera arrondie à la valeur inférieure. GREATEST(X,Y)Retourne la plus grande des deux valeurs. LEAST(X,Y) Retourne la plus petite des deux valeur. MOD(X,Y) Retourne le reste de X / Y. POWER(X,Y) Retourne X à la puissance Y. ROUND(X,Y) Arrondit X à Y positions décimales. i Y n'est pas donné, X est arrondi à la valeur de l'entier le plus proche. SIGN(X) Retourne le signe - si X < 0, sinon retourne un signe plus. SQRT(X) Retourne la racine carrée de X. Fonctions Caractères LEFT(<string>,X) Retourne les X caractères les plus à gauche de la chaîne de caractères. RIGHT(<string>,X) Retourne les X caractères les plus à droite de la chaîne de caractères. UPPER(<string>) Convertit tous les caractères de la chaîne en majuscules. LOWER(<string>) Convertit tous les caractères de la chaîne en minuscules. INITCAP(<string>) Convertit les caractères initiaux de la chaîne en Capitales. LENGTH(<string>) Retourne le nombre de caractères de la chaîne. <string>||<string> Combine les deux chaînes en une seule chaîne, concaténée, où la première chaîne est immédiatement suivie par la seconde. LPAD(<string>,X,'*') Insère des caractères * (ou n'importe quel autre, mis entre guillemets) à gauche de la chaîne de caractères pour lui donner une longueur de X caractères. RPAD(<string>,X,'*') Insère des caractères * (ou n'importe quel autre, mis entre guillemets) à droite de la chaîne de caractères pour lui donner une longueur de X caractères. SUBSTR(<string>,X,Y) Extrait Y lettres de la chaîne à partir de la position X. NVL(<column>,<value>) La fonction NVL va substituer la valeur <value> pour chaque valeur nulle dans la colonne <column>. Si la valeur courante dans la colonne <column> n'est pas nulle (NULL), NVL est sans effet. ---------------------------------------------------------------------------- Résumé de la Syntaxe--Pour Utilisateurs Avancés Seulement Voici la forme générale des instructions dont il a été question dans ce didacticiel, avec, en plus, quelques autres, (des explications sont données). SOUVENEZ-VOUS que toutes ces instructions peuvent ne pas être disponibles sur votre système, aussi vérifiez leur disponibilité dans la documentation: ALTER TABLE <TABLE NAME> ADD|DROP|MODIFY (COLUMN SPECIFICATION[S]...voir Create Table); --vous permet d'ajouter ou de supprimer une ou plusieurs colonnes d'une table, ou de changer les spécifications(données, types, etc.) d'une colonne existante; cette instruction est également utilisée pour changer les spécifications physiques d'une table (comment la table est stockée, etc.), mais ces définitions sont spécifiques au SGBD, aussi, lire la documentation. De même, ces spécifications physiques sont utilisées avec les instructions de création de table, lorsqu'une table est créée pour la première fois. De plus, seulement une seule option peut être exécutée par instruction de modification: (Alter Table)--soit add (ajout), drop (suppression), OU modify (modification) dans une simple instruction. COMMIT; --rend les modifications effectuées sur une bases de données permanentes (depuis le dernier COMMIT; connu sous le nom de transaction) CREATE [UNIQUE] INDEX <INDEX NAME> ON <TABLE NAME> (<COLUMN LIST>); --UNIQUE est optionnel; entre parenthèses. CREATE TABLE <TABLE NAME> (<COLUMN NAME> <DATA TYPE> [(<SIZE>)] <COLUMN CONSTRAINT>, ...autres colonnes); (valide également avec ALTER TABLE) --où SIZE est uniquement utilisé avec certains types de données (voir ci-dessus), et les contraintes incluent les possibilités suivantes (imposé automatiquement par le SGBD; (un non respect entraîne la génération d'une erreur) : 1. NULL ou NOT NULL (voir ci-dessus) 2. UNIQUE impose que deux lignes ne peuvent avoir la même valeur pour cette colonne 3. PRIMARY KEY indique à la base de données que cette colonne est la colonne clé primaire (utilisé uniquement si la clé est une colonne clé, autrement une instruction PRIMARY KEY (column, column, ...) apparaît après la dernière définition de colonne. 4. CHECK permet de tester une condition quand on insère ou on met à jour une donnée dans cette colonne; par exemple, CHECK (PRICE > 0) amène le système à tester si la colonne Prix est supérieure ou égale à zéro avant d'accepter la valeur...quelquefois implanté comme instruction CONSTRAINT. 5. DEFAULT insère une valeur par défaut dans la base de données si l'on veut insérer une ligne qui ne contienne pas de valeur pour cette colonne; par exemple, BENEFITS INTEGER DEFAULT = 10000 6. FOREIGN KEY fonctionne comme la Clé Primaire, mais est suivi par: REFERENCES <TABLE NAME> (<COLUMN NAME>), qui fait référence à la clé primaire de référence. CREATE VIEW <TABLE NAME> AS <QUERY>; DELETE FROM <TABLE NAME> WHERE <CONDITION>; INSERT INTO <TABLE NAME> [(<COLUMN LIST>)] VALUES (<VALUE LIST>); ROLLBACK; --Annule toutes les modifications effectuées dans la base de données, celles qui ont été faites depuis la dernière commande COMMIT...Attention! Quelques logiciels travaillant en transactions, donc, la commande ROLLBACK peut ne pas fonctionner. SELECT [DISTINCT|ALL] <LIST OF COLUMNS, FUNCTIONS, CONSTANTS, ETC.> FROM <LIST OF TABLES OR VIEWS> [WHERE <CONDITION(S)>] [GROUP BY <GROUPING COLUMN(S)>] [HAVING <CONDITION>] [ORDER BY <ORDERING COLUMN(S)> [ASC|DESC]]; --où ASC|DESC permet le classement en ordre ascendant (ASCending) ou descendant (DESCending) UPDATE <TABLE NAME> SET <COLUMN NAME> = <VALUE> [WHERE <CONDITION>]; --si la clause WHERE n'est pas donnée, toutes les lignes seront mises à jour selon l'instruction SET ---------------------------------------------------------------------------- Liens Importants Liens Informatique & SQL/DB : Netscape -- Oracle -- Sybase -- Informix --Microsoft Page de Référence -- Ask the SQL Pro -- SQL Pro's Relational DB Sites Utiles Programmer's Source -- DBMS Sites -- inquiry.com -- DB Ingredients Web Authoring -- Computing Dictionary -- DBMS Lab/Links -- SQL FAQ -- SQL Databases RIT Database Design Page -- Database Jump Site -- Didacticiels de programmation sur le Web Ressources pour le Développement -- Query List -- IMAGE SQL Divers: CNN -- USA Today -- Pathfinder -- ZDNet -- Metroscope -- CNet Liste de ressources sur Internet -- Netcast Weather -- TechWeb -- LookSmart Moteurs de Recherche: Yahoo -- Alta Vista -- Excite -- WebCrawler -- Lycos -- Infoseek -- search.com L'auteur n'est pas reponsable de ces sites. ---------------------------------------------------------------------------- Avertissement J'espère que vous aurez appris quelque chose de ce premier regard sur un langage très important qui est en train de devenir plus répandu dans le mode de l'informatique client-serveur. J'ai rédigé cette page web pour apporter quelque chose d'utile au web et à la communauté des utilisateurs du web. En réalité, j'ai appris que ce document est utilisé dans plusieurs collèges pour des cours sur les bases de données et par des chercheurs. En outre, lisez cette page dans le nouveau livre, édité par Waite Publishing, sur Borland C++ Builder, qui sera publié cet été et dans une version à venir chez Sams Publishing. De plus, je voudrais remercier tous les gens, sur les cinq continents, qui m'ont contactés à propos de cette page. J'espère aussi continuer à ajouter plus d'éléments à ce didacticiel, tels que des articles sur la conception d'une base de données et les extensions SQL non standard, même si je souhaite me tenir à l'écart de particularités propres à un Système de Gestion de Base de Donnée. Bonne chance pour vos développements en SQL et autres aventures informatiques. Jim Hoffman ---------------------------------------------------------------------------- Commentaires ou Suggestions? Envoyez-moi un courrier électronique à jhoffman@one.net. Ou vous pouvez désirer jeter un oeil aux pages Web de Jim Hoffman's Web Pages pour plus d'informations me concernant. Copyright 1996-1997, James Hoffman. Ce document peut être utilisé gratuitement par n'importe quel utilisateur d'Internet, mais ne peut pas être inclus dans un autre document, publié sous une autre forme, ou produit en masse de quelque façon que ce soit. Netscape Navigator donne le meilleur affichage de cette page; celui-ci n'est pas très bon si l'on utilise Microsoft Internet Explorer. Dernière mise à jour : 8-25-1997; ajout de quelques éléments. </verb></tscreen> <sect> Liste des autre Bases de Données <p> On trouvera ci-dessous la liste des autres bases de données SQL pour Unix, Linux. <itemize> <item> Cliquez et allez à Applications->databases. <url url="http://www.caldera.com/tech-ref/linuxapps/linapps.html"> <item> Click et allez à Applications->databases. <url url="http://www.xnet.com/~blatura/linapps.shtml"> <item> Ressources pour Bases de Données <url url="http://linas.org/linux/db.html"> <item> Liste des Bases de Données libres <url url="http://cuiwww.unige.ch:80/~scg/FreeDB/FreeDB.list.html"> <item> Liste des SGBDR de Browne <url url="http://www.hex.net/~cbbrowne/rdbms.html"> <item> Liste des SGBDR de SAL <url url="http://SAL.KachinaTech.COM/H/1/"> <item> Liste des SGBD Orientés Objets de SAL <url url="http://SAL.KachinaTech.COM/H/2/"> <item> Liste des Utilitaires et d'Autres SGDB de SAL <url url="http://SAL.KachinaTech.COM/H/3/"> <item> Index des Logiciels de Base de Données Publics de l'ACM SIGMOD <url url="http://bunny.cs.uiuc.edu/sigmod/databaseSoftware/"> </itemize> <sect> Conclusion <p> Après avoir cherché toutes les bases de données disponibles qui soient libres et dont le code source est disponible, j'ai trouvé que SEUL PostgreSQL, le SGDBR (Relationnel Objet)SQL libre, est le plus mature et le plus largement utilisé au monde. PostgreSQL est très attractif en ce que beaucoup de travail a déjà été effectué et qu'il possède des pilotes ODBC et JDBC permettant d'écrire des applications indépendantes des bases de données. Les applications écrites en PostgreSQL qui utilisent les pilotes ODBC, JDBC sont facilement portables sur d'autres systèmes tels que Oracle, Sybase et Informix. Et les applications écrites pour Oracle, Sybase et Informix qui utilisent les pilotes ODBC, JDBC sont facilement portables sur la base de données PostgreSQL. <sect> FAQ - Questions sur PostgreSQL <p> <sect1> Foire Aux Questions (FAQ) sur PostgreSQL <p> Dernière mise à jour: Mercredi 11 Juin 10:44:40 EDT 1997 Version: 6.1.1 Gestionnaire actuel: Bruce Momjian (<htmlurl url="mailto:maillist@candle.pha.pa.us " name="maillist@candle.pha.pa.us">) La version la plus récente de ce document peut être consultée sur le site Web de postgreSQL, <url url="http://www.postgreSQL.org"> On trouvera les réponses aux questions spécifiques à Linux à <url url="http://www.postgreSQL.org/docs/FAQ-Linux.phtml"> On trouvera les réponses aux questions spécifiques à Irix à <url url="http://www.postgreSQL.org/docs/FAQ-Irix.phtml"> Modifications dans cette version (* = modifié, + = nouveau) : * 3.42) Qu'est-ce qu'une Optimisation de Requête Génétique? * 3.43) J'utilise Solaris et l'affichage de mes dates est faux. Pourquoi? --------------------------------------------------------------------------- <sect1> Qu'est-ce que PostgreSQL? <p> PostgreSQL est une amélioration du système de gestion de base de données POSTGRES, un prototype de recherche de SGBD de la nouvelle génération. Alors que PostgreSQL garde le puissant modèle de données et les riches types de données de POSTGRES, il remplace le langage de requêtes PostQuel par un sous-ensemble étendu du langage SQL. PostgreSQL est libre et le code source est disponible. Le développement de PostgreSQL est effectué par une équipe de développeurs Internet qui sont tous inscrits à la liste de diffusion PostgreSQL développement. Le coordinateur actuel est Marc G. Fournier (<htmlurl url="mailto:scrappy@postgreSQL.org " name="scrappy@postgreSQL.org">). (Voir ci-dessous comment le joindre). Cette équipe est maintenant responsable de tous les développements actuels et futurs de PostgreSQL. Les auteurs de PostgreSQL 1.01sont Andrew Yu et Jolly Chen. Beaucoup d'autres ont contribué au portage, aux tests, au débogage et aux améliorations du code; Le code original de Postgres, à partir duquel PostgreSQL est dérivé, est le résultat de l'effort de nombreux étudiants de troisième cycle, de deuxième cycle et d'enseignants sous la direction du Professeur Michael Stonebraker de l'université de Californie, Berkeley. Le nom original du logiciel à Berkeley était Postgres. Lors de l'ajout des fonctionnalités SQL en 1995, il fut renommé Postgres95. Ce nom fut changé à la fin de 1996 en PostgreSQL. <sect1> Sur quelles machines tourne PostgreSQL? <p> Les auteurs ont compilé et testé PostgreSQL sur les plates-formes suivantes(quelques unes de ces compilations requièrent gcc 2.7.0) : * aix - IBM sous AIX 3.2.5 * alpha - DEC Alpha AXP sous OSF/1 2.0 * BSD44_derivé - OSs dérivé de 4.4-lite BSD (NetBSD, FreeBSD) * bsdi - BSD/OS 2.0, 2.01, 2.1, 3.0 * dgux - DG/UX 5.4R3.10 * hpux - HP PA-RISC sous HP-UX 9.0 * i386_solaris - i386 Solaris * irix5 - SGI MIPS sous IRIX 5.3 * linux - Intel x86 sous Linux 1.2 et Linux ELF (Pour le Linux non-ELF Linux, voir LINUX_ELF ci-dessous). * sparc_solaris - SUN SPARC sous Solaris 2.4 * sunos4 - SUN SPARC sous SunOS 4.1.3 * svr4 - Intel x86 sous Intel SVR4 * ultrix4 - DEC MIPS sous Ultrix 4.4 Pour les plates-formes suivantes, il y a des problèmes/bogues connus : * nextstep - Motorola MC68K ou Intel x86 sous NeXTSTEP 3.2 <sect1> Où puis-je trouver PostgreSQL? <p> Le premier site ftp anonyme pour PostgreSQL est : * <url url="ftp://ftp.postgreSQL.org/pub"> Il existe un site miroir à : * <url url="ftp://postgres95.vnet.net/pub/postgres95"> * <url url="ftp://ftp.luga.or.at/pub/postgres95"> * <url url="ftp://cal011111.student.utwente.nl/pub/postgres95"> * <url url="ftp://ftp.uni-trier.de/pub/database/rdbms/postgres/postgres95"> * <url url="ftp://rocker.sch.bme.hu"> <sect1> Quel est le régime de copyright de PostgreSQL? <p> PostgreSQL est sujet au COPYRIGHT suivant. Système de Gestion de Base de Données PostgreSQL Copyright (c) 1994-6 Université de Californie. Tous droits réservés La permission d'utiliser, de copier, de modifier, et de distribuer ce logiciel et sa documentation pour n'importe quel usage, gratuitement, et sans autorisation écrite est accordée, à la condition que cette notice de copyright et que ce paragraphe et les deux paragraphes suivants apparaissent dans toutes les copies. EN AUCUN CAS L'UNIVERSITE DE CALIFORNIE NE POURRA ETRE TENUE POUR RESPONSABLE VIS A VIS DE QUI QUE CE SOIT POUR DES DOMMAGES DIRECTS, INDIRECTS, SPECIAUX, FORTUITS, OU CONSECUTIFS, INCLUANT LA PERTE DE PROFITS, QUI POURRAIENT RESULTER DE L'USAGE DE CE LOGICIEL ET DE SA DOCUMENTATION, MEME SI L'UNIVERSITE DE CALIFORNIE A ETE AVERTIE DE LA POSSIBILITE D'UN TEL DOMMAGE. L'UNIVERSITE DE CALIFORNIE REJETTE PARTICULIERMENT TOUTE GARANTIES, INCLUANT , MAIS PAS LIMITE A, LES GARANTIES IMPLICITES DE VALEUR MARCHANDE ET D'ADAPTATION A UNE UTILISATION PARTICULIERE. LE LOGICIEL FOURNIT CI-DESSOUS EST FOURNIT "EN L'ETAT", ET L'UNIVERSITE DE CALIFORNIE N'A AUCUNE OBLIGATION DE FOURNIR MAINTENANCE, SUPPORT, MISES A JOUR, AMELIORATIONS OU MODIFICATIONS. <sect1> Support pour PostgreSQL <p> Il n'y a aucun support officiel pour PostgreSQL de la part des de l'équipe de support initiale de l'Université de Californie, Berkeley. Il est maintenu uniquement grâce à l'effort de volontaires. La liste de diffusion est: <htmlurl url="mailto:questions@postgreSQL.org " name="questions@postgreSQL.org">. Elle est disponible pour des discussions sur des sujets concernants PostgreSQL, incluant, mais non limité aux rapports d'erreurs et corrections. Pour avoir des informations sur la manière de s'inscrire, envoyer un courrier électronique avec les lignes suivantes dans le corps du message (pas dans la ligne sujet) subscribe end à <htmlurl url="mailto:questions-request@postgreSQL.org " name="questions-request@postgreSQL.org">. Il y a aussi une liste résumée. Pour s'inscrire à cette liste, envoyez un courrier électronique à: <htmlurl url="mailto:questions-digest-request@postgreSQL.org " name="questions-digest-request@postgreSQL.org"> avec, dans le CORPS du message : subscribe end Des résumés sont envoyés aux membres de cette liste chaque fois que la liste principale a reçu environ 30k de messages. Il y a une liste de diffusion des erreurs. Pour s'inscrire à cette liste, envoyez un courrier électronique à <htmlurl url="mailto:bugs-request@postgreSQL.org " name="bugs-request@postgreSQL.org"> avec, dans le CORPS du message : Il y a aussi un forum de discussion pour les développeurs. Pour s'inscrire à cette liste, envoyer un courrier électronique à <htmlurl url="mailto:hackers-request@postgreSQL.org " name="hackers-request@postgreSQL.org"> avec, dans le CORPS du message : subscribe end Des informations complémentaires sur PostgreSQL peuvent être trouvées via la page d'accueil WWW de PostgreSQL à : <url url="http://www.postgreSQL.org"> <sect1> Dernière version dePostgreSQL <p> La dernière version de PostgreSQL est la version 6.0, qui est disponible depuis le 31 Janvier 1997. La version 6.1 est programmée pour bientôt. Pour avoir des informations sur les nouveautés de la version 6.1, consulter le fichier TODO sur notre page WWW. Nous attendons la version 7.0 dans quelques mois qui sera plus rapide et réduira de 50 &percnt la taille des colonnes système, sur disque, nécessaire pour chaque ligne d'une table. Cette version disposera aussi des fonctionnalités de vidage (dump) et de restauration (restore). <sect1> Existe-t-il une version commerciale de PostgreSQL? <p> Illustra Information Technology (filiale possédée totalement par Informix Software, Inc.) vend un SGBD Relationnel Objet appelé Illustra qui était, à l'origine, basé sur postgres. Illustra a des similarités d'aspect avec PostgreSQL mais possède plus de fonctionnalités, est plus robuste, plus performant et dispose de documentation et d'un support réels. D'un autre côté, il coûte de l'argent. Pour de plus informations, contactez <htmlurl url="mailto:sales@illustra.com " name="sales@illustra.com"> <sect1> Quelle documentation est disponible pour PostgreSQL? <p> Un manuel utilisateur, des pages de manuel, et quelques petits exemples de test sont compris dans la distribution. Les pages de manuel concernant sql et les fonctions internes (built-in) sont particulièrement importantes. La page www contient des liens sur un guide d'implémentation et sur cinq papiers concernants les concepts d'architecture et les fonctionnalités de postgres . <sect1> Quelle version de SQL PostgreSQL utilise-t-il? <p> PostgreSQL supporte un sous-ensemble de SQL-92. Ils en possède les constructions les plus importantes mais manque de certaines fonctionnalités. Les différences les plus visibles sont : * les sous-requêtes imbriquées ne sont pas supportées * pas de clause HAVING sous un GROUP BY D'un autre côté, vous pouvez créer des types définis par l'utilisateur, des fonctions, de l'héritage etc. Si vous souhaitez participer à la programmation de PostgreSQL, vous pouvez ajouter les fonctionnalités manquantes énumérées ci-dessus. <sect1> PostgreSQL fonctionne-t-il avec les versions précédentes de postgres? <p> PostgreSQL v1.09 est compatible avec les bases de données créées avec la version v1.01. Ceux qui veulent faire une mise à niveau de la version 1.0 doivent lire les indications dan le répertoire MIGRATION_1.0_TO_1.02. Une mise à niveau vers la version 6.0 nécessite de faire un vidage et une restauration à partir des versions précédentes. Une mise à niveau vers la version 6.1 nécessite de faire un vidage et une restauration à partir des versions précédentes. Ceux qui font une mise à niveau de versions antérieures à 1.09 doivent d'abord faire une mise à niveau vers la version 1.09 sans vidage/restauration, puis vider les données de la version 1.09, et enfin les recharger dans la version 6.0 ou 6.1. <sect1> Combien de personnes utilisent PostgreSQL? <p> Puisque nous n'avons aucune procédure de licence ou d'enregistrement, c'est impossible à dire. Nous savons que des centaines de copies de PostgreSQL v1.* ont été rapatriées, et qu'il y a plusieurs centaines d'inscrits aux listes de diffusion. --------------------------------------------------------------------------- <sect> FAQ - Questions concernant l'Installation <p> <sect1> Initdb ne tourne pas <p> * vérifiez que vous avez les chemins appropriés * vérifiez que l'utilisateur 'postgres' dispose des droits nécessaires sur les fichiers * assurez-vous qu'il y a des fichiers dans &dollar PGDATA/files, et qu'ils ne sont pas vides. S'ils n'y sont pas, c'est que "gmake install" à échoué pour une raison quelconque <sect1> Quand je démarre le postmaster, j'ai le message "FindBackend- could not find a backend to execute..." "postmaster- could not find backend to execute..." <p> Vous n'avez probablement pas le bon chemin de spécifié. L'exécutable 'postgres' a besoin d'être dans votre chemin. <sect1> Le système paraît perturbé par les virgules, les points décimaux, et le format des dates. <p> Vérifiez votre configuration locale. PostgreSQL utilise les options locales choisies par l'utilisateur qui a lancé le processus postmaster. Adaptez les selon votre environnement de travail. <sect1> Comment puis-je installer PostgreSQL ailleurs que dans /usr/local/pgsql? <p> Il vous faut éditer le fichier Makefile.global et modifier POSTGRESDIR suivant vos souhaits, ou créer un fichier Makefile.custom et définir POSTGRESDIR ici. <sect1> Quand je lance postmaster, j'ai un message "Bad System Call core dumped". <p> Cela peu être dû à de nombreux problèmes, mais, en premier lieu, vérifiez que vous disposez bien des extensions system V dans votre noyau. PostgreSQL nécessite un support de la mémoire partagé dans le noyau. <sect1> Quand j'essaie de lancer postmaster, j'ai des messages d'erreur "IpcMemoryCreate". <p> Soit votre gestion de la mémoire partagée n'est pas configurée correctement dans le noyau ou vous avez besoin d'étendre la mémoire partagée disponible dans le noyau. La quantité dont vous avez besoin dépend de l'architecture de votre système et du nombre de tampons avec lesquels postmaster a été configuré pour tourner. Pour la plupart des systèmes, avec des tampons de la taille par défaut, vous avez besoin d'un minimum de &tilde 760K. <sect1> J'ai modifié un fichier source, mais une recompilation ne reflète pas les modifications? <p> Les fichiers Makefile ne contiennent pas les dépendances correctes pour les fichiers inclus. Il vous faut exécuter 'make clean' puis un autre 'make'. --------------------------------------------------------------------------- <sect> FAQ - Fonctionnalités de PostgreSQL <p> <sect1> Comment dois-je spécifier une CLE ou d'autres contraintes sur une colonne? <p> Les contraintes sur les colonnes ne sont par supportées dans PostgreSQL. En conséquence, le systèmes ne vérifie pas l'existence de doublons. Sous 6.0, créez un index unique sur la colonne. Les tentatives de créer des doubles dans cette colonne donneront une erreur. <sect1> Est-ce que PostgreSQL supporte les sous-requêtes imbriquées? <p> Les sous-requêtes imbriquées ne sont pas encore implantées, mais elles peuvent être simulées en utilisant des fonctions sql. <sect1> Comment dois-je définir des index "unique"? <p> PostgreSQL 6.0 supporte les index "unique". <sect1> J'ai eu un tas de problèmes dans l'utilisation des règles. <p> Actuellement, le système de règle dans PostgreSQL est pour la plupart non fonctionnel. Il fonctionne suffisamment pour supporter le mécanismes de vue, mais c'est tout. Vous utilisez les règles PostgreSQL à vos risques et périls. <sect1> Il ne me semble pas possible d'écrire au milieu de grands objets de manière fiable. <p> Le système de gestion des grands objets est également non fonctionnel dans PostgreSQL. Il fonctionne juste assez pour stocker de grandes paquets de données et de les relire, mais l'implémentation souffre de quelques problèmes sous-jacents. Vous utilisez les grands objets PostgreSQL à vos risques et périls. <sect1> PostgreSQL a-t-il un interface utilisateur graphique? Un générateur de rapport? Un interface de langage d'interrogation intégré? <p> Non. Non. Non. Au moins, pas dans la distribution officielle. Quelques utilisateurs ont indiqué quelques succès dans l'utilisation de 'pgbrowse' et de 'onyx' comme frontaux à PostgreSQL. Plusieurs contributeurs travaillent sur des outils frontaux basés sur Tk. Posez la question dans la liste de diffusion. <sect1> Comment puis-je écrire une application cliente pour PostgreSQL? <p> PostgreSQL supporte une bibliothèque d'interfaçage que l'on peut appeler à partir de C nommée libpq de même qu'une bibliothèque d'interfaçage basée sur Tcl appelée libtcl. D'autres ont contribué à une interface perl et à une passerelle WWW à PostgreSQL. Consulter la page d'accueil PostgreSQL pour plus de détails. <sect1> Comment puis-je me prémunir d'accès à mon processus d'arrière plan PostgreSQL par d'autres hôtes? <p> Utilisez une authentification basée sur l'hôte en modifiant le fichier &dollar PGDATA/pg_hba en conséquence. <sect1> Comment puis-je mettre en place un pg_group? <p> Actuellement, il n'y a pas d'interface aisée pour mettre en place des groupes d'utilisateurs. Vous devez explicitement insérer/mettre à jour la table pg_group . Par exemple : <!-- aldev removed the flower-brackets from line below to avoid problems in sgml2info command jolly=> values ('posthackers', '1234', '{5443, 8261}'); --> <tscreen><verb> jolly=> insert into pg_group (groname, grosysid, grolist) jolly=> values ('posthackers', '1234', '5443, 8261'); INSERT 548224 jolly=> grant insert on foo to group posthackers; CHANGE jolly=> </verb></tscreen> Les champs dans le fichier pg_group sont : * groname: le nom de groupe. C'est un char16 et il doit être purement alphanumérique. Ne pas inclure de soulignés ou d'autres ponctuations. * grosysid: l'identificateur de groupe. C'est un int4. Il doit être unique pour chaque groupe. * grolist: la liste des identificateurs de pg_user qui appartiennent au groupe. <tscreen><verb> C'est un int4[]. </verb></tscreen> <sect1> Quelle l'exacte différence entre les curseurs binaires et les curseurs normaux? <p> Les curseurs normaux retournent les données en format ASCII. Puisque les données sont stockées d'origine en format binaire, le système doit effectuer une conversion pour produire le format ASCII. De plus, les formats ASCII sont souvent plus grands en taille que le format binaire. Une fois que les attributs sont retournés en ASCII, souvent l'application cliente doit alors les convertir en format binaire pour les manipuler. Les curseurs binaires vous renvoient les données dans le format binaire, natif, de représentation. Donc, les curseurs binaires ont tendance à être plus rapides puisqu'il y a moins de temps de traitement dû à la conversion. Toutefois, l'ASCII est neutre en ce qui concerne l'architecture alors que la représentation binaire peut différer entre différentes architectures de machines. Donc, si votre machine cliente utilise une représentation des données différente de votre machine serveur, recevoir les attributs en format binaire ne correspond certainement pas à ce que vous désirez. Donc, si votre objectif principal des d'afficher les données en ASCII, alors les recevoir en ASCII vous évitera quelques efforts côté client. <sect1> Pourquoi l'opérateur != ne fonctionne-t-il pas? <p> SQL spécifie les opérateurs d'inégalité < > , et c'est ce que nous avons définit comme types internes. En 6.0, != est équivalent à < > . <sect1> Qu'est-ce qu'un index R-tree et à quoi est-il utilisé? <p> Un index R-tree est utilisé pour indexer les données spatiales. Un index obtenu par hachage ne peut effectuer de recherches dans une gamme de données. Un index B-tree peut seulement effectuer des recherches dans une gamme de données sur une dimension. Les index R-tree permettent de traiter des données multidimensionnelles. Par exemple, si un index R-tree peut être construit sur un attribut de type 'point' le système peut répondre plus efficacement à des requêtes telles que sélectionner tous les points à l'intérieur d'un rectangle. Le papier de référence qui décrit la conception originale du R-Tree est : Guttman, A. "R-Trees: A Dynamic Index Structure for Spatial Searching." (R-Trees: une Structure d'Index Dynamique pour les Recherches Spatiales) Proc of the 1984 ACM SIGMOD Int'l Conf on Mgmt of Data, 45-57. Vous pouvez également trouver ce papier dans le livre de Stonebraker "Readings in Database Systems" (Lectures sur les Systèmes de Gestion de Base de Données) <sect1> Quelle est la taille maximum d'un tuple? <p> Les Tuples sont limités à 8K octets. En tenant compte des attributs du système et autre surcharge, on devrait rester bien à l'écart des 8,000 octets pour être tranquille. Pour utiliser des attributs supérieurs à 8K, essayez d'utiliser l'interface pour les grands objets. Les Tuples ne doivent pas franchir la frontière des 8k donc un tuple de 5k nécessitera un espace de stockage de 8k. <sect1> J'ai défini des index, mais mes requêtes ne paraissent pas en faire usage. Pourquoi? <p> PostgreSQL ne maintient pas automatiquement de statistiques. On doit réaliser un appel à une "réorganisation" explicite pour mettre les statistiques à jour. Après que les statistiques aient été mises à jour, l'optimiseur fera un meilleur usage des index. Notez que l'optimiseur des limité et n'utilise pas les index dans certaines circonstances (telles que les dans les clauses OR). Si le système ne voit toujours pas l'index, c'est probablement parce que vous avez créé un index sur un champ de type *_ops incorrect. Par exemple, vous avez créé un champ CHAR(4), mais vous avez spécifié un index de type_class char_ops. Consultez la page du manuel sur create_index pour avoir des informations sur les types de classes disponibles. Il doit correspondre au type de champ. Postgres ne prévient pas l'utilisateur quand un index incorrect est créé. Les index ne sont pas utilisés dans les opérations ORDER BY. <sect1> Existe-t-il des pilotes ODBC pour PostgreSQL? <p> Il y a deux pilotes ODBC disponibles, PostODBC et OpenLink ODBC. Pour tous ceux qui sont intéressés par PostODBC, il y a maintenant deux listes de diffusion consacrées aux discussions sur PostODBC. Ce sont : * <htmlurl url="mailto:postodbc-users@listserv.direct.net " name="postodbc-users@listserv.direct.net"> * <htmlurl url="mailto:postodbc-developers@listserv.direct.net "name="postodbc-developers@listserv.direct.net"> ces listes sont des listes de diffusion ordinaires gérées par majordomo. Vous pouvez vous inscrire en envoyant un courrier électronique à : * <htmlurl url="mailto:majordomo@listserv.direct.net "name="majordomo@listserv.direct.net"> OpenLink ODBC est actuellement en version bêta sous Linux. Vous pouvez le rapatrier de <url url="http://www.openlinksw.com/postgres.html"> Il fonctionne avec notre logiciel client ODBC standard vous aurez donc Postgres ODBC disponible sur toutes les plates formes clients que nous supportons (Win, Mac, Unix, VMS). Nous vendrons probablement ce produit aux gens qui ont besoin d'un support de qualité commerciale, mais une version libre sera toujours disponible. Adressez vos questions à <htmlurl url="mailto:postgres95@openlink.co.uk "name="postgres95@openlink.co.uk">. <sect1> Comment puis-je utiliser postgres avec un indexage multidimensionnel (> 2 dimensions)? <p> Les R-Trees intégrés peuvent traiter les polygones et les boîtes. En théorie, les R-trees peuvent être étendus pour prendre en charge un plus grand nombre de dimensions. En pratique, l'extension des R-trees demande un peu de travail et n'avons actuellement aucun document sur la manière de le faire. <sect1> Comment puis-je effectuer des recherches d'expressions régulières? une recherche d'expression régulière sans tenir compte des majuscules ou des minuscules? <p> <tscreen><verb> PostgreSQL supporte une syntaxe de type SQL LIKE de même qu'un système de recherche d'expressions régulières plus général avec l'opérateur ~. L'opérateur !~ est l'opérateur de négation de recherche d'expressions régulières. ~* et !~* sont les opérateurs d'expression régulières indifférents aux majuscules et aux minuscules. </verb></tscreen> <sect1> Je ne peux pas accéder à la base de données en tant qu'utilisateur 'root'. <p> Vous ne devriez pas créer d'utilisateurs de base de données avec l'identificateur d'utilisateur 0(root). Ils seront incapables d'accéder à la base de données. C'est une mesure de précaution à cause de la possibilité pour chaque utilisateur de lier dynamiquement des modules objets au moteur de base de données. <sect1> J'ai subit un crash du serveur pendant une réorganisation. Comment puis-je supprimer le fichier de verrouillage? <p> Si le serveur se crash pendant une commande de réorganisation, il y a des chances pour qu'il laisse un fichier de verrouillage en suspend quelque part. Une tentative de relancer la commande de réorganisation résultera dans le WARN:can't create lock file -- another vacuum cleaner running? Si vous êtes sûr qu'il n'y a pas de réorganisation en cours, vous pouvez supprimer le fichier appelé "pg_vlock" dans le répertoire de votre base de données (qui est &dollar PGDATA/base/< dbName >) <sect1> Quelle et la différence entre les différents types caractères? <p> <tscreen><verb> Type Nom Interne Notes -------------------------------------------------- CHAR char 1 caractère CHAR2 char2 2 caractères CHAR4 char4 4 caractères optimisé pour une longueur fixe CHAR8 char8 8 caractères CHAR16 char16 16 caractères CHAR(#) bpchar complété par des blancs jusqu'à la longueur fixe spécifiée VARCHAR(#) varchar la taille spécifie la longueur maximum, pas de remplissage TEXT text longueur limitée seulement par la longueur maximum du tuple BYTEA bytea tableau d'octets de longueur variable Rappelez vous, il vous faut utiliser le nom interne lorsque vous créez des index sur ces champs ou quand vous effectuez d'autres opérations internes. Les quatre derniers types ci-dessus sont des types "varlena" (i.e. les quatre premiers octets donnent la longueur, suivie par les données). CHAR(#) et VARCHAR(#) allouent le nombre maximum d'octets quelle que soient les données stockées dans le champ. TEXT et BYTEA sont les seuls types caractères qui ont une longueur variable sur le disque. </verb></tscreen> <sect1> Dans une requête, comment puis-je détecter si un champ est NULL? <p> PostgreSQL possède deux mots-clés intrinsèques, "isnull" et "notnull" (notez qu'il n'y a pas d'espaces). La Version 1.05 et suivante ainsi que la 6.* comprennent IS NULL et IS NOT NULL. <sect1> Comment puis-je voir que l'optimiseur de requête est en train d'évaluer ma requête? <p> Insérez le mot 'EXPLAIN' au début de la requête, par exemple : EXPLAIN SELECT * FROM table1 WHERE age = 23; <sect1> Comment puis-je créer un champ série? <p> Postgres ne permet pas à l'utilisateur de spécifier une colonne utilisateur comme ayant le type SERIAL. A la place, vous pouvez utiliser le champ oid de chaque ligne comme valeur unique. Cependant, si vous avez besoin de vider et de recharger la base de données, vous serez obligés d'utiliser pgdump de postgres version 1.07 ou ultérieur ou 6.* avec l'option -o'ou COPY avec l'option WITH OIDS pour conserver les oids. Une autre manière valide de le faire est de créer une fonction : create table my_oids (f1 int4); insert into my_oids values (1); create function new_oid () returns int4 as 'update my_oids set f1 = f1 + 1; select f1 from my_oids; ' language 'sql'; puis: create table my_stuff (my_key int4, value text); insert into my_stuff values (new_oid(), 'hello'); Cependant, il faut garder à l'esprit qu'il y a compétition ici où un serveur peut effectuer une mise à jour, puis un autre serveur effectuer une mise à jour et que les deux sélectionnent le même nouvel identificateur. Cette instruction doit être effectuée dans le cadre d'une transaction. Les Séquences sont implantées dans la version 6.1 <sect1> Comment puis-je créer un index multicolonnes? <p> Dans la version 6.0, vous ne pouvez pas directement créer un index multicolonnes en utilisant l'instruction "create index". Il vous faut définir une fonction qui agit sur les colonnes multiples, puis, utiliser "create index" avec cette fonction. En 6.1, cette fonctionnalité est disponible. <sect1> Que sont les fichiers temp_XXX dans le répertoire de ma base de données? <p> Ce sont les fichiers temporaires "temp_ files" créés par l'exécuteur de requête. Par exemple, si un tri doit être effectué pour réaliser une instruction ORDER BY, quelques fichiers temporaires sont crées en résultat du tri. Si vous n'avez pas de transactions ou de tri en cours à cet instant, vous pouvez supprimer ces fichiers temporaires "temp_ files" sans risques. <sect1> Pourquoi mes fichiers ne deviennent-ils pas petits après une suppression? <p> Si vous exécuter une réorganisation avec une version pre-6.0, les lignes non utilisées seront marquées pour être réutilisées, mais les blocs du fichier ne seront pas libérés. En 6.0, une réorganisation réduit la taille des tables correctement. <sect1> Pourquoi je ne peux pas me connecter à ma base de données à partir d'une autre machine? <p> La configuration par défaut permet uniquement de se connecter à partir de l'hôte tcp/ip localhost (machine locale). Vous devez ajouter une entrée pour un hôte supplémentaire dans le fichier pgsql/data/pg_hba. <sect1> J'ai l'erreur 'default index class unsupported' (index par défaut, classe non supportée) en créant un index. Comment dois-je faire? <p> Vous avez probablement utilisé : create index idx1 on person using btree (name); Les index PostgreSQL sont extensibles, et par conséquent en pre-6.0, vous devez spécifier un type de classe (class_type) quand vous créez un index. Lisez la page de manuel de create index (nommée create_index). Avec la version 6.0, si vous ne spécifiez pas de type de classe (class_type), il prend par défaut le type correspondant à la première colonne. <sect1> Pourquoi la création d'un index entraîne un crash de ma tâche de fond serveur? <p> Vous avez probablement définit un type de classe *_ops type incorrect pour le champ que vous voulez indexer. <sect1> Comment puis-je trouver quels index et quelles opérations sont définis dans la base de données? <p> Exécutez le fichier pgsql/src/tutorial/syscat.source. Il donne l'illustration de beaucoup de 'sélections' ('select's) à faire pour obtenir des informations sur les tables du système de gestion de base de données. <sect1> Pourquoi les instructions ont-elles besoin d'un caractère supplémentaire terminal? Pourquoi 'createuser' retourne 'unexpected last match in input()'? Pourquoi pg_dump ne fonctionne-t-il pas? <p> Vous avez compilé postgres avec flex version 2.5.3. Il y a un bogue dans cette version de flex. Utilisez la version 2.5.2 ou 2.5.4 de flex à la place. Il y a un fichier doc/README.flex qui doit faire un colmatage correct du code source flex 2.5.3. <sect1> Tous mes serveurs se plantent lors d'un accès concurrent à une table. Pourquoi? <p> Ce problème peut avoir son origine dans le noyau qui n'est pas configuré pour supporter les sémaphores. <sect1> Quels sont les outils disponibles pour ajouter des fonctionnalités aux pages Web de? <p> Pour une intégration au web, PHP/FI est une excellente interface. L'URL pour cela est <url url="http://www.vex.net/php/"> PHP est très bien pour des choses simples, mais pour si c'est plus compliqué, certains utilisent encore l'interface perl et CGI.pm. Un exemple d'utilisation de WWW avec C pour dialoguer avec Postgres peut être essayé, il est à: * <url url="http://www.postgreSQL.org/~mlc"> Une passerelle WWW basée sur WDB utilisant perl peut être téléchargée de : * <url url="http://www.eol.ists.ca/~dunlop/wdb -p95"> <sect1> Qu'est-ce que la fonctionnalité "time-warp" et en quoi cela concerne-t-il la réorganisation? <p> PostgreSQL traite les modifications de données de manière différente de la plupart des systèmes de gestion de bases de données. Quand une ligne est modifiée dans une table, la ligne originale est marquée avec un horodatage du moment où cette modification est intervenue, et une nouvelle ligne est créée avec les données actuelles. Par défaut, seulement les données actuelles sont utilisées dans une table. Si vous spécifiez une donnée date/heure à la suite du nom de la table dans une clause FROM, vous pouvez avoir accès aux données qui étaient "actuelles" à ce moment là, i.e. SELECT * FROM employees ['July 24, 1996 09:00:00'] affiche les lignes d'employés dans la ligne au moment spécifié. Vous pouvez spécifier des intervalles tels que [date,date], [date,], [,date], ou [,]. Cette dernière option permet d'accéder à toutes les lignes qui ont jamais existé. L'insertion (INSERT) de lignes reçoit également un horodatage, donc, les lignes qui n'étaient pas dans la table à l'instant désiré ne seront pas affichées. La réorganisation supprime les lignes qui ne sont plus "actuelles" (courantes). La fonctionnalité "time-warp" est utilisée par le moteur du SGBD pour l'annulation des modifications et pour la restauration après un plantage. Les dates/heures d'expiration peut être fixés avec la commande purge. En 6.0, après le nettoyage d'une table, la date de création d'une ligne peut être incorrecte, causant l'échec d'un parcours de la base de données basé sur les dates (time-travel). Cette fonctionnalité de "time-travel" a été supprimé dans la version 7.0. <sect1> Comment dois-je ajuster mon moteur de SGBD pour avoir de meilleures performances? <p> On peut faire deux choses. Vous pouvez utilisez l'option "Openlink" pour désactiver fsync() en lançant le postmaster avec l'option '-o -F'. Ceci évitera que des fsync() mettent à jour les données sur disque après chaque transaction. Vous pouvez également utiliser l'option -B du postmaster pour accroître le nombre de mémoires tampon partagées que doivent se partager les différents processus en tâche de fond. Si vous donnez une valeur trop élevée à ce paramètre, le processus ne sera pas lancé ou se plantera de manière inattendue. Chaque tampon fait 8K et leur nombre est de 64 par défaut. <sect1> Quelles sont les fonctionnalités disponibles pour la mise au point dans PostgreSQL? <p> PostgreSQL dispose de plusieurs fonctions qui donnent des informations sur son état qui peuvent être utiles pour des besoins de débogage. Tout d'abord, en compilant avec DEBUG définit, de nombreux assert()'s permettent de suivre l'avancement du processus de fond de plan et arrêtent le programme quand quelque chose d'inattendu se produit. A la fois le postmaster et postgres ont plusieurs options de débogage. Premièrement, à chaque fois que lancez le postmaster, assurez-vous de rediriger la sortie standard et les messages d'erreurs vers un fichier d'enregistrement, comme : <tscreen><verb> cd /usr/local/pgsql ./bin/postmaster >server.log 2>&1 & </verb></tscreen> Ceci créera un fichier server.log en tête de l'arborescence du répertoire de PostgreSQL. Ce fichier peut contenir des informations utiles concernant les problèmes et les erreurs rencontrés par le serveur. Postmaster possède une option -d qui permet d'obtenir des informations plus détaillées. L'option -d peut prendre une valeur de 1 à 3 qui spécifie le niveau de débogage. On obtient un fichier de débogage bavard qui peut être formaté en utilisant le programme 'indent'. (Il vous faudra peut être supprimer les lignes '====' dans les versions 1.*.) Faites attention au fait qu'un niveau de débogage supérieur à un entraîne la génération de fichiers d'enregistrement volumineux dans les versions 1.*. Vous pouvez , en réalité, faire tourner le processus de fond de plan postgres à partir de la ligne de commande, et taper vos instructions SQL directement. Ceci n'est recommandé que SEULEMENT dans des situations de débogage. Notez qu'un caractère saut de ligne termine la requête, pas un point-virgule. Si vous avez compilé en utilisant les symboles de débogage, vous pouvez peut-être utiliser un débogueur pour voir ce qui se passe. Le processus de fond de plan n'ayant pas été lancé par le postmaster, il ne tourne pas dans un environnement identique et les problèmes d'interaction processus de fond de plan/verrouillage peuvent ne pas être reproduits. Quelques systèmes d'exploitation peuvent se connecter à un processus de fond de plan directement pour diagnostiquer les problèmes. Le programme postgres possède les options a -s, -A, -t qui peuvent être très utiles pour la mise au point et pour la mesure de performances. La commande EXPLAIN (Voir dans cette FAQ) permet de voir comment PostgreSQL interprète votre requête. <sect1> Qu'est-ce qu'un oid? Qu'est-ce qu'un tid? <p> Les Oid sont la réponse de Postgres à des identificateurs de ligne uniques ou à des colonnes sérielles. Chaque ligne qui est créée dans Postgres reçoit un oid unique. Tous les oids générés par initdb sont inférieurs à 16384 (voir backend/access/transam.h). Tous les oids post-initdb (créés par un utilisateur) sont égaux ou supérieurs à cette valeur. Tous ces oids sont uniques, non pas seulement dans une table, ou une base de données, mais uniques à l'intérieur de l'installation postgres toute entière. Postgres utilise les oids dans ses tables système internes pour relier les lignes de tables séparées. Ces oids peuvent être utilisés pour identifier des lignes spécifiques à un utilisateur et dans les jointures. On recommande l'utilisation de colonnes de type oid pour stocker des valeurs d'oids. Consulter les pages de manuel sql(l) pour voir les autres colonnes internes. Les tids sont utilisés pour identifier des lignes physiques spécifiques contenant des valeurs de bloc ou de décalage. Les tids changent après une modification ou un rechargement des lignes. Ils sont utilisés par des enregistrements d'index pour pointer sur des lignes physiques. On ne peut pas y accéder par sql. <sect1> Quel est le sens de quelques termes utilisés dans? <p> Des parties du code source et d'anciennes documentations utilisent des termes qui sont d'un usage plus commun. En voici quelques uns : * row, record, tuple ligne, enregistrement, tuple * attribute, field, column attribut, champ, colonne * table, class table, classe * retrieve, select retrouver, sélectionner * replace, update remplacer, mettre à jour * append, insert ajouter, insérer * oid, serial value oid, valeur sérielle * portal, cursor portail, curseur * range variable, table name, table alias variable indiquant une étendue, nom de la table, alias de la table Merci de me faire savoir si vous pensez à d'autres. <sect1> Qu'est-ce que l'Optimisation de Requête Génétique? <p> Le module GEQO dans PostgreSQL est sensé résoudre le problème d'optimisation de requête sur la jointure de plusieurs tables au moyen d'un Algorithme Génétique (GA). Il permet le traitement de grandes jointures par l'intermédiaire d'une recherche non--exhaustive. Pour de plus amples informations voir README.GEQO <htmlurl url="mailto:utesch@aut.tu-freiberg.de "name="utesch@aut.tu-freiberg.de">. <sect1> J'utilise Solaris et l'affichage de mes dates est faux. Pourquoi? <p> Il y avait un bogue dans 6.0 qui causait ce problème sous Solaris avec l'optimisation -O2. Passez à la version 6.1. <sect1> Comment puis-je avoir plus de 32 processus d'arrière plan concurrents? <p> Editez include/storage/sinvaladt.h, et changez la valeur de MaxBackendId. Dans le futur, nous avons prévu de rendre ce paramètre configurable. --------------------------------------------------------------------------- <sect> FAQ - Etendre PostgreSQL <p> <sect1> J'ai écrit une fonction définie par l'utilisateur et quand je la fait tourner sous psql, j'ai un plantage avec vidage mémoire. <p> Ce problème peut provenir d'un certains nombre de causes. Tout d'abord, essayez de tester votre fonction dans un programme de test indépendant. Assurez-vous également que vous n'êtes pas en train d'envoyer des NOTICES elog quand le frontal attend des données, comme dans les fonctions type_in() or type_out() <sect1> J'ai des messages du type "NOTICE-PortalHeapMemoryFree- 0x402251d0 not in alloc set"! <p> Vous êtes en train de libérer (pfree) quelque chose qui n'a pas été alloué (palloc). Quand vous écrivez des fonctions définies par l'utilisateur, n'incluez pas le fichier "libpq-fe.h". Si vous faites cela, va entraîner que votre palloc soit un malloc à la place d'un free. Puis, quand la tâche de fond libère (pfrees) la mémoire, vous recevez le message NOTICE. <sect1> J'ai écrit quelques nouveaux types et quelques fonctions astucieux pour PostgreSQL. <p> S'il vous plaît, partagez-les avec les autre utilisateurs de PostgreSQL. Envoyez vos extensions dans la liste de diffusion, et elles finiront peut-être dans le sous-répertoire contrib/. <sect1> Comment dois-je écrire une fonction C qui retourne un tuple? <p> Cela nécessite beaucoup de génie, tellement que les auteurs n'ont jamais essayer, bien que, en principe, cela soit possible. Une réponse brève sera ... vous ne pouvez pas. Cette possibilité est envisagée dans le future. --------------------------------------------------------------------------- <sect> FAQ - Bogues <p> <sect1> Comment dois faire un rapport de bogue? <p> Regardez la FAQ courante à <url url="http://www.postgreSQL.org"> Regardez aussi à notre site ftp <url url="ftp://ftp.postgreSQL.org/pub"> pour voir s'il n'y a pas une version plus récente de PostgreSQL. Vous pouvez aussi remplir le fichier formulaire "bug-template" et l'envoyer à : * <htmlurl url="mailto:bugs@postgreSQL.org "name="bugs@postgreSQL.org"> C'est l'adresse de la liste de diffusion des développeurs. <sect> FAQ Linux-PostgreSQL - Compilation de PostgreSQL <p> ===================================================== Foire Aux Questions (FAQ) de PostgresSQL V6.0 Spécifique Linux A LIRE EN PARALLE AVEC LA FAQ NORMALE ===================================================== Dernière mise à jour: Wed Jan 29 20:16:00 GMT 1997 Gestionnaire actuel: Andrew C.R. Martin (<htmlurl url="mailto:martin@biochem.ucl.ac.uk " name="martin@biochem.ucl.ac.uk">) Auteur original: Andrew C.R. Martin (<htmlurl url="mailto:martin@biochem.ucl.ac.uk " name="martin@biochem.ucl.ac.uk">) <sect1> Quelles modifications dois-je apporter à src/Makefile.global ou src/Makefile.custom? <p> Ces modifications sont réalisées plus facilement en exécutant le script d'adaptation dans le répertoire src qui créera un fichier Makefile.custom pour vous. Si vous le faites par vous-même, vous *devez* renseigner la variable suivante : PORTNAME= linux Il vous faudra aussi modifier celle-ci pour refléter votre propre installation: POSTGRESDIR Si vous validez l'option USE_TCL option, vous devrez renseigner celles-ci : TCL_INCDIR= TCL_LIBDIR= TCL_LIB= TK_INCDIR= TK_LIBDIR= TK_LIB= X11_INCDIR= X11_LIBDIR= X11_LIB= Sur mon système Slackware3.0, ces données sont : TCL_INCDIR= /usr/include/tcl TCL_LIBDIR= /usr/lib TCL_LIB= -ltcl TK_INCDIR= /usr/include/tcl TK_LIBDIR= /usr/lib TK_LIB= -ltk X11_INCDIR= /usr/include/X11 X11_LIBDIR= /usr/X386/lib X11_LIB= -lX11 Vous pouvez aussi effectuer d'autres modifications dont vous avez besoin, ceci étant documenté dans les fichiers the INSTALL file and in Makefile.global <sect1> Pourquoi ai-je des problèmes avec "libreadline" manquant? <p> Les systèmes Linux ne sont généralement pas livrés avec la bibliothèque GNU readline installée. Soit vous vous assurez que vous n'avez pas activé les options readline dans src/Makefile.global ou src/Makefile.custom soit vous installez la bibliothèque GNU readline. Notez que Debian Linux (comme FreeBSD) est livré avec readline installé. <sect1> [REDHAT] Pourquoi ai-je des problèmes avec libdl and dlfcn.h manquants? <p> La bibliothèque libdl est utilisée pour la liaison dynamique de fonctions fournies par l'utilisateurs au moment de l'exécution. Pour une raison quelconque, cette bibliothèque a été oubliée dans la distribution Redhat. Il semble que ce problème a été résolu dans la version Redhat 4.0 (Colgate). RedHat possède maintenant un nouveau paquetage ld.so RPM sur son site FTP. Récupérez simplement : <url url="ftp://ftp.redhat.com/pub/redhat/devel/i386/RedHat/RPMS/ld.so-1.7.14-4.i386.rpm"> Installez le fichier RPM de la manière habituelle et c'est tout! Il y a eu des rapports indiquant que des systèmes ont été abîmés suite à l'accès à ces bibliothèques par certains programmes pendant leur mise à jour (ce qui n'est pas tout à fait surprenant). En conséquence, c'est une bonne idée de redémarrer le système avant l'installation de nouvelle bibliothèques et d'avoir le minimum de choses en fonction pendant ces mises à niveau. Passer en mode mono-utilisateur est certainement aussi une bonne idée! Si vous voulez le faire de la manière difficile, vous pouvez obtenir la bibliothèque et le fichier en-tête à : <url url="ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ld.so-1.7.14.tar.gz"> Autrement, vous pouvez obtenir les binaires précompilés dans distributions/debian/buzz/binary-i386/base/ld.so-1.7.14-4.deb sur le même site, ou suivre les instructions données pour la question 1.2 de correction de la même erreur avec les premières versions de Slackware 3.1. Ne pas utiliser cette méthode, à moins que vous sachiez ce que vous faites! <sect1> [SLACKWARE 3.1] Pourquoi ai-je des problèmes avec libdl and dlfcn.h manquants ? <p> Voir la réponse à la question 1.3. Slackware jusqu'à la version 3.0 était fourni avec cette bibliothèque et le fichier "include" et ils ont semblé revenir en arrière avec les dernières versions 3.1, mais les premières livraisons 3.1 (avant le 9 Septembre 1996) ne les avaient pas et beaucoup de versions CD-ROM ont été réalisés à partir de ces premières versions 3.1. Il y a eu des rapports indiquant que des systèmes ont été abîmés suite à l'accès à ces bibliothèques par certains programmes pendant leur mise à jour (ce qui n'est pas tout à fait surprenant). En conséquence, c'est une bonne idée de redémarrer le système avant l'installation de nouvelle bibliothèques et d'avoir le minimum de choses en fonction pendant ces mises à niveau. Passer en mode mono-utilisateur est certainement aussi une bonne idée! La meilleure manière de corriger cela est d'obtenir le fichier ldso.tgz du disque a4 d'une distribution plus récente de Slackware 3.1 de décompacter ce fichier à partir du répertoire root (/), puis de faire sh install/doinst.sh pour terminer l'installation, à la suite de cela, faites ldconfig Si vous voulez l'installer manuellement, vous devez d'abord installer le fichier dlfcn.h in /usr/include. Puis, installer le fichier libdl.so.1.7.14 (ou une version plus récente) dans /lib, puis faire : cd /lib ln -sf libdl.so.1.7.14 libdl.so.1 ln -sf libdl.so.1 libdl.so Sur quelques systèmes (dépendant de la configuration de GCC) il peut être nécessaire de faire : cd /usr/lib ln -sf /lib/libdl.so . Finalement ldconfig <sect1> Ma compilation du processus d'arrière plan échoue réclamant le "fichier include" dlfcn.h missing <p> Voir la réponse aux questions 1.3/1.4. N'oubliez pas que si vous utilisez un système a.out vous devez auparavant avoir installé le paquetage dld (qui n'est pas fourni avec la plupart des systèmes a.out) pour avoir dlfcn.h en entier. Voir Question 1.11. <sect1> GCC se plaint d'une option ignorée -fpic <p> Le première versions de GCC acceptaient soit -fpic soit -fPIC. Il apparaît que les plus récentes versions (V2.7.2?) requièrent -fPIC. Si vous utilisez une version ELF de Linux, on peut ignorer cela sans problème, puisque -fPIC est la valeur par défaut. Vous pouvez apporter une correction à cela en éditant le fichier src/Makefile.global et en changeant CFLAGS_SL <sect1> J'ai des messages d'avertissement du type "warning- cast from pointer to integer of different size" <p> Ils apparaissaient dans les premières versions de Postgres95 et peuvent, sans risque, être ignorés. PostgreSQL V6.0 doit pouvoir se compiler sans messages d'avertissement sauf ceux relatifs aux fichiers en-têtes système (qui peuvent également être ignorés sans risque). <sect1> [SuSE-Linux 4.2] Où sont curses et termcap? <p> SuSE-Linux a ncurses et non pas curses. Fixer la valeur de CURSES_LIB dans src/Makefile.custom à -lncurses (ou faites ceci par l'intermédiaire d'un script personnalisé). SuSE-Linux possède la bibliothèque termcap library dans /usr/lib/termcap au lieu de /usr/lib. Si vous avez un problème, il vous faut ajouter la ligne suivante à src/Makefile.custom: LDADD_BE+= -L/usr/lib/termcap Vous pouvez avoir besoin d'éditer src/bin/psql/Makefile et d'effectuer la modification de: ifeq ($(PORTNAME), linux) LD_ADD+= -ltermcap en: ifeq ($(PORTNAME), linux) LD_ADD+= <sect1> Pourquoi ai-je des problèmes avec ld.so? <p> Si vous avez des problèmes avec ld.so, une autre bibliothèque nécessaire en format ELF pour les liens dynamiques, alors c'est que vous avez bricolé votre système ou (plus vraisemblablement) effectué une mise à niveau de Linux. Voyez les réponses aux questions 1.3/1.4. Vous pouvez avoir besoin d'installer ld.so.x.y.z dans /lib et de faire tourner ldconfig. La version stable la plus récente du paquetage ld package est 1.7.14 Au moment de la rédaction de ce texte, les versions 1.8.x de ld sont expérimentales. <sect1> Pourquoi ai-je les erreurs `yy_flush_buffer undefined'? <p> Ce n'est pas réellement spécifique à Linux, mais c'est courant sur les installations Linux les plus anciennes. Il vous faut une version récente de flex (2.5.2 ou suivantes) pour compiler PostgreSQL. Notez que flex 2.5.3 a un bogue: voir la Question 3.4. <sect1> Comment dois-je compiler PostgreSQL sur un système a.out? <p> Premièrement, vous devez installer la bibliothèque dld. On peut l'obtenir sur le site Sunsite sous le nom : Linux/libs/dld.3.2.7.tar.gz Deuxièmement, ajouter la ligne suivante au fichier src/Makefile.custom: LINUX_ELF= (ou utilisez un script personnalisé) <sect1> Pourquoi make échoue-t-il avec - yacc -d /disk2/PostgreSQL/src/backend/parser/gram.y make- /usr/bin/make- cannot execute binary file <p> Ce fut un problème des premières versions de Postgres95. Pour PostgreSQL on utilise bison -y par défaut plutôt que yacc. yacc est généralement implanté comme script qui invoque bison -y Pour une raison quelconque (certaines versions de make? certaines versions de bash?) make est incapable d'exécuter ce fichier script. Pour corriger cela, éditez simplement src/mk/port/postgres.mk.linux et, à la fin du fichier, changez : # YACC = bison -y en YACC = bison -y <sect1> Que sont les références à libsocket dans X11_LIB et libnsl dans src/Makefile.global? <p> Ce fut un problème dans la version 1.08 (elles sont spécifiques à Sun Solaris). Cela a été corrigé dans 1.09 et 6.0 <sect1> [DEBIAN] Où se trouve libtermcap? <p> Le Linux de Debian est livré sans bibliothèque termcap et utilise ncurses (qui à la place utilise terminfo). Il n'y a pas besoin de modifier la variable CURSES_LIB dans src/bin/psql/Makefile puisque Debian fournit un lien de libncurses vers libcurses (à la différence de SuSE-Linux --- voir la Question 1.8). Vous pouvez avoir besoin d'éditer src/bin/psql/Makefile et de changer: ifeq ($(PORTNAME), linux) LD_ADD+= -ltermcap en: ifeq ($(PORTNAME), linux) LD_ADD+= <sect> FAQ Linux-PostgreSQL - Compilation des programmes accessoires <p> <sect1> L'éditeur de liens n'arrive pas à trouver libX11 quand on compile pgtclsh <p> Ajoutez ce qui suit à src/Makefile.custom X11_LIBDIR = /usr/X11R6/lib <sect> FAQ Linux-PostgreSQL - Problèmes d'exécution <p> <sect1> J'ai une erreur indiquant _fUnKy_POSTPORT_sTuFf_ non défini quand j'exécute les scripts tels que createuser <p> C'est un bogue dans la V1.06-V1.07 de Postgres et il est corrigé dans la version V1.08 et au-dessus. <sect1> Je lance postmaster et ensuite le système affiche 'Bad system call(Core dumped)' <p> Ceci indique que vous n'avez pas compilé le support de la mémoire partagée dans votre noyau. Il vous faut recompiler le noyau Linux en incluant cette fonctionnalité. <sect1> Quand j'essaie de lancer le Postmaster, pourquoi ai-je une erreur de la forme Failed Assertion("!(file != 0) - (null)", File <p> Failed Assertion("!(file != 0):(null)", File: "/usr/local/PostgreSQL/src/backend/storage/file/fd.c", Line: 257) !(file != 0) (0) initdb: could not create template database initdb: cleaning up. Vos permissions sur le fichier /dev/null ne sont pas bonnes. ls -l /dev/null devrait vous donner quelque chose comme: crw-rw-rw- 1 root wheel 2, 2 Oct 8 18:41 /dev/null Corrigez les permissions en utilisant : chmod a+rw /dev/null <sect1> Pourquoi createuser ne fonctionne-t-il pas? <p> Il y a un problème avec la Version 2.5.3 de GNU flex et de createuser. Vos options sont de revenir à la version V2.5.2 de flex, d'appliquer une rustine à la version V2.5.3 (fournie dans doc/README.flex) ou d'attendre la version V2.5.4 qui corrigera ce bogue. <sect1> Pourquoi ai-je une erreur comme IpcMemoryCreate- memKey=155356396 , size=760632 , <p> permission=384IpcMemoryCreate: shmget(..., create, ...) failed: Invalid argument Vous n'avez pas inclus le support IPC dans votre noyau Linux. Il vous faudra reconstruire le noyau et valider cette option. <sect1> Pourquoi psql échoue avec psql- can't load library 'libpq.so.1' <p> Psql a été compilé pour être lié dynamiquement avec la bibliothèque libpq. Pour remédier à cela, vous devez vous connecter comme root et éditer le fichier /etc/ld.so.conf Ajouter une simple ligne à la fin qui donne le nom du répertoire de la bibliothèque PostgreSQL (le sous-répertoire lib de votre installation pour PostgreSQL) et exécuter /sbin/ldconfig <sect> FAQ IRIX-PostgreSQL - Compilation de PostgreSQL <p> ===================================================== Foire Aux Questions (FAQ) for PostgresSQL V6.1 Spécifique IRIX A LIRE EN PARALLELE AVEC LA FAQ NORMALE ===================================================== Dernière mise à jour: Vendredi 13 Juin 09:54:00 BST 1997 Gestionnaire actuel: Andrew C.R. Martin (<htmlurl url="mailto:martin@biochem.ucl.ac.uk" name="martin@biochem.ucl.ac.uk">) Auteur original author: Andrew C.R. Martin (<htmlurl url="mailto:martin@biochem.ucl.ac.uk" name="martin@biochem.ucl.ac.uk">) Modifications dans cette version (* = modifié, + = nouveau, - = supprimé): +1.5) Puis-je installer PostgreSQL sous Irix 6.4? Ce fichier est divisé approximativement comme suit : <itemize> <item>1.*) Installation de Postgres95 <item>2.*) Désinstallation de Postgres95 <item>3.*) Extension de Postgres95 </itemize> <sect> FAQ-IRIX Installation de Postgres95 <p> <sect1> De quels éléments supplémentaires ai-je besoin pour installer Postgres95 sous Irix? <p> Vous *devez* avoir les éléments suivants installés: <itemize> <item> a) Gnu make (installé sous le nom gmake) </itemize> Nous vous recommandons d'installer ce qui suit : <itemize> <item> a) GNU install (installé sous le nom ginstall) </itemize> Vous pouvez choisir d'installer : <itemize> <item> a) La bibliothèque GNU readline (si vous désirez que psql ait le support de readline). <item> b) Tcl/Tk (si vous souhaitez compiler pgtclsh) </itemize> <sect1> Quelles modifications dois-je apporter à src/Makefile.global ou src/Makefile.custom? <p> La manière la plus simple de faire cela est d'utiliser le script personnalisé dans le répertoire src. Vous *devez* renseigner les variables suivantes : PORTNAME= irix5 Vous aurez aussi besoin de changer ce qui suit pour s'adapter à votre propre installation : POSTGRESDIR Si vous activez l'option USE_TCL, vous aurez besoin de renseigner: TCL_INCDIR= TCL_LIBDIR= TCL_LIB = TK_INCDIR= TK_LIBDIR= TK_LIB = Vous pouvez également faire toutes les autres modifications dont vous avez besoin comme indiqué dans le fichier INSTALL file et dans Makefile.global <sect1> Que sont les références a libsocket dans X11_LIB et à libnsl dans src/Makefile.global? <p> Ce fut un problème dans la version 1.08 (elles sont spécifiques à Sun Solaris). Cela a été corrigé dans 1.09 et 6.0 <sect1> Are there any other changes I should make? <p> Si vous avez installé le programme GNU install (ginstall), vous devriez ajouter la ligne suivante à src/Makefile.custom: CUSTOM_INSTALL=ginstall Pour une explication sur ce point, voir la Question 2.1 <sect1> Puis-je installer PostgreSQL sous Irix 6.4? <p> Irix 6.4 a un bogue dans ld qui l'empêche de prendre en compte correctement les adresses des procédures statiques quand les fichiers objets sont assemblés en fichiers objets plus grands en utilisant 'ld -r'. Ce bogue a été rapporté à Silicon Graphics. La rustine suivante peut être appliquée pour le contourner. (Fourni par Bob Bruccoleri <htmlurl url="mailto:bruc@bms.com" name="bruc@bms.com">) *** ./backend/Makefile.orig Thu May 22 00:00:15 1997 --- ./backend/Makefile Thu Jun 5 16:47:27 1997 *************** *** 54,60 **** all: postgres &dollar (POSTGRES_IMP) global1.bki.source local1_template1.bki.source postgres: &dollar (OBJS) ../utils/version.o ! &dollar (CC) -o postgres &dollar (OBJS) ../utils/version.o &dollar (LDFLAGS) &dollar (OBJS): &dollar (DIRS:%=%.dir) --- 54,64 ---- all: postgres &dollar (POSTGRES_IMP) global1.bki.source local1_template1.bki.source postgres: &dollar (OBJS) ../utils/version.o <!-- aldev removed the brackets from cp below ! find . -name "*.o" -exec cp \{\} . \; --> <tscreen><verb> ! # &dollar (CC) -o postgres &dollar (OBJS) ../utils/version.o &dollar (LDFLAGS) ! -rm -f *.o ! find . -name "*.o" -exec cp (flower-brackets) . \; </verb></tscreen> ! rm -f SUBSYS.o ! &dollar (CC) -o postgres *.o ../utils/version.o &dollar (LDFLAGS) &dollar (OBJS): &dollar (DIRS:%=%.dir) <sect> FAQ-IRIX Désinstallation de Postgres95 <p> <sect1> Pourquoi ne puis-je pas déplacer les fichiers exécutables? <p> Par défaut, le portage IRIX utilise la version compatible BSD du programme install de /usr/bin/X11. Si vous lisez la page de manuel pour cette version d'install, vous verrez que son utilisation n'est pas destinée à l'utilisateur final; il possède l'effet de bord intéressant de changer le propriétaire des fichiers qu'ils installe en root. Vous devriez encore pouvoir détruire les fichiers puisque vous (utilisateur postgres) êtes propriétaire du répertoire dans lequel ils sont stockés. Le programme install normal de IRIX ne peut pas être utilisé facilement car il prend ses arguments en ordre inverse. De ce fait, on recommande d'utiliser la version GNU du programme install (ginstall). Voir la Question 1.4 <sect> FAQ-IRIX Extending Postgres95 <p> <sect1> Comment dois-je compiler un programme C pour créer une fonction d'extension à Postgres95 <p> Voici une ligne de commande en exemple : cc -I/usr/local/postgres95/include/ -I/usr/local/postgres95/src/backend -shared -o funcs.so funcs.c <sect> FAQ-IRIX PostgreSQL contact des AUTEURS <p> Dr. Andrew C.R. Martin University College Londres EMAIL: (Work) <htmlurl url="mailto:martin@biochem.ucl.ac.uk" name="martin@biochem.ucl.ac.uk"> (Home) <htmlurl url="mailto:andrew@stagleys.demon.co.uk " name="andrew@stagleys.demon.co.uk"> URL: <url url="http://www.biochem.ucl.ac.uk/~martin"> Tel: (Work) +44(0)171 419 3890 Tel: (Home) +44(0)1372 275775 <sect> Notice de Copyright <p> Copyright (c) 1997 Al Dev (Alavoor Vasudevan). Tous droits réservés. La permission d'utiliser, de copier, de modifier et de distribuer ce document, gratuitement, et sans accord écrit est accordée, à condition que la notice de copyright ci-dessus, ce paragraphe et les deux paragraphes suivants apparaissent dans toutes les copies. Les marques, les compagnies et les noms de produits mentionnés dans ce document sont des marques de fabrique ou des marques déposées de leurs propriétaires respectifs. Veuillez vous référer aux notices de copyright individuelles de marques, compagnies et produits mentionnés dans ce document. Ce document est délivré "tel quel" et l'auteur n'apporte aucune garantie explicite ou implicite. </article>