  Database-SQL-RDBMS HOW-TO pour Linux
  Al Dev (Alavoor Vasudevan)        aldev@hotmail.com
  v4.0, 21 December 1997, version francaise Mars 1998

  Ce  document est un "guide pratique" pour la mise en place rapide d'un
  moteur de Base de Donnees SQL et des outils frontaux  sur  un  systeme
  Unix.  Il  traite egalement du langage standard International ANSI/ISO
  SQL et passe en revue les merites/avantages d'un  moteur  de  Base  de
  Donnees  developpe  dans le cadre mondial de l'environnement de devel-
  oppement ouvert d'internet.  Ce document explique  COMMENT  mettre  en
  place  une Base de Donnees Relationnelle SQL Objet de la nouvelle gen-
  eration "PostgreSQL" sur votre systeme unix qui pourra  etre  utilisee
  comme Base de Donnees Serveur d'Application ou Serveur Web. PostgreSQL
  se rapproche chaque mois un peu plus des normes Internationales ISO et
  ANSI  SQL 1998,92,89. Ce document donne aussi des informations sur les
  programmes d'interface a la base de donnees tels  que  frontaux  GUIs,
  outils RAD (Developpement Rapide d'Application ), interfacage des lan-
  gages de programmation ("C", "C++", Java, Perl),  pilotes  ODBC,  JDBC
  ainsi  que sur les outils et programmes interfacage d'une Base de Don-
  nees Web . L'information donnee ici est  valable  pour  toutes  autres
  plates-formes  unix et autres Bases de Donnees. Cette information sera
  tres utile aux nouveaux utilisateurs des Bases de  Donnees,  de  Post-
  greSQL  et  du langage SQL.  Ce document comporte aussi un didacticiel
  SQL et les specifications de la syntaxe  SQL  qui  devrait  etre  tres
  utile aux debutants. Les gens experimentes trouveront dans ce document
  un guide de reference tres pratique. Pour les etudiants, l'information
  donnee  ici leur permettra d'obtenir le code source du Systeme de Ges-
  tion de Base de Donnees Relationnel (SGBDR) PostgreSQL a partir duquel
  ils pourront etudier comment un moteur de SGBDR SQL est ecrit.

  11..  IInnttrroodduuccttiioonn

  Tout systeme informatique au monde a besoin d'une base de donnees pour
  stocker/retrouver  les  informations.  Sans  base   de   donnees,   un
  ordinateur  devient  inutile.  La  premiere  raison  pour  laquelle on
  utilise  un  ordinateur  est  de   stocker,   retrouver   et   traiter
  l'information  et  de  faire  cela  tres rapidement, et donc, de faire
  economiser du temps. En  meme  temps  le  systeme  doit  etre  simple,
  robuste,  rapide,  fiable,  economique  et  d'utilisation  aisee.  Les
  systemes de gestion de base de donnees les plus  courants  sont  bases
  sur  les  specifications ISO (International Standard Organisation) SQL
  lesquelles sont egalement basees sur les normes americaines ANSI  SQL.
  Les specifications courantes generalement utilisees sont l'ANSI SQL 92
  et l'ANSI SQL 89. La prochaine norme est la SQL 1998/99 aussi  appelee
  SQL-3.  Les  systemes de gestion de bases de donnees les plus repandus
  tels que Oracle, Sybase et Informix s'appuient sur  ces  standards  ou
  essaient de les implementer.

  Ainsi  qu'il est indique dans ce document, il y a plus de 20 varietes,
  commerciales/internet, de systemes  de  gestion  de  base  de  donnees
  actuellement utilises dans le monde et beaucoup, beaucoup plus dans un
  futur proche. En l'absence d'une norme telle que  l'ANSI/ISO  SQL,  il
  serait tres difficile pour l'utilisateur de developper une application
  une fois pour toutes et  de  l'utiliser  avec  tous  les  systemes  de
  gestion   de   bases   de  donnees.  Aujourd'hui,  l'utilisateur  veut
  developper son application une  fois  pour  toutes  en  utilisant  les
  normes  ISO  SQL,  ODBC,  JDBC  et  la vendre afin qu'elle puisse etre
  utilisee sur une grande variete de systemes  de  gestion  de  base  de
  donnees a travers le monde.

  PostgreSQL  est la Base de Donnee LIBRE la plus populaire au monde qui
  implemente la plupart des normes ISO SQL, ANSI SQL/98, SQL/92 et  ANSI
  SQL/89  RDBMS.  PostgreSQL est une base de donnees relationnelle Objet
  de la nouvelle generation et les futures normes ANSI SQL tels  que  le
  SQL  1998 (SQL-3) et au-dela traiteront de maniere croissante de bases
  de donnees Objet et de types de donnees Objet. PostgreSQL est le  seul
  SGBD  (RDBMS  -  Relational  Data Base Management System) au monde qui
  supporte les bases de donnees Objet et SQL. Ce document vous  explique
  comment  installer  le systeme de gestion de base de donnees ainsi que
  tous les paquetages concernant les bases de donnees, comment mettre en
  place  la  base  de  donnees Web, la base de donnees application , les
  frontaux GUIs et  les  programmes  interfacage.  On  ne  saurait  trop
  RECOMMANDER   d'ecrire   vos   applications   bases   de  donnees  100
  %compatibles avec les normes ISO/ANSI SQL,  ODBC,  JDBC  ceci  rendant
  votre  application portable sur de multiples SGBD (Systemes de gestion
  de Bases de Donnees) tels que  PostgreSQL,  Oracle,  Sybase,  Informix
  etc.

  La  haute  qualite, et un large ensemble de possibilites de PostgreSQL
  viennent du fait que ce systeme est developpe suivant le  principe  du
  sont  ceux  ou  la  totalite  du  code  source  est  fournie  et ou le
  developpement  se  fait  a  travers  l'internet  par  une  tres  large
  communaute  de  cerveaux  humains  en  reseau.  La tendance future des
  developpement logiciels reside dans ce que  l'on  appelle  les  "super
  autoroutes de l'information" qui s'etendent a travers le monde entier.
  Dans les annees a venir, la croissance d'internet va etre 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 mathematiques et des statistiques a  la  qualite
  des logiciels, on obtient la meilleure qualite des logiciels 'Systemes
  Ouverts' tel que PostgreSQL en mettant le code source des programmes a
  la  disposition  d'un  grand nombre de cerveaux humains interconnectes
  par les super-autoroutes de l'information. Plus le nombre de  cerveaux
  au  travail sera grand, meilleure sera la qualite du logiciel produit.
  Le modele "Systeme Ouvert" evite aussi de reinventer la roue  tout  en
  etant   particulierement   economique,  en  diminuant  les  delais  de
  distribution   et   en   suivant   les   lois   economiques   modernes
  d'optimisation  des  ressources  nationales et globales. Dans un futur
  proche, a l'aube du 21-ieme siecle,  la  maniere  de  se  procurer  un
  logiciel va changer. Les utilisateurs accorderont en premier lieu leur
  preference aux logiciels ouverts tel PostgreSQL.

  Acheter  un  logiciel  PEUT  devenir  une  attitude  archaique.  On  a
  seulement  besoin d'acheter un bon materiel, il vaut mieux de depenser
  de l'argent en materiel et trouver le logiciel sur internet.  Le point
  important,   c'est  que  le  gros  du  travail  est  effectue  par  le
  materiel(99 %). Le materiel est le cheval de bataille et  le  logiciel
  apporte   une  contribution  mineure.   C'est-a-dire  que  le  travail
  effectue par le logiciel est insignifiant compare a celui du  materiel
  de   l'ordinateur.  Le  materiel  est  tellement  plus  complique  que
  seulement 6 pays sur  180  au  monde  ont  demontre  leur  capacite  a
  concevoir  et a fabriquer les composants d'ordinateurs. La fabrication
  de composants d'ordinateurs est un processus  tres  complexe  de  tres
  haute  technologie,  requerant de tres larges investissements en usine
  et en machines  de  production  maitrisant  la  technologie  des  0.25
  micron, des milliards de transistors/circuits implantes sur une petite
  puce de silicium, et qui, encore aujourd'hui ne peut etre maitrise par
  de  nombreux  pays developpes!.  Des compagnies telles que AMD, Intel,
  Cyrix, Hitachi, Ibm et autres ont depense des  milliards  d'hommes-ans
  de travail pour maitriser des hautes technologies telles que la Micro-
  electronique et la Nano-electronique (Micro  signifie  millionieme  de
  metre  et  Nano  signifie  milliardieme  de  metre).   La  technologie
  actuelle  utilise  la  micro-electronique  a  0.35  microns  avec  des
  conducteurs   en   aluminium,   celle  de  0.25  microns  utilise  des
  conducteurs de cuivre. Dans un futur proche, la technologie  des  0.10
  microns  avec  conducteurs de cuivre et meme la nano-electronique sera
  utilisees pour les circuits integres d'ordinateurs.

  Comme on peut le voir c'est le materiel qui est important et de  haute
  technologie,  le  logiciel  est  une technologie courante et N'EST PAS
  aussi important. Donc la  fabrication  de  materiel  est  vitale  pour
  l'economie   nationale!.   Des  compagnies  comme  Compaq,  Dell,  Sun
  Microsystems, HP, IBM qui fabriquent des  ordinateurs  contribuent  de
  facon importante a l'economie U.S. aujourd'hui et dans le futur!!

  D'un  autre  cote, chaque pays au monde developpe/produit du logiciel.
  En fait, n'importe qui dans le monde, avec  un  petit  PC  economique,
  peut  creer  un systeme serveur de base de donnees Oracle!!  Mais cela
  lui prendra environ 20 ans (Le  serveur  de  base  de  donnees  Oracle
  correspond a plus de 20 hommes-ans de travail). Un homme-an correspond
  au travail d'un homme a temps plein pendant une annee. Si 20 personnes
  travaillent pendant un an cela correspond a 20 hommes-ans.

  Des SGBD tels que Oracle, Informix, Sybase, IBM DB2 sont ecrits a 100%
  en langage C et les binaires crees par compilation de ces sources sont
  fournis aux clients.

  Puisqu'une  masse importante de travail a ete effectuee sur PostgreSQL
  au cours des 12 dernieres annees, cela n'aurait aucun sens de  recreer
  ex-nihilo  un autre systeme de gestion de base de donnees satisfaisant
  aux normes ANSI/ISO SQL. Il est bien plus interessant  de  prendre  le
  code existant de PostgreSQL, de commencer a l'utiliser, de l'ameliorer
  et d'y ajouter les fonctionnalites manquantes.

  PostgreSQL n'est pas seulement un SGBD libre mais  aussi  un  "Produit
  Internet"  et  a  ce titre merite respect et reconnaissance de tout un
  chacun.

  22..  QQuu''eesstt--ccee qquuee PPoossttggrreeSSQQLL ??

  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 materielles
  sous differents Systemes d'Exploitation.

               Quelquefois des corrections urgentes d'erreurs sont diffusees apres la diffusion
               d'une revision de PostgreSQL. Vous pouvez appliquer ces rustines optionnelles
               selon les besoins de votre application. Effectuez les etapes suivantes pour
               appliquer ces rustines -
                       cd "Vers le repertoire source de postgresql"
                       patch < "Specifiez le nom du fichier rustine (fichier patch) ici"
                       make clean
                       make

  L'objectif ultime et  le  but  final  de  PostgreSQL  est  de  devenir
  compatible  a  100  %  a la norme ANSI/ISO SQL ainsi que de devenir le
  numero UN mondial des systemes de gestion de Base de  Donnees  ouverts
  generiques.   PostgreSQL  guidera,  conduira,  controlera,  suivra  et
  dictera le futur de l'ANSI/ISO SQL.  C'est-a-dire, l'implementation et
  les idees se feront en premier dans PostgreSQL puis, plus tard, seront
  incorpores dans  l'ANSI/ISO  SQL.  PostgreSQL  represente  "l'etat  de
  l'art" de la technologie des bases de donnees.

  Le  serveur  Informix  Universal  (diffuse  en  1997) est base sur une
  version precedente de PostgreSQL car Informix a achete  Illustra  Inc.
  et  l'a  integree  a  Informix.  La  base  de  donnees  Illustra etait
  completement basee sur Postgres (version precedente de PostgreSQL).

  PostgreSQL  est  une  amelioration  du  SGBD  POSTGRES,  prototype  de
  recherche  de  SGBD  de  la  prochaine generation. PostgreSQL, tout en
  conservant le puissant modele de donnees et la richesse des  types  de
  donnees  de  POSTGRES,  remplace le langage de requete PostQuel par un
  sous-ensemble etendu de SQL.

  Le  developpement  de  PostgreSQL  est  realise  par  une  equipe   de
  developpeurs  Internet  qui sont tous inscrits a la liste de diffusion
  "PostgreSQL developpement mailing list".  Son coordinateur actuel  est
  Marc  G. Fournier scrappy@postgreSQL.org . Cette equipe est maintenant
  responsable des developpements actuels et futurs de PostgreSQL.

  Les auteurs de  PostgreSQL 1.01 sont Andrew  Yu  et  Jolly  Chen.   De
  nombreux  autres  ont  contribue  au  portage, aux tests, a la mise au
  point et a l'amelioration du code. Le code original  Postgres,  duquel
  PostgreSQL est issu, est le resultat de l'effort de nombreux etudiants
  de troisieme  cycle,  de  deuxieme  cycle  et  d'enseignants  sous  la
  direction   du  Professeur  Michael  Stonebraker  de  l'universite  de
  Californie, Berkeley.

  Le nom original du logiciel a Berkeley etait Postgres. Lors de l'ajout
  des fonctionnalites SQL en 1995, il fut renomme Postgres95. Ce nom fut
  change a la fin de 1996 en PostgreSQL.

  Des millions d'exemplaires du SGBD  PostgreSQL  sont  installes  comme
  serveurs,  serveurs  Web  et  serveurs d'application. Ce SGBD est tres
  avance, c'est un SGBD Relationnel-Objet (ORDBMS).

  PostgreSQL peut stocker  plus  de  types  de  donnees  que  les  types
  traditionnels  entier, caracteres, etc. - L'utilisateur peut creer des
  types, des fonctions, de l'heritage  de  type  etc.  (La  Version  7.0
  rendra  ces  fonctions  avancees  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 realisation.

  +o  Titre :           PostgreSQL SQL RDBMS Database (Systeme de Gestion
     de Base de Donnees Relationnelle Objet)

  +o  Version actuelle : 6.2.1 patch level 3

  +o  Age :           PostgreSQL a 12 ans. En developpement depuis 1985

  +o  Auteurs      :              Developpe      par     des     millions
     d'universites/compagnies sur internet au  cours  des  12  dernieres
     ANNEES

  33..  OOuu llee ttrroouuvveerr??

  On peut acheter le CDROM Linux Redhat 4.2, le CDROM Linux Debian ou le
  CDROM Linux Slackware qui contiennent deja postgresql en paquetage rpm
  (a la fois en code source et en binaires) au :

  +o  site  Web  Linux  System  Labs  :   <http://www.lsl.com/>   7 (U.S.
     dollars)

  +o  site Web Cheap Bytes Inc :   <http://www.cheapbytes.com/>  7  (U.S.
     dollars)

  +o  site Web Principal Debian, contact: Oliver.Elphick@lfix.co.uk

  Dans  un futur proche, l'organisation PostgreSQL vendra un 'PostgreSQL
  CDROM' qui contiendra le code source complet et les binaires pour tous
  les systemes d'exploitation Unix.

  Distributions uniquement en binaire de PostgreSQL :

  +o  On  peut executer PostgreSQL sans compiler le source. Recuperer les
     binaires         pour         Intel-Linux         de          l'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  a  la  fois  le  source  et  les  binaires de
     PostgreSQL.

  +o  Sites  binaires  pour   Solaris,   HPUX,   AIX,   IRIX,   Linux   :
     <ftp://ftp.postgresql.org/pub/bindist>    Si    vous   faites   une
     compilation pour n'importe laquelle des  plates-formes  envoyer  le
     binaire a ce site, cela peut etre utile aux autres.

  +o  site   ftp   :   recuperer   les   binaires   pour  Intel-Linux  de
     <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  a  la  fois  le  source  et  les  binaires  de
     PostgreSQL.

  Sites WWW Web :

  +o  Site Web primaire :    <http://www.postgresql.org/>

  +o  Site Web secondaire :  <http://logical.thought.net/postgres95/>

  +o  <http://www.itm.tu-clausthal.de/mirrors/postgres95/>

  +o  <http://s2k-ftp.cs.berkeley.edu:8000/postgres95/>

  +o  <http://xenium.pdi.net/PostgreSQL/>

  +o  <http://s2k-ftp.cs.berkeley.edu:8000/postgres95/>

  Les sites ftp sont indiques ci-dessous :-

  +o  Primaire FTP :       <ftp://ftp.postgresql.org/pub>

  +o  Secondaire FTP :     <ftp://ftp.chicks.net/pub/postgresql>

  +o  <ftp://ftp.emsi.priv.at/pub/postgres/>

  +o  <ftp://ftp.itm.tu-clausthal.de/pub/mirrors/postgres95>

  +o  <ftp://rocker.sch.bme.hu/pub/mirrors/postgreSQL>

  +o  <ftp://ftp.jaist.ac.jp/pub/dbms/postgres95>

  +o  <ftp://ftp.luga.or.at/pub/postgres95>

  +o  <ftp://postgres95.vnet.net:/pub/postgres95>

  +o  <ftp://ftpza.co.za/mirrors/postgres>

  +o  <ftp://sunsite.auc.dk/pub/databases/postgresql>

  +o  <ftp://ftp.task.gda.pl/pub/software/postgresql>

  +o  <ftp://xenium.pdi.net/pub/PostgreSQL>

  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.

  +o  Pour  obtenir  la  liste  des   sites   miroirs   aller   a   l'url
     <ftp://sunsite.unc.edu>

  44..   PPoossttggrreeSSQQLL SSuuppppoorrttee ddeess BBaassee ddee DDoonnnneeeess eexxttrreemmeemmeenntt ggrraannddeess >> 220000
  GGiiggaass

  Les  performances  des  machines  a  cpu 32-bit decroissent rapidement
  quand la taille de la base de donnees  depasse  5  giga.  Vous  pouvez
  faire  tourner des bases de donnees de 30 gigas avec un cpu 32-bit cpu
  mais cela ne sera pas tres performant. Cette  limitation  est  imposee
  par la quantite maximum de memoire RAM (maximum de 2 gigas seulement),
  la limitation de la taille du systeme de  fichier  ainsi  que  par  le
  systeme d'exploitation.  Avec un cpu 32-bit, le systeme d'exploitation
  "se cognera la tete" trop souvent sur "le plafond 32-bit".

  Si vous avez  besoin  d'utiliser  des  bases  de  donnees  extremement
  grandes  (superieures  a  5  gigaoctets),  il est fortement recommande
  d'utiliser des machines 64-bit telles que :  Digital  Alpha  cpu,  Sun
  Ultra-sparc  64-bit  cpu,  Silicon  graphics 64-bit cpu, a venir Intel
  Merced IA-64 cpu, machines HPUX 64bit , machines IBM 64-bit.  Si  l'on
  compile  PostgreSQL  avec  un cpu 64-bit il pourra supporter d'enormes
  bases  de  Donnees  et  de  grosses  requetes.  Les  performances   de
  PostgreSQL pour des interrogations sur de grandes tables et de grandes
  bases de donnees sera plus rapide de plusieurs ordres de grandeurs que
  sur  des  machines  a  cpu 32-bit . L'avantage des machines 64-bit est
  qu'elles disposent d'un grand espace d'adressage  memoire  et  que  le
  systeme d'exploitation peut gerer de tres grands systemes de fichiers.
  Cela permet des meilleures  performances  avec  de  grandes  bases  de
  donnees, plus de memoire centrale (RAM), plus de possibilites etc...

  55..  PPoossttggrreeSSQQLL eesstt--iill ffiiaabbllee??

  Le  paquetage  de  "Test de Regression" permet de s'assurer de son bon
  fonctionnement.  Il est inclus (src/test/regress) dans la distribution
  et  permet  a  l'ordinateur d'effectuer la verification des operations
  SQL standard ainsi que des capacites de PostgreSQL. L'avantage  de  ce
  test  effectue  par  l'ordinateur  vient  du  fait  que  celui-ci peut
  effectuer plusieurs millions de test SQL tres 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 a  envoyer  ces  tests  au  site
  PostgreSQL  primaire  si  vous  pensez  que  cela  peut etre utile aux
  autres. Le  paquetage  de  Test  de  Regression  permet  d'asseoir  la
  confiance  des  utilisateurs  en PostgreSQL et facilite le deploiement
  rapide de PostgreSQL sur des systemes en  production  sans  inquietude
  majeure.

  Le  paquetage  "Test  de  Regression"  peut  etre  considere comme une
  specification technique "tres solide" reconnue  mutuellement  par  les
  developpeurs  et  par  les  utilisateurs  finaux.  Les developpeurs de
  PostgreSQL utilisent de facon intensive ce paquetage durant la periode
  de  developpement  et  egalement  avant  de  mettre  le  logiciel a la
  disposition des utilisateurs pour en assurer la parfaite qualite.

  66..   OOuuttiill  GGUUII  ffrroonnttaall  ppoouurr   PPoossttggrreeSSQQLL   ((IInntteerrffaaccee   UUttiilliissaatteeuurr
  GGrraapphhiiqquuee))

  PostgreSQL  est  dote  d'une  librairie  d'interface  TCL/TK  dans  la
  distribution  appelee  'pgtcl'.  TCL/TK  est un outil de developpement
  rapide d'application et un langage de script extremement puissant.  On
  developpe  une fois pour toutes et on utilise sur NT, Win 95, Linux et
  tous les systemes Unix! TCL/TK est egalement largement  utilise  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'abreviation  de Integre) pour TCL/TK nomme SpecTCL. Verifiez la
  presence de ce paquetage  (format  rpm)  dans  la  distribution  linux
  Redhat ou dans l'un des sites sunscript indiquees ci-apres. TCL/TK est
  normalement inclus dans  tous  les  cdrom  linux.  On  peut  egalement
  l'obtenir a partir des sites -

  +o  <http://sunscript.sun.com/>

  +o  <http://sunscript.sun.com/TclTkCore/>

  +o  <ftp://ftp.sunlabs.com/pub/tcl/tcl8.0a2.tar.Z>

  +o  Manuels   de   reference:   de  nombreux  livres  sur  TCL/TK  sont
     disponibles sur le marche.

  +o  Visual TCL  <ftp://ftp.redhat.com/pub/contrib/i386/visualtcl*.rpm>

  77..  OOuuttiillss ddee ddeevveellooppppeemmeenntt iinntteeggrreess ppoouurr PPoossttggrreeSSQQLL ((IInntteerrffaaccee  UUttiill--
  iissaatteeuurr GGrraapphhiiqquuee))

  Essayez les outils de developpement suivants utilisable en conjonction
  avec  les  pilotes  ODBC/JDBC.   Ils  sont  similaires  a  Borland C++
  Builder, Borland JBuilder.

  Vibe est un IDE Java et C++ (Environnement de  Developpement  Integre)
  qui  a ete nomme IDE de l'annee par la revue "Unix Review". Ce produit
  a 800 US dollars est disponible pour linux au prix extremement bas  de
  79  US  dollars  pour  un  duree limitee. Essayez le! C'est le reve du
  developpeur.

  +o  Des  informations  complementaire  sur  Vibe  sont  disponibles   a
     <http://www.LinuxMall.com/products/00487.html>

     Vous  pouvez  aussi utiliser Borland C++ Builder, Delphi, JBuilder,
     PowerBuilder sur Windows95 pour se connecter a PostgreSQL  sur  une
     machine unix au travers de pilotes odbc/jdbc.

  Outils IDE gratuits -

  Regardez le CDROM de la distribution RedHat.

  +o  FreeBuilder  <ftp://ftp.redhat.com/pub/contrib/i386/free*.rpm>

  +o  SpecTCL  <ftp://ftp.redhat.com/pub/contrib/i386/spec*.rpm>

  +o  JccWarrior  <ftp://ftp.redhat.com/pub/contrib/i386/jcc*.rpm>

  +o  Applixware Tool  <http://www.redhat.com>

  +o  XWPE         X        Windows        Programming        Environment
     <http://www.rpi.edu/~payned/xwpe/>
     <ftp://ftp.redhat.com/pub/contrib/i386/xwpe*.rpm>

  +o  XWB            X            Windows            Work           Bench
     <ftp://ftp.redhat.com/pub/contrib/i386/xwb*.rpm>

  +o  NEdit  <ftp://ftp.redhat.com/pub/contrib/i386/nedit*.rpm>

  88..  KKaanncchheennjjuunnggaa -- OOuuttiill RRAADD JJaavvaa ppoouurr PPoossttggrreeSSQQLL

  Kanchenjunga est un outil de  developpement  rapide  (RAD)  Java  pour
  PostgreSQL.  Vous pouvez utiliser cet outil pour developper rapidement
  l'application java s'interfacant a PostgreSQL.

  +o  <http://www.man.ac.uk/~whaley/kj/kanch.html>

  99..  PPiillootteess dd''iinntteerrffaaccee ppoouurr PPoossttggrreeSSQQLL

  99..11..  OODDBBCC PPiillootteess ppoouurr PPoossttggrreeSSQQLL

  ODBC signifie 'Open DataBase Connectivity'. C'est une  norme  repandue
  pour  acceder  aux  informations  des  bases  de donnees de differents
  vendeurs. Le fonctionnement des applications ecrites en utilisant  les
  pilotes  ODBC  est  garanti  quelle  que  soient  les bases de donnees
  utilisees PostgreSQL, Oracle, Sybase, Informix etc..

  +o  <http://www.openlinksw.com>   Open   Link   Software    Corporation
     distribue  des  ODBC  pour PostgreSQL et d'autres bases de donnees.
     Open Link dispose aussi d'ODBC gratuits (quantite limitee) verifier
     aupres d'eux.

  +o  <http://stud1.tuwien.ac.at/~e9025461/>  C'est  le  site primaire de
     PostODBC  (PostgreSQL  ODBC)  .  Malheureusement  c'est   un   site
     particulierement lent.

  +o  <http://www.MageNet.com/postodbc/DOC>  Ce  miroir  est maintenu par
     Julia Anne Case qui est aussi un developpeur PostODBC majeur.

  Il existe aussi un projet interessant appele FreeODBC Pack  Package  .
  Il   n'y  a  pas  de  version  PostgreSQL,  peut-etre  pouvez  vous  y
  participer.

  +o  <http://www.ids.net/~bjepson/freeODBC/> c'est une version  gratuite
     d'ODBC.

  99..22..  PPiillootteess UUDDBBCC ppoouurr PPoossttggrreeSSQQLL

  UDBC  est  une  version  statique  de pilote de gestionnaire et de DLL
  d'ODBC independant, pour integrer le support de la  connectivite  base
  de donnees directement au niveau des applications.

  +o  <http://www.openlinksw.com>  Open  Link  Software Corporation vends
     UDBC pour PostgreSQL et  autres  SGBD.   Open  Link  dispose  aussi
     d'UDBC gratuits (quantite limitee) verifier aupres d'eux.

  99..33..  PPiillootteess JJDDBBCC ppoouurr PPoossttggrreeSSQQLL

  JDBC  signifie  'Java  DataBase  Connectivity'. Java est un langage de
  developpement independant de la  plate-forme  d'utilisation  developpe
  par  Sun  Microsystems. Les programmeurs Java sont encourages a ecrire
  leurs applications en utilisant JDBC  pour  faciliter  la  portabilite
  entre   differentes   plates-formes  telles  que  PostgreSQL,  Oracle,
  informix, etc. Si vous ecrivez des applications Java applications vous
  pouvez  obtenir  les  pilotes  JDBC pour PostgreSQL a partir des sites
  suivants :

  Le pilote JDBC est inclus dans la distribution PostgreSQL.

  +o  <http://www.demon.co.uk/finder/postgres/index.html>   Sun's    Java
     connectivity to PostgreSQL

  +o  <ftp://ftp.ai.mit.edu/people/rst/rst-jdbc.tar.gz>

  +o  <http://www.openlinksw.com>  Open  Link  Software Corporation vends
     JDBC pour PostgreSQL et  autres  SGBD.   Open  Link  dispose  aussi
     d'JDBC gratuits (quantite limitee) verifier aupres d'eux.

  99..44..  CCllaasssseess JJaavvaa ppoouurr PPoossttggrreeSSQQLL

  Ces classes pour PostgreSQL seront tres utiles au programmeur JAVA.

  +o  <ftp://www.blackdown.org/pub/Java/Java-Postgres95>

  +o  <http://www.blackdown.org>

  1100..   PPiilloottee  dd''iinntteerrffaaccee  ddee SSGGBBDD PPeerrll ((DDaattaabbaassee IInntteerrffaaccee  DDBBII)) ppoouurr
  PPoossttggrreeSSQQLL

  1100..11..  iinntteerrffaaccee PPeerrll 55 ppoouurr PPoossttggrreeSSQQLL

  Cette  interface est incluse dans la distribution de PostgreSQL. On la
  trouve dans le repertoire src/pgsql_perl5.

  +o  Email : E.Mergl@bawue.de

  +o  On la trouve aussi dans -

  +o  Page d'accueil Perl :

  1100..22..  QQuu''eesstt--ccee qquuee DDBBII ??????

  L'interface de SGBD Perl (Perl  Database  Interface  -  DBI)  est  une
  interface  logicielle  d'acces  a  un  SGBD  (Application  Programming
  Interface - API) pour le langage PERL. Les specifications de l'API DBI
  perl  definissent  un  ensemble  de  fonctions,  de  variables  et  de
  conventions d'acces a un SGBD coherent et independant du SGBD utilise.

  1100..33..  AAnnnnoonnccee dduu ppiilloottee DDBBII DDBBDD--PPgg--00..6633 DDBBII ppoouurr PPoossttggrreeSSQQLL

  Sur  le  site  CPAN on trouve DBD-Pg-0.63.tar.gz.  Depuis sortie de la
  derniere  version  publique,  les  modifications  suivantes  ont   ete
  effectuees :

  -  -  adaptation  a  PostgreSQL-6.2  :  o  $  sth->rows  de meme que $
  sth->execute et $ sth->do renvoient le nombre de lignes affectees meme
  pour  les  instructions non-Select.  o ajout du support d'autorisation
  par mot de passe, lire la page du manuel concernant pg_passwd.

  - - le parametre data_source de la methode de connexion  accepte  deux
  parametres  additionnels  qui  sont  senses representer les parametres
  hote et port : DBI->connect("dbi:Pg:dbname:host:port", "uid", "pwd")

  - - support de l'instruction AutoCommit. Lire la documentation  de  ce
  module pour evaluer son impact sur vos scripts !
  -  -  prise  en  compte  dans un meilleur style perl du type de donnee
  bool, Lire la documentation de ce module pour evaluer son  impact  sur
  vos scripts !

  Pour de plus amples informations voir:

  1100..44..  NNootteess ccoonncceerrnnaanntt cceettttee vveerrssiioonn eett ffiicchhiieerr LLIISSEEZZ--MMOOII

       #---------------------------------------------------------
       #
       # $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 precedentes.            *
       *                                                        *
       *            Lire la documentation du module             *
       *               pour l'attribut AutoCommit               *
       *               et le type de donnee bool.               *
       *                                                        *
       **********************************************************

  DESCRIPTION :

  ------------

  Ceci  est  la  version  0.63  de  DBD-Pg.   DBD-Pg  est  une interface
  PostgreSQL pour Perl 5 utilisant DBI.

  Pour des informations complementaires concernant DBI consulter:

  COPYRIGHT :

  -----------

  La distribution de ce  document  est  soumise  aux  conditions  de  la
  licence  publique  generale  GNU  ou la licence protegeant la creation
  Artistique (Artistic  License),  ainsi  que  c'est  specifie  dans  le
  fichier LISEZ-MOI perl.

  SI VOUS AVEZ DES PROBLEMES :

  ---------------------------

  Envoyez vos commentaires et vos rapports d'erreur a E.Mergl@bawue.de

  Pensez  a  inclure  les  messages affiches 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)

  PLATE-FORMES :

  -------------

  Cette  version  def  DBD-Pg  a  ete  developpee  pour  Linux  2.0 avec
  chargement dynamique des extensions perl. Merci de me faire savoir  si
  vous rencontrez des problemes 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 repertoire racine de votre installation Postgres. Taper les
  commandes suivantes:

  1.   perl Makefile.PL 2.   make 3.   make test 4.   make install

  ( de 1. a 3. comme utilisateur normal, pas comme root ! )

  TEST :

  ------

  Lancer 'make test'.  Noter que l'utilisateur lancant  ce  script  doit
  avoir  ete  cree  avec  des droits d'acces lui permettant de creer des
  bases de donnees "ET" des utilisateurs !. Ne pas lancer ce  script  en
  tant que root!.

  Si le test echoue avec le message 'login failed', verifier que l'acces
  a template1 de la base de donnees ainsi qu'a pgperltest  ne  sont  pas
  proteges dans pg_hba.conf.

  Si  vous utilisez la bibliotheque partagee libpq.so verifiez que votre
  chargeur dynamique trouve libpq.so. La commande  Linux  /sbin/ldconfig
  -v  devrait  vous  renseigner  sur l'endroit ou se trouve libpq.so. Si
  ldconfig ne trouve pas libpq.so, soit ajoutez  une  entree  appropriee
  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  resultant  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 incomplete de perl.
  Si vous avez des erreurs de compilation du style "XS_VERSION_BOOTCHECK
  undeclared",  executez  un  Si  ce  fichier  n'est pas present, il est
  indispensable de recompiler et de reinstaller perl.

  Utilisateurs SGI : si vous avez un defaut  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  defaut).   "David  R.
  Noble" drnoble@engsci.sandia.gov drnoble@engsci.sandia.gov

  ---------------------------------------------------------------------------

  E.Mergl@bawue.de                     5 Octobre 1997

  ---------------------------------------------------------------------------

  1100..55..  FFAAQQ ppoouurr DDBBII

  On  trouvera  ci-dessous  les  Questions Frequemment Posees (FAQ) pour
  DBI. La page Web d'accueil se trouve a

  <http://www.hermetica.com/technologia/perl/DBI>

                           DBI Foire Aux Questions v.0.35
                         Derniere mise a jour : 20 Juin, 1997

  * NOM
  * RESUME
  * VERSION
  * DESCRIPTION
  * Information & Sources d'Informations

     * 1.1 Qu'est-ce que DBI, DBperl, Oraperl and *perl?
     * 1.2. Ou puis-je les trouver?
     * 1.3. Ou puis-je trouver plus d'informations?

  * Problemes de compilation

     * 2.1. Problemes de compilation ou "echec aux tests!"

  * Questions de Plates-formes et de Pilotes

     * 3.1 Quelle est la difference entre ODBC et DBI?
     * 3.2 DBI est-il supporte sur les plates-formes Windows 95 / NT ?
     * 3.3 Puis-je acceder a des bases de donnees 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 a sa place?
     * 3.6 Quand mSQL-2 sera t'il supporte?
     * 3.7 Quel systeme de gestion de base de donnees me recommandez-vous?
     * 3.8 Est-ce que X est supporte dans DBI?

  * Questions de programmation

     * 4.1 Est-ce que DBI est d'une quelconque utilite 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 a partir de la ligne de commande, ca
           marche, mais, quand je le lance a partir de C, ca echoue!" Pourquoi?
     * 5.1 Puis-je faire de l'execution en parallele avec DBI?
     * 5.2 Comment manipuler des donnees BLOB avec DBI?
     * 5.3 Comment puis-je invoquer des procedures enregistrees avec DBI?
     * 5.4 Comment puis-je recuperer les valeurs de retour des procedures enregistrees avec DBI?
     * 5.5 Comment puis-je creer ou detruire une base de donnees 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 methodes func?

  * Support et formation

     * Assistance Commerciale
     * Formation

  * Autres References
  * AUTEUR
  * COPYRIGHT

  ----------------------------------------------------------------------------

  NOM

  DBI::FAQ -- Foire Aux Questions pour l'interface de SGBD Perl5

  ----------------------------------------------------------------------------

  RESUME

      perldoc DBI::FAQ

  ----------------------------------------------------------------------------
  VERSION

  La version actuelle de ce document , du 20 Juin, 1997, porte le numero 0.35.

  ----------------------------------------------------------------------------

  DESCRIPTION

  Ce document contient les reponses aux questions les plus frequemment posees
   a la fois sur les Mailing Lists DBI et personnellement aux membres de l'equipe
  de developpement 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'acces aux bases de donnees (Application
        Programming Interface  -API) pour le langage Perl. Les specifications DBI
        API definissent un ensemble de fonctions, de variables et de conventions
        coherents d'interfacage a une base de donnees independant de la base de
        donnees utilisee.''

  En langage simple, l'interface DBI permet aux utilisateurs d'acceder de maniere transparente
  a de multiples base de donnees. Ainsi, Si vous vous connectez a une
  base de donnees Oracle, Informix, mSQL, Sybase ou n'importe quelle autre, vous n'avez
  pas besoin de connaitre les mecanismes sous-jacents de la couche 3GL. L'API
  definie par DBI fonctionnera sur tous ces types de bases de donnees.

  On obtient un benefice du meme ordre en ayant la possibilite de se connecter a deux bases de
  donnees de differents fournisseurs a l'aide du meme script perl, i.e., je veux lire des
  donnees d'une base de donnees Oracle et les inserer dans une Informix a partir du meme
  programme. La couche logicielle DBI permet de le realiser simplement et efficacement.

  Voici un diagramme decrivant ce principe :

                              [ Architecture DBI  ]

  DBperl est le nom ancien des specifications de l'interface. Il est utilise maintenant
  pour designer les modules perl4 d'interfacage des bases de donnees tels que oraperl,
  isqlperl, ingperl et autres. Ces interfaces n'ont pas d'API standard et ne sont
  generalement pas supportes.

  Voici une liste des modules DBperl, de leur equivalent DBI correspondants et du
  support d'information. Notez que les auteurs cites ici ne maintiennent generalement
  pas le module DBI de la base de donnees. Les adresses E-mail n'ont pas ete verifiees
  et ne doivent etre utilisees que pour les questions concernant les modules perl4 listes
  ci-dessous. Les questions sur les pilotes DBI doivent etre directement
  adressees aux listes de diffusion des utilisateurs DBI.

    Nom du module 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 possedent des couches logicielles d'emulation. Ainsi
  DBD::Oracle est livre avec une couche d'emulation Oraperl, ce qui permet d'executer
  d'anciens scripts oraperl sans modification. La couche logicielle d'emulation traduit
  les appels oraperl API en appels DBI et les execute.

  Voici une table des  couches d'emulation :

      Module        Couche d'emulation     Etat
      ------          ---------------     ------
      DBD::Oracle     Oraperl             Complete
      DBD::Informix   Isqlperl            En cours de  developpement
      DBD::Sybase     Sybperl             Fonctionnelle? ( Necessite une
                                          verification)
      DBD::mSQL       Msqlperl            En version experimentale avec
                                          DBD::mSQL-0.61

  L'emulation Msqlperl est un cas particulier. Msqlperl est un pilote perl5 pour les
  bases de donnees mSQL , mais il ne se conforme pas aux specifications DBI. On
  desapprouve son utilisation en faveur de  DBD::mSQL. On peut tele-charger Msqlperl a
  partir du site CPAN via :

      http://www.perl.com/cgi-bin/cpan_mod?module=Msqlperl

  ----------------------------------------------------------------------------

  1.2. Ou 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 recuperer les
  versions a jour des pilotes, en general absentes des sites miroirs. On peut acceder
  a CPAN grace au splendide programme "CPAN multiplexeur" de Tom Christiansen's situe
  a:

      http://www.perl.com/CPAN/

  Pour des informations plus specifiques 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. Ou puis-je trouver plus d'informations?

  Il existe quelques sources d'information sur  DBI.

  Specifications DBI

           http://www.hermetica.com/technologia/perl/DBI/doc/dbispec

       On trouve deux specifications disponibles a cette adresse: la nouvelle
       specification Draft (edition provisoire) DBI qui est un document en
       evolution rapide a mesure que l'equipe de developpement s'approche d'une
       version stable de l'interface, et l'ancienne specification historique
       DBperl a partir de laquelle l'interface DBI actuelle a evolue.

       Il faut considerer ce dernier document comme ne presentant qu'un interet
       historique et ne pas l'utiliser en tant que manuel de programmation ou
       document de reference. Il demeure cependant une source d'informations
       tres utile.

  Documentation POD (Plain Old Documentation)
       Les PODs sont des morceaux de documentation generalement noyes a
       l'interieur des programmes perl qui documentent le code "sur place".
       Ce sont des ressources tres 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 etre lue avec les commandes suivantes.

       La Specification DBI
            Les PODs pour la specification DBI peut etre lue avec la commande :

                perldoc DBI

       Oraperl
            Les utilisateurs de la couche d'emulation fournie avec DBD::Oracle,
            peuvent s'informer sur la maniere de programmer en utilisant
            l'interface Oraperl en tapant:

                perldoc Oraperl

            Ce qui permettra d'obtenir une copie a jour de la page de manuel
            originale ecrite par Kevin Stock pour perl4. L'API oraperl y est
            entierement listee et decrite.

       DBD::mSQL
            Les utilisateurs du module DBD::mSQL peuvent lire des informations
            sur quelques fonctions privees 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 systeme
            en tapant :

                perldoc DBI::FAQ

            Ceci peut etre plus pratique pour ceux qui ne sont pas connectes a
            l'Internet ou le sont d'une maniere peu pratique.

       Les POD en general
            On peut lire des informations sur la maniere d'ecrire des PODs,
            ainsi que sur la philosophie des PODs en general en tapant :

                perldoc perlpod

            Les utilisateurs ayant le module Tk installe seront peut-etre
            interesses d'apprendre qu'il existe un lecteur de POD base sur Tk
            nomme tkpod. Il formate les POD de maniere pratique et lisible.

  Discussions, Cancans et Observations

           http://www.hermetica.com/technologia/perl/DBI/tidbits

       Il y a , de temps en temps, une serie de discussions de la part de
       certaines personnes, dans les listes de diffusion sur DBI,
       qui, pour essayer d'eclaircir un simple point, finissent par
       transformer en brouillon des documents tout a fait complets. Ces
       documents sont souvent de qualite variable, mais donnent un
       apercu du fonctionnement des interfaces.

  ``DBI -- L'interface de SGBD en perl5''
       C'est un article ecrit par Alligator Descartes et Tim Bunce sur la structure
       de DBI. Il a ete publie dans le numero 5 de ``The Perl Journal''.
       Il est extremement 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, publie dans l'edition de novembre 1996 du ``Dr. Dobbs
       Journal'' traitait de DBperl. L'auteur de cet article n'a apparemment
       pas contacte un seul membre de l'equipe de developpement DBI pour
       verifier l'information contenue dans son article. Plusieurs critiques
       de cet article dans les listes de diffusion des utilisateurs
       de dbi ont ete 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 fraicheur de l'information.

       Cependant, cette reference est donnee par soucis d'exhaustivite.

  ``The Perl5 Database Interface''
       Cette reference est celle d'un livre a ecrire par Alligator Descartes
       (pour lui, c'est moi) publie par O'Reilly et Associes a paraitre
       cet hiver.

       La table des matieres de ce livre devrait contenir :

            * Introduction
                 + Les Bases de Donnees
                 + CGI / WWW
                 + perl
            * Concepts de Base des Bases de donnees
                 + Types de Bases de Donnees
                      o Flat File
                      o AnyDBM
                      o RDBMS
                 + Utiliser Quelle Base de Donnees, pour Quoi faire...
            * SQL
                 + Pourquoi SQL?
                 + Structuration de l'Information dans les Bases de Donnees
                 + Extraction des Donnees d'une Base de Donnees
                 + Manipulation des Donnees et des Structures de Donnees
            * Architecture DBI
            * Programmation avec DBI
                 + Initialisation DBI
                 + Identifiants
                      o Identifiants de pilotes
                      o Identifiants de bases de donnees
                      o Identifiants d'instructions
                 + Connexion and Deconnexion
                 + Gestion des Erreurs
                 + Emission de Requetes Simples
                 + Execution d'Instructions Atomiques
                 + Instructions MetaDonnees
                 + Instruction plus dans le style perl
                 + Liaison
                 + Gestion des Transactions
                 + Methodes utilitaires
                 + Gestion des Attributs et des Variables Dynamiques
            * DBI et ODBC
            * Les Pilotes de Bases de Donnees
                 + DBD::Oracle et oraperl
                 + DBD::Informix et isqlperl
                 + DBD::mSQL et Msqlperl
            * Etude de Cas
                 + DBI et le WWW
                 + Migration des Donnees et Stockage
                 + Logiciel d'administration
            * Appendice: API Reference / Specification
            * Appendice: Ressources

  Fichiers LISEZMOI
       Les fichiers LISEZMOI fournis avec chaque pilote contiennent de temps
       en temps quelques informations utiles (non, vraiment! ) pouvant etre
       pertinentes pour l'utilisateur.
       S'il vous plait, lisez-les. Cela rendra nos pauvres existences plus
       supportables. On peut toutes les trouver depuis la page WWW DBI
       principale a :

           http://www.hermetica.com/technologia/perl/DBI

  Listes de diffusion
       Il y a trois listes de diffusion pour DBI gerees par Ted Lemon.
       On peut s'inscrire a toutes et resilier cette inscription a
       travers le World Wide Web a l'URL :

           http://www.fugue.com/dbi

       Les listes ou les utilisateurs peuvent participer sont:

       dbi-announce
            Cette liste de diffusion est reservee uniquement aux annonces.
            Tres peu de trafic. Les annonces sont generalement postees
            sur la page WWW DBI principale.

            Si vous n'arrivez pas a utiliser le formulaire sur la page WWW
            indiquee ci-dessus, inscrivez-vous a cette liste de la maniere
            suivante :

                Email: 'dbi-announce-request@fugue.com' avec le mot 'subscribe'
            dans le corps du message.

       dbi-dev
            Cette liste de diffusion est a l'usage des developpeurs pour discuter
            des idees et des concepts de l'interface DBI, API et des mecanismes
            des pilotes. Seulement utiles pour les developpeurs et les personnes
            interessees. Trafic faible.

            Si vous n'arrivez pas a utiliser le formulaire sur la page WWW
            indiquee ci-dessus, inscrivez-vous a cette liste de la maniere
            suivante :

                Email: 'dbi-dev-request@fugue.com' avec 'subscribe' dans
            le corps du message.

       dbi-users
            Cette liste de diffusion est un lieu de discussion generale utilisee
            pour les rapports d'erreurs, la discussion sur differents problemes
            et des demandes de renseignement d'interet general. Trafic moyen.

            Si vous n'arrivez pas a utiliser le formulaire sur la page WWW
            indiquee ci-dessus, inscrivez-vous a cette liste de la maniere
            suivante :

                Email: 'dbi-users-request@fugue.com' avec 'subscribe' dans
            le corps du message.
  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 ete mis en place
           pour permettre une recherche par les utilisateurs.

       Archives des Listes de Diffusion Europeennes

                http://www.rosat.mpe-garching.mpg.de/mailing-lists/PerlDB-Interest

            Identique a l'archive US ci-dessus.

  ----------------------------------------------------------------------------

  Problemes de compilation

  ----------------------------------------------------------------------------

  2.1. Problemes de compilation ou "Il echoue aux tests!"

  En premier lieu, consulter la documentation en ligne concernant ce module, que ce
  soit DBI lui-meme ou un module DBD, et verifier que ce n'est pas un probleme de
  compilation connu pour votre architecture. On peut trouver ces documents a :

      http://www.hermetica.com/technologia/perl/DBI

  Si c'est un probleme connu, vous devrez probablement attendre qu'il ait ete corrige.
  Si vraiment vous avez besoin d'une solution, essayez l'une des solutions suivantes :

  Essayez de le corriger vous meme
       Cette technique n'est generalement par recommandee aux craintifs. Si vous pensez
       que vous y etes arrive, alors, envoyer un fichier rustine (context diff ) a
       l'auteur en expliquant les points suivants :

          o Quel etait le probleme, et, si possible, des jeux d'essai.

          o Ce que vous avez du faire pour le corriger. Assurez vous que vous
            n'oubliez rien.

          o Donnez des informations concernant la Plate-forme utilisee, les versions :
            de la Base de Donnees, de Perl, du module et de DBI.

  Envoyez un Email a l'auteur SANS RALER!
       S'il vous plait, postez votre email a l'adresse indiquee dans les pages
       WWW du pilote avec lequel vous avez rencontre des problemes. Ne pas poster
       directement a une adresse que vous connaissez a moins qu'elle ne
       corresponde a l'une de celles qui sont indiquees.

       Nous avons un vrai travail a faire, et nous devons consulter les listes de
       diffusion traitant des problemes rencontres. De plus nous ne pouvons pas
       forcement avoir acces a <inserez ici le nom de votre plate-forme favorite,
       celle qui vous cause des lesions cerebrales> et de ce fait vous apporter
       une quelconque assistance!
       Desole de vous paraitre dur, mais c'est comme cela!

       Cependant, vous pouvez tomber sur l'un de ces genies creatifs, qui, a 3
       heures du matin resoudra votre probleme et vous fournira une rustine en 5
       minutes. L'ambiance dans le cercle DBI est que nous apprecions de
       connaitre les problemes des utilisateurs puisque nous travaillons dans
       le meme environnement.

       Si vous envisagez d'envoyer un Email a un auteur, essayez de fournir le
       plus d'informations possible, i.e. :
          o TOUS les renseignements provenant du fichier LISEZMOI du module
            posant probleme.
            Je dis bien TOUS. Nous n'ajoutons pas de lignes dans la documentation
            pour le plaisir, ou pour que les fichiers LISEZMOI se conforment
            a une quelconque norme de taille.

          o Si vous disposez d'un vidage memoire, essayer de generer une trace du
            contenu de la pile (stack) a partir du vidage memoire (core dump) en
            utilisant le module Devel::CoreStack. L'envoyer egalement. On peut
            trouver le module Devel::CoreStack sur CPAN a :

                http://www.perl.com/cgi-bin/cpan_mod?module=Devel::CoreStack

          o Les numeros de version du Module, de perl, des jeux d'essai, du
            systeme d'exploitation ainsi que tout autre information pertinente.

       Souvenez-vous que, plus vous nous enverrez d'informations plus vite
       nous pourrons resoudre le probleme. 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 general une idee astucieuse de rapporter les problemes
       rencontres dans les listes de diffusion. Les auteurs lisent tous
       ces listes d'une part et d'autre part vous ne perdez rien a le faire,
       donc, faites-le.

  ----------------------------------------------------------------------------

  Questions de Plates-formes et de Pilotes

  ----------------------------------------------------------------------------

  3.1 Quelle est la difference entre ODBC et DBI?

  Ca, c'est une bonne question! Reponse a rediger de maniere detaillee!

  ----------------------------------------------------------------------------

  3.2 DBI est-il supporte sur les plates-formes Windows 95 / NT ?

  Finalement, oui! Jeff Urlwin s'est employe avec constance a porter DBI et DBD::Oracle
  sur ces plates-formes, et, depuis la disponibilite d'un perl plus stable et d'un
  portage de MakeMaker, le projet a progresse a pas de geant.

  Les portages de DBI et de DBD::Oracle pour Win32 ports font maintenant partie
  integrante de DBI, donc, la recuperation d'une version de DBI superieure a 0.81 doit
  donner satisfaction. Pour ce qui est des rustines necessaires pour DBD::Oracle,
  veuillez lire la page d'information de portage pour Win32 a :

      http://www.hermetica.com/technologia/perl/DBI/win32

  ----------------------------------------------------------------------------

  3.3 Puis-je acceder aux bases de donnees Microsoft Access ou SQL-Server avec DBI?

      Contribution de Tim Bunce et Jeff Urlwin

  Il existe une couche logicielle d'emulation experimentale 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 a :

      http://www.roth.net

  Etant donne son etat, les rapports de problemes, sans correction, ont de bonnes
  chances d'etre ignores. Vous aurez egalement besoin du patch kit Win32 DBI tel qu'il
  est fourni par Jeff Urlwin. Pour trouver l'endroit ou il est disponible, lire la
  reponse a la question precedente.

  Jeff Urlwin fournit actuellement un gros travail sur la couche logicielle ODBC.
  Pour en revenir a la question initiale, theoriquement, oui, on peut acceder aux bases
  de donnees Microsoft Access ou SQL-Server avec DBI via ODBC!

  ----------------------------------------------------------------------------

  3.4 Existe-t-il un DBD pour <inserez le nom de votre SGBD favori ici>?

  Est-il cite dans la liste des pilotes DBI ?

      http://www.hermetica.com/technologia/perl/DBI/DBD

  Sinon, non. L'absence complete d'un pilote pour un SGBD donne dans cette page
  signifie que personne n'a manifeste l'intention d'y travailler.

  Comme corollaire a 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 reellement un pilote DBI, et qu'il puisse ne pas respecter les specifications.
  Par consequent, les questions pour des problemes concernant ce code ne doivent
  pas etre posees dans les listes de diffusion DBI.

  ----------------------------------------------------------------------------

  3.5 Qu'est-ce que DBM? Et pourquoi dois-je utiliser DBI a sa place?

  Extrait de ``DBI - L'Interface de Base de Donnees pour Perl 5'' :

      ``A l'origine UNIX etait bienheureux avec sa "Base de Donnees" rustique reposant
  sur des fichiers, nommee systeme dbm. Avec dbm vous enregistrez les donnees dans des
  fichiers et les retrouvez rapidement. Cependant, il souffre de serieux
  inconvenients.

          Verrouillage des fichiers

          Les systemes dbm ne permettent par un verrouillage particulierement
          robuste des fichiers, de meme qu'il n'y a pas de possibilite de
          corriger les problemes survenants lors d'ecritures [ dans la base
          de donnees ] simultanees.

          Structures de Donnees Arbitraires

          Les systemes dbm permettent seulement une simple structure de donnees
          fixe: paires cle-valeur. Cette valeur peut etre un objet complexe,
          tel qu'une structure [ C ], mais la cle doit etre unique. Ce fut une
          grande limitation dans l'utilite des systemes dbm.

      Cependant, les systemes dbm continuent a offrir des fonctions utiles pour les
      utilisateurs ayant des ensembles de donnees simples et des ressources limitees,
      puisqu'ils sont rapides, robustes et extremement bien testes. Les modules Perl
      pour acceder aux systemes dbm font maintenant partie integrante de la
      distribution Perl via le module AnyDBM_File.''

  Pour resumer, DBM est une solution parfaitement satisfaisante pour les bases de
  donnees essentiellement en lecture seule, ou pour des ensembles de donnees simples
  et reduits. Toutefois, pour des ensembles de donnees plus importants, sans
  mentionner un verrouillage des transactions robuste, on recommandera aux utilisateurs
  de preferer DBI.

  ----------------------------------------------------------------------------

  3.6 Quand mSQL-2 sera t'il supporte?

  De meme que pour DBD::mSQL-0.61, il y a eu un support pour mSQL-2. Cependant, il
  n'y a encore aucun reel support pour les nouvelles methodes func, concernant les
  index, ajoutees a la bibliotheque de base mSQL. Celles-ci seront prochainement
  disponibles et seront accessibles a DBD::mSQL au travers de methodes func privees.
  Vous pouvez obtenir plus d'informations concernant ces methodes func privees dans
  le POD DBD::mSQL en tapant :

      perldoc DBD::mSQL

  a condition d'avoir une installation correcte de DBD::mSQL.

  ----------------------------------------------------------------------------

  3.7 Quel systeme de gestion de base de donnees me recommandez vous?

  C'est un sujet particulierement epineux pour lequel une reponse objective est
  delicate dans la mesure ou, chaque ensemble de donnees, chaque usage et chaque
  configuration du systeme est different d'un utilisateur a l'autre.

  Du point de vue de l'auteur, si l'ensemble de donnees 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 donnees, alors mSQL est une solution parfaitement acceptable. Ce SGBD
  est extremement bon marche, est merveilleusement robuste et beneficie d'un excellent
  support. Des informations complementaires sont disponibles sur le site WWW Hughes
  Technology a :

      http://www.hughes.com.au

  Si l'ensemble de donnees entraine 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 francais) Oracle7. Le site WWW
  Oracle est une excellente source d'information complementaire.

      http://www.oracle.com

  Informix est un autre RDBMS de haut niveau qu'il faut envisager. Il existe plusieurs
  differences entre Oracle et Informix qui sont trop complexes pour etre detaillees
  dans ce document. On trouvera l'information sur Informix sur leur site WWW a :

      http://www.informix.com

  En cas d'utilisation dans des applications en frontal WWW, mSQL peut etre un
  meilleur choix du fait de ses temps de connexion courts entre le script CGI et le
  SGBD que Oracle RDBMS qui, a chaque connexion, reclame plus de ressources. mSQL est
  moins gourmand en ressources et plus rapide.

  Ce point de vue n'est pas forcement partage par tout le monde et n'est pas sponsorise
  ou dicte par une quelconque societe. Il est donne tel quel.

  ----------------------------------------------------------------------------

  3.8 Est-ce que <inserez une fonctionnalite ici> est supporte par DBI?

  Si l'on suppose que la fonctionnalite en question n'est pas, en standard, specifique
  d'un SGBD, alors la reponse sera non.

  DBI represente un API qui doit fonctionner avec la plupart des SGBD, et n'a pas de
  fonctionnalite specifique a un SGDB particulier.

  Cependant, les auteurs d'un pilote peuvent, s'ils le desirent, ajouter une
  fonctionnalite specifique a un SGBD a travers les methodes func definies dans l'API
  DBI. Les developpeurs de Scripts doivent noter que l'utilisation de cette
  fonctionnalite au travers de ces methodes func a de bonnes chances d'en sacrifier la
  portabilite entre les differents SGBD.

  ----------------------------------------------------------------------------

  Questions de Programmation
  ----------------------------------------------------------------------------

  4.1 Est-ce que DBI est d'une quelconque utilite pour la programmation CGI?

  En un mot, oui! DBI est extremement utile pour la programmation CGI! En fait, je
  serais tente de repondre que la programmation CGI est une des deux principales
  utilisation de DBI.

  DBI confere aux programmeurs CGI la possibilite d'offrir des base de donnees WWW a
  leurs utilisateurs, ce qui donne a ces utilisateurs la possibilite d'utiliser de
  grandes quantites de donnees bien organisees. DBI donne aussi la possibilite , si un
  site recoit un trafic trop important pour les performances du serveur, d'ameliorer
  ce serveur de base de donnees de facon 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
  requetes clients.

  En utilisant le module mod_perl Apache de Doug MacEachern, l'interpreteur perl est
  inclus dans le processus fils httpd. Les modules CGI, DBI, et vos autres modules
  favoris peuvent etre charges au lancement de chaque processus fils. Ces modules ne
  seront pas recharges a moins d'etre modifies sur disque.

  Pour de plus amples informations sur Apache, consultez le site WWW du Projet Apache
  a :

      http://www.apache.org

  Le module mod_perl peut etre recupere 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 John D. Groenveld

  En utilisant le module Apache::DBI de Edmund Mergl, les connexions a la base de
  donnees sont enregistrees dans une table avec chacun des processus httpd fils. Si
  votre application utilise une base de donnees simple utilisateur, cette connexion
  peut etre lancee avec chaque processus fils. Actuellement, les connexions a la base
  de donnees ne peuvent pas etre partagees entre processus httpd fils.

  Apache::DBI peut etre tele-charge 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, ca marche, mais, quand
  je le lance sous httpd, ca echoue!" Pourquoi?

  Fondamentalement, il y a une bonne chance que cela provienne du fait que
  l'utilisateur a partir duquel vous avez lance la ligne de commande a
  un ensemble de variables d'environnement correctement configure, ce sont, dans la
  cas de DBD::Oracle, des variables telles que $ORACLE_HOME, $ORACLE_SID or TWO_TASK.

  Le processus httpd s'execute habituellement sous un utilisateur id ne correspondant
  pas a un utilisateur, ce qui implique qu'il n'y a pas d'environnement configure.
  Tous scripts essayant de s'executer dans ces circonstances echoueront.
  Pour resoudre ce probleme, initialisez l'environnement de votre base de donnees dans
  un bloc BEGIN ( ) en tete de votre script. Ceci devrait resoudre votre probleme.

  De meme, 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 complementaires. Il est peu
  probable que ce probleme concerne DBI.

  Le guide ``Idiot's Guide To Solving Perl / CGI Problems'' peut etre trouve a :

      http://www.perl.com/perl/faq/index.html

  ainsi que ``Perl CGI Programming FAQ''. Lisez ces DEUX documents tres soigneusement!

  ----------------------------------------------------------------------------

  5.1 Puis-je faire de l'execution en parallele avec DBI?

  A la date de ce document ( voir en tete ), non. perl ne permet pas l'execution en
  parallele. Cependant, l'execution en parallele doit faire partie de la distribution
  perl de base a compter de la version 5.005, ce qui sous-entend que le support de
  l'execution en parallele pour DBI devrait suivre rapidement.

  Pour quelques exemples de code OCI pour Oracle ayant des instructions SELECT avec
  execution en parallele, voir :

      http://www.hermetica.com/technologia/oracle/oci/orathreads.tar.gz

  ----------------------------------------------------------------------------

  5.2 Comment manipuler des donnees BLOB avec DBI?

  A ecrire.

  ----------------------------------------------------------------------------

  5.3 Comment puis-je invoquer des procedures enregistrees avec DBI?

  En supposant que vous avez cree une procedure enregistree a l'interieur de la base
  de donnees cible, eg, une base de donnees Oracle, vous pouvez utiliser $dbh->do pour
  executer immediatement cette procedure. Par exemple,

      $dbh->do( "BEGIN someProcedure END" );

  ----------------------------------------------------------------------------

  5.4 Comment puis-je recuperer les valeurs de retour de procedures enregistrees 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 creer ou supprimer une base de donnees avec DBI?

  La creation et la suppression de bases de donnees sont des concepts qui sont
  beaucoup trop abstraits pour etre supportes par DBI. Par exemple, Oracle ne supporte
  pas le concept de detruire une base de donnees du tout! Ainsi, dans Oracle, le
  serveur de base de donnees est essentiellement la base de donnees elle-meme alors
  que dans mSQL, le processus serveur s'execute tranquillement sans aucune base de
  donnees creee. C'est un probleme trop heterogene pour s'y attaquer.

  Quelques pilotes, cependant, supportent la creation et la suppression de bases de
  donnees a travers des methodes func privees. Il vous faut regarder dans la
  documentation des pilotes que vous utilisez pour verifier s'ils supportent de tels
  mecanismes.

  ----------------------------------------------------------------------------

  5.6 Comment puis-je valider ou annuler une instruction avec DBI?

  A ecrire.

  ----------------------------------------------------------------------------

  5.7 Comment les valeurs NULL sont-elles prises en compte par DBI?

  Les valeurs NULL dans DBI sont traitees comme la valeur undef. Des NULLs peuvent
  etre inseres dans les bases de donnees en tant que NULL, par exemple :

      $rv =
          $dbh->do( "INSERT INTO table VALUES( NULL )" );

  mais lors d'une interrogation, les NULLs devront etre testes comme des undef. C'est
  une norme pour tous les pilotes.

  ----------------------------------------------------------------------------

  5.8 Qu'est-ce que c'est que ces histoires de methodes func?

  Une methode func est definie a l'interieur de DBI comme etant un point d'entree pour
  une fonctionnalite d'une base de donnees specifique, eg, la possibilite de creer ou
  supprimer des bases de donnees. L'invocation de ces methodes specifiques aux pilotes
  est simple. Par exemple, pour invoquer une methode createDatabase qui n'a qu'un seul
  argument, on ecrira :

      $rv =
          $dbh->func( 'argument', 'createDatabase' );

  Les developpeurs de logiciels doivent cependant noter que ces methodes func ne sont
  pas portables entre SGBD.

  ----------------------------------------------------------------------------

  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 qualite de ces services (le traducteur non plus!). Les liens ci-dessous ne sont
  indiques qu'a titre de reference.

  ----------------------------------------------------------------------------

  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 effectuee par la compagnie
  pour laquelle Tim Bunce, auteur de DBI, travaille. Pour des informations
  complementaires sur leurs services, veuillez voir :

           http://www.perl.co.uk/tpc
  ----------------------------------------------------------------------------

  Formation

  Aucun programme de formation n'est connu a ce jour.

  ----------------------------------------------------------------------------

  Autres References

  Dans cette section, on trouvera des liens WWW divers pouvant presenter un interet
  pour les utilisateurs de DBI. Ils n'ont pas ete verifies et peuvent mener a des
  sites inconnus ou a 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>

  ----------------------------------------------------------------------------
  Reproduit avec l'autorisation de Alligator Descartes Hermetica
  ----------------------------------------------------------------------------

  1111..  PPGGAACCCCEESSSS -- UUnn GGUUII ppoouurr llaa ggeessttiioonn ddee PPoossttggrreeSSQQLL

  Il est deja inclus dans la distribution de PostgreSQL.  Pour une copie
  plus recente, vous pouvez acceder au site web :

  +o  <http://www.flex.ro/pgaccess>

  +o  Si   vous   avez   des   commentaires,  des  suggestions  pour  des
     ameliorations, n'hesitez pas a envoyer un courrier electronique a :
     teo@flex.ro

  Voici ce que dit la page d'accueil de pgaccess :

  PgAccess - une interface Tcl/Tk pour PostgreSQL

  La derniere version de PgAccess est 0.63 , du 4 Decembre 1997

  Je pense qu'il y a eu quelques problemes au chargement de la bibliotheque libpgtcl.
  Je vous invite a lire la section speciale concernant libpgtcl

  Que fait PgAccess maintenant!
  Voici quelques images des fenetres de PgAccess : Fenetre principale, createur
  de tables, vue de table (interrogation), createur visuel d'interrogation .

  Tables
  - Ouverture de tables pour la visualisation, 200 enregistrements maximum
    ( modifiable dans le menu des preferences )
  - re-dimensionnement d'une colonne en tirant la ligne verticale de la grille
    ( plus pratique a realiser a l'interieur meme de la table que dans l'en-tete)
  - texte encadre dans les cellules - disposition enregistree pour chacune des tables)
  - importation/exportation vers des fichiers externes (SDF,CSV)
  - possibilite de filtres (filtre de saisie, tel que (prix>3.14)
  - possibilites de tri (saisie manuelle de(s) champ(s) a trier)
  - edition en ligne
  - assistant generateur de table ameliore
  - edition de champ amelioree
  Requetes
  - definition, edition et enregistrement de "requetes definies par l'utilisateur"
  - enregistrement de requetes en tant que vues
  - execution des requetes
  - visualisation des resultats de requetes de type select
  - suppression et changement de nom de requete
  - NOUVEAU !!! Createur visuel de requetes avec possibilites de "glisser/deposer".
    Pour tous ceux d'entre vous qui ont l'extension pour Netscape Navigator de Tcl/Tk
    installee, vous pouvez le voir au travail en cliquant ici
  Sequences
  - definition de sequences, ainsi que leurs suppression et inspection
  Fonctions
  - definition, inspection et suppression de fonctions en langage SQL

  Sur la liste A FAIRE!
  - conception des tables (ajout de nouveaux champs, changement de nom, etc.)
  - definition de fonction
  - generateur de rapport
  - langage de script de base

  Informations complementaires concernant libgtcl

  Vous aurez egalement besoin de la bibliotheque d'interface de PostgreSQL a Tcl,
  disponible comme moduleTcl/Tk chargeable. Son nom est libpgtcl et le source est
  situe dans le repertoire PostgreSQL /src/interfaces/libpgtcl. Precisement, vous
  aurez besoin d'une bibliotheque libpgtcl qui soit "chargeable" a partir de Tcl/Tk.
  Ce qui est techniquement different d'un fichier objet chargeable PostgreSQL
  ordinaire, car libpgtcl est constituee d'un ensemble de fichiers objets. Sous Linux,
  on l'appelle libpgtcl.so. Vous pouvez tele-charger a partir d'ici une version deja
  compilee pour les systemes Linux i386. La seule chose a faire est de copier
  libpgtcl.so dans le repertoire bibliotheque systeme (/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 ete lie avec la bibliotheque libpgtcl!

  De toute maniere, l'application devrait fonctionner sans problemes

  1122..  OOuuttiill WWiinnddoowwss iinntteerraaccttiiff ddee ggeenneerraattiioonn ddee rreeqquueettee ppoouurr PPoossttggrreeSSQQLL

  ("Windows  Interactive Query Tool" WISQL ou MPSQL) Il est identique au
  serveur de requete  SQL  de  Microsoft  WISQL!  Il  dispose  d'un  GUI
  agreable  et  d'un  historique  des commandes. Vous pouvez utiliser le
  coupe/colle  ainsi  que  d'autres  fonctionnalites  sympathiques  pour
  accroitre votre productivite.

  +o  <http://www.troubador.com/~keidav/index.html>

  +o  Email : keidav@whidbey.com

  +o  <http://www.ucolick.org/~de/> dans le fichier tcl_syb/wisql.html

  +o  <http://www.troubador.com/~keidav/index.html>

  +o  Email : de@ucolick.org

  1133..  OOuuttiill iinntteerraaccttiiff ddee ggeenneerraattiioonn ddee rreeqquueettee ppoouurr PPoossttggrreeSSQQLL -- IISSQQLL

  ISQL  est  destine  aux  terminaux  fonctionnants  en  mode  ligne  de
  commande.   C'est  inclus  dans  la distribution et nomme PSQL. Il est
  tres similaire a  Sybase ISQL, et a Oracle SQLplus.  A  l'invite  unix
  tapez  la  commande  'psql'  qui en retour vous affichera le caractere
  d'attente de commande: psql> .

       Tapez /h pour obtenir de l'aide sur les commandes utilisables.

  C'est tres convivial et d'utilisation facile.  C'est aussi tres  utile
  pour  ecrire  des  scripts pour les interpreteurs de commandes Bourne,
  Korn et C-shells.

  1133..11..  MMPPMMGGRR -- UUnn oouuttiill ddee ggeessttiioonn ddee BBaassee ddee DDoonnnneeeess ppoouurr PPoossttggrreessSSQQLL

  MPMGR fournira un outil graphique de gestion de Base de  Donnees  pour
  PostgresSQL. Vous pouvez le trouver a

  +o  <http://www.troubador.com/~keidav/index.html>

  +o  Email: keidav@whidbey.com

  +o  <http://www.ucolick.org/~de/> dans le fichier tcl_syb/wisql.html

  +o  <http://www.troubador.com/~keidav/index.html>

  +o  Email: de@ucolick.org

  1144..  MMiissee eenn ppllaaccee ddee pplluussiieeuurrss mmaacchhiinneess PPoossttggrreeSSQQLL aavveecc uunn sseeuull mmoonnii--
  tteeuurr

  Vous  pouvez  empiler  plusieurs  cpu  et  les  connecter  a un unique
  moniteur en utilisant un commutateur pour choisir  la  connexion  avec
  une unite centrale particuliere. Ce qui economise de l'espace et evite
  l'utilisation de plusieurs  ecrans  (200  US  dollars),  claviers  (60
  dollars) et mulots (50 dollars) et evite aussi pas mal de pagaille.

  Veuillez consulter ces sites :

  +o  <http://www.networktechinc.com/servswt.html>   (120   dollars/PC  8
     ports) qui propose des commutateurs de serveurs  'Server  Switches'
     et des commutateurs uniquement video

  +o  Scene               Double               Inc,               England
     <http://www.scene.demon.co.uk/qswitch.htm>

  +o  Cybex corporation  <http://www.cybex.com>

  +o  Raritan Inc  <http://www.raritan.com>

  +o  RealStar Solutions Inc  <http://www.real-star.com/kvm.htm>

  +o  Belkin Inc  <http://www.belkin.com>

  +o  DataComm Warehouse Inc Appels 24 heures sur 24, 7 jours  sur  7  au
     1-800-328-2261   Ils   fournissent   toutes   sortes  de  materiels
     d'ordinateur  <http://www.warehouse.com>

  +o  Better             Box             Communications              Ltd.
     <http://www.betterbox.com/info.html>

  +o  Allez chez votre marchand de materiel le plus proche et demandez un
     commutateur de serveur "Server Switch" egalement connu sous le  nom
     "KVM Auto Commutateurs".

  Utilisez le moteur de recherche yahoo pour trouver d'autres compagnies
  en utilisant la cle de recherche 'Server Switches' ou "KVM  Switches".

  Pour  avoir  de  meilleures  performances,  on  recommande  instamment
  d'avoir une machine unix pour  chaque  processus  serveur  PostgreSQL.
  Aucun  autre  programme/traitement  ne doit tourner sur cette machine.
  Consultez la page Affaires de votre journal  local  pour  trouver  des
  vendeurs  de  machines  intel nues, avec un moniteur monochrome de 13"
  (moniteur particulierement economique). Les  vendeurs  locaux  vendent
  uniquement  du  materiel  SANS un quelconque Microsoft Windows/DOS (ce
  qui vous fait economiser environ $ 150).  Vous n'avez pas besoin  d'un
  moniteur  couleur  pour  un  serveur  de  base de donnees puisque vous
  pouvez en effectuer l'administration a distance a partir d'une station
  de  travail  PC  couleur. Procurez-vous le cdrom Linux a l'adresse ci-
  dessous -

  +o  Site Web Linux  System  Labs  :    <http://www.lsl.com/>   7  (U.S.
     dollars)

  +o  Site  Web  Cheap Bytes Inc :   <http://www.cheapbytes.com/> 7 (U.S.
     dollars)

     Assurez-vous que le materiel que vous achetez est supporte  par  le
     Linux  Redhat.  Verifiez  sur  le  site  ftp  de Redhat le materiel
     recommande tels que les coupleurs  SCSI,  les  cartes  video  avant
     d'acheter.   Pour seulement $ 600 vous obtiendrez une machine intel
     puissante  avec  un  Linux  Redhat  faisant   tourner   PostgreSQL.
     Utilisez  odbc/jdbc/perl/tcl  pour  vous  connecter  a PostgreSQL a
     partir  de  Windows95,  OS/2,  Unix  Motif  ou  butineur   Netscape
     (Netscape est en train de rapidement devenir le client standard).

  Pour  empiler  les unites centrales, achetez une etagere allant du sol
  au plafond  pour  $  15  et  fixez-la  au  mur  en  plusieurs  points.
  Chevillez-la  egalement au sol. La taille de l'etagere doit etre telle
  qu'elle corresponde exactement a celle  de  l'ordinateur.  Placez  les
  unites  Intel  le cote contre le mur de sorte que l'avant et l'arriere
  soient facilement accessibles (ports serie, ports reseau,  connections
  d'alimentation).  Suivez  les  regles  de  l'Ergonomie,  les  etageres
  doivent avoir assez de place  de  chaque  cote  et  il  doit  y  avoir
  suffisamment  de  place  entre  plusieurs etageres. Regroupez les fils
  proprement. Posez  des  bandes  metalliques  verticales  pour  que  le
  materiel  ne  tombe  pas  durant  les  tremblements  de terre. On peut
  installer environ 30 unites  centrales  Intel-Linux  sur  une  etagere
  allant  du  sol  au  plafond.  Ainsi,  dans  une  petite piece on peut
  installer environ 10 etageres avec 300 unites centrales controlees par
  seulement un seul moniteur et un seul clavier!!

  On trouvera ci-dessous un extrait du catalogue de networktechnic Inc

  Commandez maintenant, appelez le  800-742-8324 (appel gratuit a partir des USA)

  Pour recevoir notre catalogue, veuillez envoyer votre adresse par courrier electronique a :
  sales@networktechinc.com

  PILOTEZ PLUSIEURS PC's avec un seul clavier, ecran et mulot
  Ces commutateurs electroniques permettent de piloter jusqu'a 64 PC's avec un unique
  clavier, ecran et mulot. Son microprocesseur interne simule la presence constante du
  clavier, de l'ecran et du mulot pour chacun des PC's connectes.

  Fonctionnalites et Applications

  * Clavier, face avant ou commande a distance
  * utilisation de connecteurs de mulots 9 broches D Serie ou 6 broches miniDIN
  * utilisation de connecteurs de clavier 5 broches DIN ou 6 broches miniDIN
  * resolution video 1600x1200 sans degradation
  * Utilisation de cables standards
  * Boitier pour bureau ou pour montage en rack

  Specifications - Clavier

  * Tous les connecteurs dont femelles
  * 5 broches DIN ou 6 broches miniDIN
  * Permettent un Re-demarrage (boot) materiel ou logiciel de tous les PC's a chaque instant

  Controles - 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 entraine le fonctionnement dans
  les modes SCAN, BROADCAST ou COMMAND
  * Les LEDs en face avant indiquent le mode d'operation du clavier
  * L'appui sur CTRL+* entraine le fonctionnement en mode COMMAND
  * Les modes SCAN, BROADCAST ou COMMAND sont disponibles

  Mulot

  * 9 broches D serie
          o Le commutateur NTI emule le mulot Microsoft serie pour tous les PC's
          o 9 broches D male pour mulot
          o 9 broches D femelle pour PC's
  * 6 broches miniDIN
          o Le commutateur NTI emule le mulot IBM PS/2 pour tous les PC's
          o Tous les connecteurs sont femelles

  Par cable, a distance

  * Optionnel--doit etre acquis separement
  * Fonctionnement identique a celui "Boutons en face avant"

  Information technique

  * Demander le manuel technique MAN025

  Moniteur (ecran) - VGA

  * Bande passante 150 MHz
  * Resolution 1600X1200 sans degradation
  * Tous les connecteurs sont des connecteurs femelles

  Alimentation

  * 110 ou 220 VAC a 50 ou 60 Hz

  1155..  OOuuttiill SSyysstteemmee ddee ssuuiivvii ddee PPrroobblleemmee//PPrroojjeett ppoouurr PPoossttggrreeSSQQLL

  Se trouve a l'url :

  +o  <http://www.homeport.org/~shevett/pts/>

  1166..  CCoonnvveerrssiioonn ddee ffiicchhiieerrss ddbbaassee ddbbff eenn ffiicchhiieerrss PPoossttggrreeSSQQLL

  Le programme dbf2msql fonctionne parfaitement avec mSQL et PostgreSQL.
  Vous pouvez le trouver a

  +o  <ftp.nerosworld.com/pub/SQL/dbf2sql/>

  +o  <ftp://gopher.library.tudelft.nl/pub/misc/dbf2msql-0.4.tar.gz>

  +o  <ftp://ftp.postgresql.org/pub/incoming/dbf2pg-3.0.tar.gz>

  Ce programme a ete ecrit par Maarten Boekhold, Faculty  of  Electrical
  Engineering  TU  Delft, NL Computer Architecture and Digital Technique
  section M.Boekhold@et.tudelft.nl

  Vous pouvez egalement  utiliser  une  methode  python  pour  lire  des
  fichiers dbf et les charger dans une base de donnees postgres.

  +o  Voir  <http://www.python.org>

  1177..  LLee ssyysstteemmee ddee ddeevveellooppppeemmeenntt AAppppGGEENN

  PostgreSQL 4GL pour les applications de bases de donnees web.

  AppGEN peut etre tele-charge de

  <http://www.man.ac.uk/~whaley/ag/appgen.html>

  <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 quatrieme generation ainsi
  qu'un  generateur  d'application  pour   produire   des   applications
  destinees  au  World Wide Web (WWW). Ces applications sont typiquement
  utilisees a travers l'internet ou dans le cadre d'un  reseau  intranet
  d'entreprise.  Les  applications  AppGEN  sont implantees en scripts C
  respectants la norme Common Gateway Interface  (CGI)  utilise  par  la
  plupart des serveurs Web.

  Pour utiliser AppGEN il vous faudra disposer de :-

  PostgresSQL, systeme de gestion de base de donnees relationnel

  Un serveur web compatible CGI tel que HTTPD du NCSA

  D'un compilateur ANSI C tel que GCC

  AppGEN est constitue des executables Unix (Linux) suivants :-

  +o  defgen,  qui produit une application cadre, de base, a partir de la
     structure logique  des  donnees.  Ces  applications  sont  capables
     d'ajouter,  de  mettre  a  jour,  de supprimer et de rechercher les
     enregistrements  d'une  base  de   donnees   tout   en   conservant
     automatiquement l'integrite referentielle de cette base.

  +o  appgen,  le compilateur AppGEN qui compile le code source appgen en
     code source C CGI executable et en documents  formates  HTML  prets
     pour leur deploiement sur un serveur web.

  +o  dbf2sql,  un  utilitaire de conversion de fichiers .dbf compatibles
     dBase III en scripts SQL executables. Ce qui permet de  migrer  les
     donnees  stockees  dans la plupart des bases de donnees DOS/Windows
     vers un serveur SQL tel que PostgresSQL.

  +o  De plus, AppGEN  comprend  un  ensemble  de  documents  HTML  ,  de
     fichiers  GIF  et  d'applets Java qui sont utilises, a l'execution,
     par le systeme. Et, naturellement, comme pour tout bon logiciel, la
     totalite du code source est fournie.

  L'auteur,      Andrew     Whaley,     peut     etre     contacte     a
  andrew@arthur.smuht.nwest.nhs.uk tous les commentaires ou  suggestions
  concernant ce logiciel seront les bienvenus.

  1188..   OOuuttiill ddee CCoonncceeppttiioonn//IImmpplleemmeennttaattiioonn ppoouurr SSGGBBDD WWeebb ppoouurr PPoossttggrreeSSQQLL
  -- EEAARRPP

  <http://www.oswego.edu/Earp>

  <ftp://ftp.oswego.edu> dans le repertoire 'pub/unix/earp'.

  On trouvera ci-dessous un extrait de la page d'accueil de EARP:-

  Le  "Programme  de  Reponse  Facilement Ajustable" ("Easily Adjustable
  Response Program" - EARP) cree par David Dougherty

  1188..11..  EEAARRPP,, cc''eesstt qquuooii??

  EARP est un outil de Conception/Implementation pour  Base  De  Donnees
  Web,  realise  au-dessus  du  systeme  de  gestion  de base de donnees
  PostgresSQL. Ses fonctionnalites comprennent:

  +o  Un systeme de conception visuel.

  +o  Une interface d'envoi de courrier electronique. (pouvant prendre en
     charge le courrier entrant et sortant)

  +o  Un Mecanisme de Securite ameliore.

  +o  Un pilote cgi.

  1188..22..  IImmppllaannttaattiioonn

  L'implantation  principale  de  EARP  consiste  en  un binaire CGI qui
  s'execute sous le demon http pour fournir l'acces au serveur  de  base
  de  donnees.  Tous  les  outils  de  conception  sont integres dans le
  pilote, aucune conception ne se fait sur le web. Les outils  eux-memes
  requierent un navigateur graphique, la compatibilite des objets concus
  avec ces outils est independante de  l'implantation,  elle  ne  depend
  uniquement que des preferences de conception individuelles.

  1188..33..  CCee ddoonntt vvoouuss aavveezz bbeessooiinn ppoouurr ffaaiirree ffoonnccttiioonnnneerr EEAARRPP

  EARP  est  sense  fonctionner  sur une grande variete de plates-formes
  avec peu de modifications sinon pas du tout.  Les  plates-formes  pour
  lesquelles le fonctionnement est connu sont les suivantes:

  +o  Solaris 2.5

  +o  Linux 1.2.13+

  +o  GNU C++

  +o  Postgres95 (Version 1.01 / 1.02)

  +o  netsite server

  +o  NCSA httpd

  +o  GNU C++

  +o  Postgres95 (Version 1.01 / 1.02)

  +o  NCSA httpd

  +o  Apache httpd

  1188..44..  NNoouuvveelllleess FFllaasshh

  La version actuelle (1.3) de Earp a ete concue au-dessus de la version
  de libpq livree avec Postgres95  v1.01/1.02.   Si  vous  utilisez  une
  version plus recente de Postgres, vous devez vous attendre a ce que le
  programme   necessite   quelques   modifications   pour    fonctionner
  correctement.   Dans  la version de developpement (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 ecrire ces modules. La version  de  developpement
  est   attendue,   pour   le   public,   aux  alentours  du  milieu  du
  printemps(97).

  1188..55..  CCoommmmeenntt ffoonnccttiioonnnnee--tt--iill??

  Une  des  fonctionnalites  principales  de  EARP  est  d'utiliser  une
  approche orientee objet pour produire des pages html qui s'interfacent
  a la base de  donnees.  La  plupart  des  pages  sont  constituees  de
  plusieurs  objets.  Chaque  objet est produit par une sorte d'outil et
  recoit un nom, les objets sont alors  lies  ensembles  et  appeles  en
  sequence  par  l'outil  de gestion de pages. Les objets sont egalement
  reutilisables a l'interieur de plusieurs pages. Il existe  des  outils
  de  base  pour  HTML,  pour  les  Requetes,  pour  la  saisie dans des
  formulaires, le formatage variable  des  requetes  et  des  objets  en
  entree, ainsi que pour lier des objets pour en former de nouveaux.  On
  trouve egalement des outils plus avances tels que l'outil de  courrier
  electronique et l'outil de creation de requetes en parallele.

  La   gestion   perfectionnee   de  la  securite  est  une  des  autres
  fonctionnalites de EARP.  L'acces aux  differentes  zones  du  systeme
  EARP peut etre limite par une grande variete de moyens. Pour faciliter
  cette securite perfectionnee, EARP effectue  des  controles  a  chaque
  connexion   au  systeme,  et  determine  a  quels  "ids"  et  "groups"
  appartient l'agent qui se connecte. Les acces aux zones  sont  definis
  separement,  et la combinaison des deux permet de decider si l'acces a
  une certaine zone de Earp est autorise. De plus  ,  tout  ce  qui  est
  requis pour realiser les fonctionnalites de securite se trouve dans un
  serveur  http  qui  effectue  une  authentification  de  l'utilisateur
  minimale (ou meilleure).

  1188..66..  QQuueellqquueess eexxeemmpplleess eenn lliiggnnee

  Partie  integrante  de  l'aide  au  SGBD ICC Help Database, la Page du
  Catalogue  de  Recherche  est  un  document  EARP  qui  peut  executer
  plusieurs  requetes.   Les  boites  de  selection sont generees par le
  programme EARP a partir de listes dans la base de donnees.

  Comme autre exemple de ce que l'on peut faire avec EARP... vous pouvez
  maintenant voir la Liste des Objets de la Base de Donnees d'aide.

  La  creation de ces trois interfaces m'a pris moins de quinze minutes.

  1188..77..  OOuu ppuuiiss--jjee llee ttrroouuvveerr??

  EARP est disponible via un ftp anonyme a  <ftp://ftp.oswego.edu>  dans
  le  repertoire  'pub/unix/earp'.  La  version  actuelle  a  la date de
  redaction de ce texte est 1.3.1

  S'il vous plait, apres avoir recupere et mis en service EARP,  envoyez
  moi un mot pour en decrire le succes ou les echecs.

  1188..88..  DDooccuummeennttaattiioonn ddiissppoonniibbllee

  Toute  la  documentation a ete deplacee a la page index "User Docs and
  Tutorials" (Documentation Utilisateur et Cours).

  1188..99..  LL''HHiissttooiirree dd''EEAARRPP

  Earp 0.1 a  demarre  en  tant  que  programme  a  l'automne  1995.  Je
  travaillais  a  la  realisation d'un livre d'or accessible par le web,
  dynamiquement configurable.  A ce moment la, il y avait tout un tas de
  programmes  cgi  faisant  tous  quelque chose de different et d'utile,
  agreges par un peu de colle SSI et un  peu  de  programmation  c.   Je
  realisais  alors  que je faisais beaucoup de travail repetitif, et que
  la plupart des choses que  je  faisais  devaient  s'executer  dans  de
  nombreuses fenetres a la fois (netscape, emacs, shell, mail) alors que
  la mise au point etait  rapidement  devenue  un  cauchemar.   A  cette
  epoque  mon ami et patron Don Michaels me contacta. Il etait interesse
  par l'automatisation d'une grosse partie de notre support  utilisateur
  et  par  la tenue d'une base de donnees gerant l'historique des appels
  et des reponses.

  Peu de temps apres, j'avais termine le schema initial de ce qui est en
  train  de  devenir rapidement notre base de donnees d'aide. Seulement,
  je rechignais a l'idee de construire une  base  de  donnees  d'aide  a
  partir  de ce qui etait alors un ensemble tres primitif d'utilitaires.
  Lorsque les cours du printemps 96 debuterent, je demarrais quand  meme
  le  projet,  principalement  sous le coup de l'ennui, mais aussi parce
  que j'etais dans un cours d'architecture de base de donnees et que  je
  voulais m'entrainer un peu les meninges. Peu de temps apres j'avais un
  prototype acceptable en etat de marche, ce qui rendit Don tres heureux
  car  il avait renonce a l'idee de quelqu'un creant une base de donnees
  d'aide  pour  lui.  (Le  prototype  tourne  encore  sur  l'un  de  mes
  serveurs...(juin  96))  Le  prototype faisait vraiment quelques choses
  tres interessantes, mais en avril, j'etais a  nouveau  decourage...  A
  chaque  fois que je desirais modifier quelque chose, j'entrais dans un
  lent processus de recompilation, ou je tombais sur  un  fichier  texte
  particulierement  distrayant.  Je n'avais aussi aucun moyen d'utiliser
  le concept de building block si utile dans EARP...  J'ai  realise  pas
  mal  d'enormes  coupes-colles.  Vers la fin de l'annee scolaire je fus
  encore une fois decourage sur le deroulement des  choses  et  decidais
  que  ce  dont  j'avais  besoin,  c'etait  d'un  ensemble d'outils plus
  adaptes a ce que je  faisais.  De  plus,  je  voulais  aussi  que  mon
  prototype fonctionne sur une VRAIE base de donnees relationnelle et je
  ne cherissais pas l'idee de recommencer tout ce travail d'acces  codes
  en dur, de liens, et de methodes de sortie.

  J'eus  un  bref moment de repit, si l'on peut dire. Nous soutenions la
  Conference SUNY CIT et j'ai tellement ete occupe pendant  une  semaine
  et  demi  que je pris du recul par rapport a tout ce que j'avais ecrit
  sur le prototype de base de donnee d'aide excepte sur  les  idees  que
  j'avais  eues  quand j'avais ecrit la serie d'utilitaires initiale et,
  ce qui m'irritait le plus c'etait l'etat actuel des choses.

  Peu de temps apres la conference, je commencais  le  prototype  de  la
  version  actuelle  de  EARP(may96),  en  utilisant le SGBD relationnel
  postgres95 comme support. A la mi-juin, le prototype avait  evolue  en
  une suite integree de prototypes d'outils tout a fait seduisante, avec
  comme premier avantage de tous tourner en html, et  de  stocker  leurs
  donnees d'initialisation dans la base de donnee. La plus grande partie
  de la deuxieme moitie de juin fut consacree a la mise au point du code
  et  a  l'utilisation  de  l'interface.( Pendant ces deux semaines j'ai
  accede plus de 5000 fois a notre serveur  web.)  A  la  fin  juin,  la
  plupart  des  bogues importants etaient chasses de EARP, et il y avait
  un nombre suffisant d'objets dans la "nouvelle" base de donnees d'aide
  que  l'on  pouvant  en  faire  l'annonce  officielle a notre equipe de
  support.

  A propos, j'ai egalement tenu un journal pendant le  developpement  de
  EARP  et Don Michaels et moi presentons un papier decrivant la Base de
  Donnees d'Aide a la conference ACM/SIGUCCS a Chicago en  Septembre  de
  cette annee.

  1199..  WWWWWW WWeebb iinntteerrffaaccee ppoouurr PPoossttggrreessSSQQLL -- ddbbeennggiinnee

  <http://www.cis-computer.com/dbengine/ >

  dbengine  est une interface Web plug 'n play pour Postgres95 creee par
  Ingo Ciechowski

  Un extrait de la page d'accueil de dbengine est donne ci-dessous:-

                                   dbengine

                              [CGI-Forum Webring]

                  une interface "installez-et-utilisez" pour Postgres95

  Version 0.82 alpha
  Documentation au 08/11/97
  Ecrit par Ingo Ciechowski
  ---------------------------------------------------------------------------

  A propos de dbengine

  dbengine est une interface entre le WWW et Postgres95 qui permet un acces simple a
  n'importe quelle base de donnees existante en seulement quelques minutes.

  Ce petit programme Perl  est ne apres avoir essaye un tas de paquetages
  disponibles tels que AppGen, PHP-FI et d'autres. Alors, pourquoi ai-je, en quelque
  sorte, reinvente la roue ?

  Et bien, PHP-FI offre une sorte de langage Perl dans vos documents, mais pas le vrai
  Perl alors que AppGen et wdb-p95 necessite la creation d'un fichier de configuration
  pour chacune de vos bases de donnees -- c'est un peu comme si vous deviez apprendre
  un nouveau meta-langage avant de pouvoir commencer a travailler.

  C'est a ce moment que je commencais a me sentir plus a l'aise avec une petite
  applet Perl de mon cru... et maintenant mon dbengine est devenu un outil qui, je
  pense, est pret a etre partage avec les autres.

  A la difference des autres outils, vous n'avez pas a apprendre un langage de
  programmation particulier ou un langage de script pour commencer a utiliser dbengine.
  De plus, il n'y a pas a creer de fichier de configuration pour chaque base de
  donnees, et vous n'avez donc pas besoin de vous familiariser avec sa structure.
  Cependant - au cas ou vous voudriez profiter de toutes les possibilites de dbengine,
  ce serait une bonne idee de connaitre le langage Perl.

  Le systeme tout entier peut etre configure a l'aide de simples manipulations d'une
  base de donnees complementaire qui contient les informations de detail sur la maniere
  de visualiser vos acces a la base de donnees. Vous pouvez meme specifier des Champs
  Virtuels qui sont calcules en temps reel avant d'etre affiches a l'ecran.

  Images d'ecrans

     * Vue d'une liste des tables et des bases de donnees connectees (104k)
     * Vue d'un enregistrement avec la liste des enregistrements concernes
       d'une table separee (100k)

  Licence

  dbengine est un logiciel libre selon les memes conditions que Perl. Lisez sa licence
  si vous n'etes pas sur de ce que vous pouvez ou ne pouvez pas faire. La derniere
  ligne indique que c'est une version plus gentille et plus moderee 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!

  informations complementaires...

  Si vous etes interesse par des informations plus precises concernant dbengine,
  utilisez ces liens :

     * comment installer dbengine
     * comment configurer le paquetage
     * travailler avec dbengine
     * base de donnees de description
     * fichiers modeles

  Si vous avez besoin d'informations complementaires, n'hesitez pas a m'envoyer un E-Mail.
  Et naturellement, il y a de plus le code source Perl, bien documente, qui peut vous
  aider a trouver votre chemin ;-)

  ---------------------------------------------------------------------------
       derniere mise a jour de cette page : 08/11/97
  ---------------------------------------------------------------------------

  2200..  MMoodduullee AAppaacchhee WWeebbsseerrvveerr ppoouurr PPoossttggrreeSSQQLL -- NNeeooSSoofftt NNeeooWWeebbSSccrriipptt

  Apache   est  un  serveur  Web  bien  connu.  On  trouvera  un  module
  d'interface  de  PostgreSQL  pour  le   serveur   Web   Apache   a   -
  <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 compliques dans des fichiers HTML.

  Quand une page HTML contenant un script NeoWebScript est  appelee,  le
  serveur  Web  ,  ayant le NeoWebScript active, execute le(s) script(s)
  inclus, produisant une page Web dont le contenu, personnalise,  a  ete
  cree par le programme.

  NeoWebScript  est  un  moyen rapide, sure, facile a apprendre de creer
  des programmes interactifs puissants directement en code HTML dans des
  pages  Web.  Avec  NeoWebScript,  les  compteurs,  les  formulaires de
  courrier electronique, murs a graffitis,  livres  d'or  et  suivi  des
  visiteurs  sont  aises,  meme  pour  un programmeur debutant. Regardez
  comment NeoWebScript se defend bien par rapport a 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'integrant avec  le
  nouveau serveur Apache 1.2.0 .

  Si  vous  utilisez  un  serveur web ayant NeoWebScript installe et que
  vous  vouliez  commencer  a  l'utiliser,  il  y  a  un  tout  un   tas
  d'Informations  Utilisateur  disponibles.  Les  reponses de bases pour
  demarrer  se  trouvent  dans  la   "FAQ   Nouvel   Utilisateur".   Des
  didacticiels  vous  guident dans l'apprentissage du langage, alors que
  des Demonstrations vous apportent des applications toutes  faites  que
  vous  pouvez  tele-charger  et  adapter. Le document "Commandes et les
  Variables" constitue la reference complete du  langage,  et  celui  de
  Maintenance  contient  des  conseils  et des astuces pour vous aider a
  resoudre tous les problemes.

  Au cas ou vous souhaiteriez installer NeoWebScript sur  votre  serveur
  web,  votre  webmestre  doit lire notre "FAQ Sysop" pour se lancer. Le
  document "Theorie de  fonctionnement"  explique  comment  NeoWebScript
  fonctionne, celui d'Installation est un guide pas a pas des operations
  a effectuer. Le guide de Gestion traite de la maniere de configurer et
  de  faire fonctionner le serveur, celui de Tests permet de verifier le
  fonctionnement correct de NeoWebScript, enfin,  celui  de  Maintenance
  traite des problemes de serveur.

  He,   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  complete
  quand  vous  vous  enregistrerez  pour  tele-charger le logiciel, mais
  l'essentiel est que nous aimerions recevoir la somme monstrueuse de  $
  99  si  vous desirez 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  ete  invente  par  Karl
  Lehenbauer,  Directeur  Technique chez NeoSoft, et documente, renforce
  et etendu par les  programmeurs  de  NeoSoft  et  par  des  redacteurs
  techniques.

  Le  serveur  Apache  est  le  serveur  web le plus populaire au monde,
  totalisant 42  %des  1  044  163  sites  interroges  lors  de  l'etude
  "Netcraft  Web  Server"  de  Mai  1997. La deuxieme plus grande valeur
  enregistree concerne les  differents  serveurs  Microsoft,  totalisant
  legerement  plus  de  16  %,  soit  une  difference  d'environ 270,000
  serveurs.

  Tcl/Tk est un langage de script puissant, libre  et  multi-plateformes
  developpe  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  developpeurs de logiciels de realiser un travail
  dix fois plus rapidement qu'avec des outils bases sur C ou C++.  C'est
  aussi  un  grand  langage  de  synthese permettant de faire travailler
  ensemble des applications existantes en les rendant plus graphiques et
  orientees Internet."

  Avec  une  communaute de developpement de plus de 500 000 personnes de
  par le monde et des milliers d'applications  commerciales,  Sun  vient
  juste  d'annoncer  la  creation  d'un  nouveau groupe de travail nomme
  SunScript, pour soutenir cette communaute  avec  un  environnement  de
  developpement  integre  et  pour developper une suite de produits pour
  etablir un lien entre Tcl le Web et Java.

  Karl Lehenbauer,  Fondateur  et  Directeur  Technique  de  NeoSoft,  a
  participe  au  developpement  de  Tcl/Tk  des le tout debut. Avec Mark
  Diehkans, ils sont les auteurs de Tcl etendu   (Extended  Tcl),  connu
  egalement  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 etendu, et furent
  introduites dans le langage par le Dr.  Ousterhout.

  NeoSoft Inc., 1770 St. James Place, Suite 500, Houston, TX 77056 USA

  2211..  HHEEIITTMMLL,, eexxtteennssiioonn,, ccoottee sseerrvveeuurr ddee HHTTMMLL eett llaannggaaggee 44GGLL ppoouurr PPoosstt--
  ggrreeSSQQLL

  Heitml est un autre outil d'interfacage de postgres avec le  monde  du
  world wide web.  Pour plus de details contacter

                 Helmut Emmelmann H.E.I. Informationssyteme GmbH
                 Wimpfenerstrasse 23 Tel. 49-621-795141
                 68259 Mannheim Germany Fax. 49-621-795161

  +o  E-mail Mr.Helmut Emmelmann at emmel@h-e-i.de

  +o  Heitml site web principal  <http://www.heitml.com>

  +o  Heitml site web secondaire  <http://www.h-e-i.deom>

  Heitml  est  a  la  fois  une  extension,  cote serveur, de HTML et un
  langage de la quatrieme generation (4GL). Avec lui, on peut ecrire des
  applications  web  dans  un  style  HTML  et en utilisant de nouvelles
  balises de style HTML.

  heitml (prononce "H-ail"-TML) est une extension de HTML et un  langage
  de  quatrieme generation complet permettant aux Applications utilisant
  le web d'interagir avec des donnees stockees dans des bases de donnees
  SQL, sans meriter l'ecriture de scripts CGI complexes.

  heitml etend HTML cote serveur, convertissant de maniere dynamique les
  fichiers ".hei" au format HTML et ainsi, les rendant compatibles  avec
  n'importe quel butineur web. Il englobe la syntaxe simple et familiere
  de HTML et apporte un large assortiment de Balises et de Bibliotheques
  pre-developpees  pour  prendre  en  charge  les  taches qui auparavant
  necessitaient CGI. De meme que XML,  heitml  permet  l'utilisation  de
  balises  definies par l'utilisateur. Avec heitml les marqueurs definis
  par l'utilisateur peuvent etre  traduits  en  HTML  et  envoyes  a  un
  butineur.

  heitml  est destine a la fois aux concepteurs HTML et aux programmeurs
  professionnels. Les concepteurs  HTML  peuvent  utiliser  les  Balises
  heitml pour fabriquer des pages web dynamiques, des acces aux bases de
  donnees SQL ou creer des applications web completes. On peut creer des
  Compteurs,  des  bases  de  donnees d'inscriptions, des formulaires de
  recherche, des formulaires  de  courrier  electronique  ou  des  menus
  hierarchises  en  utilisant  simplement des Balises de style HTML pre-
  developpees que l'on  trouve  dans  les  nombreuses  Bibliotheques  de
  Composants.

  Pour   les   programmeurs,  heitml  inclut  un  langage  de  quatrieme
  generation complet en HTML

                 (e.g. <if>, <while>, et <let> Balises),

  plus un evaluateur d'expression puissant pour  les  types  de  donnees
  entiers, reels, booleens chaine de caracteres et tuple. Les tuples ont
  une reference semantique comme dans les langages orientes objets  mod-
  ernes  et  sont  stockes  sur  un  tas. Les variables heitml y compris
  toutes les structures de donnees complexes stockees sur le tas conser-
  vent leur valeur de page en page par l'utilisation du Mode Session. Il
  vous est possible de  definir  vos  propres  balises  ou  vos  balises
  d'environnement et meme de redefinir les balises HTML.

  Avec heitml il devient possible de

  -  -  -  developper  des Sites Web de maniere structuree et modulaire,
  tout  en  reduisant  de  facon  drastique  la  surcharge  due   a   la
  maintenance.

  -  -  -  developper des Sites Web intelligents et interactifs, dont le
  contenu s'adapte dynamiquement aux besoins de l'utilisateur.

  - - - de visualiser le contenu de bases  de  donnees  SQL  sans  autre
  programmation  que l'utilisation de notre bibliotheque de Balises pre-
  definies "dba".

  - - - de developper des applications de bases de donnees 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 particulierement  rapide  (mis  a  part  la
  surcharge due a 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 donnees yard sont
  supportes. heitml tourne sous Linux, BSDi, Solaris et SunOS,  de  meme
  que sous Windows NT avec CGI, ISAPI et ODBC et Windows 95.

  heitml  (sous  linux)  est  libre  pour  la  recherche,  et  pour  une
  utilisation privee et  non  commerciale.  Les  Sites  Web  commerciaux
  doivent  payer  une  licence.  La version totalement operationnelle de
  heitml est disponible pour une periode  d'essai  et  peut  etre  tele-
  chargee  librement.  (Notez, cependant, que chaque page Web ".hei" que
  vous developperez affichera un message indiquant  qu'il  s'agit  d'une
  version  a  usage non commerciale. Apres enregistrement, vous recevrez
  une  cle  pour  effacer  ce  message  sans  avoir  a  reinstaller   le
  programme.)

  Les nouvelles fonctionnalites de la version 1.2 sont

  -  -  -  Bibliotheque  de Composants pour des Formulaires de Recherche
  dans  un  Base  de  Donnees,  menus  hierarchises  d'ouverture  et  de
  fermeture, formulaires de courrier electronique

  - - - Le Mode Session a ete re-concu et ameliore pour conserver toutes
  les  variables  (y  compris  le  tas  tout  entier)  au  travers   des
  differentes  pages. Cela signifie que les donnees, de n'importe quelle
  taille  sont  conservees  a  l'interieur  d'une  session.  Ceci  offre
  l'opportunite   d'un   champ   plus  large  pour  creer  de  nouvelles
  applications, e.g. stockage complet des resultats d'une  interrogation
  dans la memoire de la session.

  -  -  -  Les  instructions  d'installation,  la  documentation  et les
  bibliotheques d'exemples ont ete augmentees de maniere  significative,
  un cours d'auto-formation a ete ajoute

  -  -  -  Des balises pour executer des commandes shell et pour envoyer
  des courriers electronique ont ete ajoutees

  - - - 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 facon intuitive. En cas d'erreur a l'execution,
  toutes  les  structures  de  donnees  internes  sont affichees dans le
  butineur en indiquant et  preservant  leurs  positions  dans  le  code
  source original.

  -  - - Diverses nouvelles variables serveur et fonctions integrees ont
  ete ajoutees

  - - - En mode production, heitml collecte maintenant des  informations
  completes   sur  les  erreurs  survenues  lors  de  l'acces,  par  des
  utilisateurs, a votre site.

  Voici ce que dit la page d'accueil de heitml -

  heitml  (prononcer   "H-ail"-TML)   etend   et   augmente   de   facon
  significative   les   fonctionnalites   de   HTML  grace  aux  balises
  definissables et aux possibilites completes de programmation.  Ce  qui
  permet  de  creer  simplement des applications au contenu dynamique et
  orientees bases de donnees 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  cote,  comme
  utilisateur   avance   ou  comme  programmeur  vous  pouvez  creer  et
  programmer de puissantes bibliotheques  de  balises.   Cette  approche
  rend  heitml  souhaitable  a la fois pour les utilisateurs nouveaux de
  HTML et pour les programmeurs professionnels.  heitml  tourne  sur  le
  serveur  web  et  genere  dynamiquement  du  HTML,  aussi  heitml  est
  compatible avec les normes internet et avec  n'importe  quel  butineur
  web.  Il  permet un acces total aux bases de donnees tout en evitant a
  l'utilisateur toute  la  complexite  inutile  de  CGI.  heitml  a  ete
  developpe  selon  les plus recents criteres en matiere de construction
  de compilateurs et de systemes transactionnels.

  Les pages heitml sont developpees exactement de la meme facon que  les
  pages   HTML,  a l'aide d'un editeur de texte ou d'un editeur HTML, et
  placees comme d'habitude sur le serveur  web.  Cependant,  maintenant,
  les  pages peuvent contenir des balises heitml dynamiques et des acces
  a des bibliotheques de balises. Vous pouvez utiliser ces balises  pour
  acceder  a  une base de donnees, pour creer un contenu dynamique, pour
  envoyer des courriers electronique, et meme pour creer  de  puissantes
  applications  telles  que  les  bases  de donnees d'inscriptions ou de
  systemes d'achats.

  Les nouveaux venus a HTML et les  programmeurs  professionnels  seront
  stupefaits de la vitesse et de la facilites avec lesquelles il peuvent
  concevoir des applications passionnantes telle que  notre  Livre  d'Or
  Interactif sans necessiter la complexite et l'apprentissage difficiles
  des scripts CGI, simplement en utilisant les outils fournis dans notre
  bibliotheque dba.

  heitml est accompagne d'un large eventail de bibliotheques de balises,
  pour creer des livres d'or, des applications de maintenance  de  bases
  de  donnees,  des formulaires puissants de courrier electronique ou de
  structuration de votre site web a l'aide de menus  hierarchiques.  Ces
  outils  sont prets a etre utilises, il suffit simplement d'ajouter les
  balises correspondantes a votre site web.

  En tant que programmeur experimente, vous pouvez  pleinement  utiliser
  l'architecture  dynamique persistante de tuple d'heitml : heitml n'est
  pas  simplement  un  langage  de  script  a  typage  dynamique,   avec
  evaluateur d'expression, procedures recursives et capacites de passage
  de parametres etendues, mais il  apporte  aussi  des  possibilites  de
  tuples  persistants  dynamiques  pour  conserver  automatiquement  des
  donnees de session de n'importe quelle taille.

  heitml a tellement de nouvelles possibilites  et  d'usages  que  c'est
  impossible  de  les decrire tous dans une simple page web.  Pour cette
  raison, nous avons concu ce site Web de maniere  a  fournir  soit  une
  simple  vue  d'ensemble du produit, soit a fouiller aussi profondement
  que vous le desirez dans les "tenants  et  aboutissants"  du  langage.
  Quelle  que  soit l'approche que vous choisirez, nous pensons que vous
  trouverez que heitml a beaucoup a offrir, et nous  esperons  que  vous
  serez d'accord pour trouver que reellement "il porte le monde du World
  Wide Web a un niveau plus eleve!"

  Le menu, sur le cote gauche de l'ecran vous  aidera  a  naviguer  dans
  notre  Site  Web  Site  de  maniere organisee et methodique, mais vous
  pouvez aussi utiliser notre  Menu  Rapide  (Quick  Menu)  pour  sauter
  directement a n'importe quelle page avec un seul clic sur le mulot.

  Si  vous  visitez  ce  Site pour la premiere fois, nous vous suggerons
  d'essayer  le  Livre  d'Or  Interactif   d'heitml   pour   avoir   une
  demonstration  vraiment  impressionnante  de la facon 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 creiez votre propre page Web privee et que vous la
  voyiez publiee immediatement!

  La section traitant des Fonctionnalites de heitml fourni  un  Sommaire
  Rapide  de  ses  Fonctionnalites  et de ses Avantages, de meme que des
  Pages destinees a repondre aux besoins specifiques  et  aux  questions
  des  Concepteurs  et des Programmeurs. Notre Guide du Langage offre un
  didacticiel, en ligne, qui montre, de maniere pratique, quelques  unes
  des   facons  dont  vous  pouvez  utiliser   heitml  pour  developper,
  ameliorer et simplifier vos Pages Web et vos Applications.

  Le document Reference du Langage est destine a ceux qui cherchent  une
  information  specifique sur la syntaxe, la structure, et l'utilisation
  des differents elements du langage. Cependant, ce  pourrait  etre  une
  bonne idee pour tout le monde de lire la Page concernant la Conception
  Generale qui offre une vue  d'ensemble  sur  les  types  de  problemes
  specifiques  pour  lesquels  heitml  a ete concu afin d'y apporter une
  solution.

  Naturellement, vous voudrez savoir si heitml  tourne  sur  le  Systeme
  d'Exploitation  specifique,  le  Serveur  Web, ou le SGBD SQL que vous
  utilisez, vous trouverez toutes ces informations  dans  notre  section
  des Plates-formes Supportees.

  Enfin,  nous  vous  invitons  a  Tele-charger  une  copie  d'essai  du
  programme pour l'utiliser sur votre propre systeme. Nous  sommes  surs
  que  vous  apprecierez  cette  "methode  d'essai avant achat", et nous
  sommes a l'ecoute de tout retour d'informations que vous voudrez  bien
  nous donner.

  2222..   PPHHPP//FFII  LLaannggaaggee  ddee ssccrriipptt ccoottee sseerrvveeuurr,, aavveecc HHTTMMLL iinntteeggrree,, ppoouurr
  PPoossttggrreeSSQQLL

  Outil d'interfacage WWW  <http://www.vex.net/php>

  Pour   les   questions   envoyer   un   courrier   electronique   a  :
  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  cote  serveur,  avec  langage  HTML
  integre.  Il vous permet d'ecrire des scripts simples directement dans
  vos fichiers .HTML a la maniere JavaScript, sauf que, a la  difference
  de  JavaScript,  PHP/FI  n'est  pas  dependant  du  butineur  utilise.
  JavaScript est un langage, cote client, avec HTML  integre  alors  que
  PHP/FI  est  un  langage  cote 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
  systemes d'exploitation supportes, et vous  jetterez  probablement  un
  oeil  sur  LiveWire  Pro. Si vous preferez un logiciel libre, evoluant
  rapidement, qui est disponible avec la totalite de  son  code  source,
  vous apprecierez probablement PHP/FI.

  2222..11..  FFoonnccttiioonnnnaalliitteess pprriinncciippaalleess

  Support de CGI Standard, FastCGI et du module Apache.  Comme programme
  CGI standard, PHP/FI peut etre installe sur n'importe  quelle  machine
  Unix  sur  laquelle  tourne  n'importe  quel serveur web Unix. Avec le
  support de la nouvelle norme FastCGI, PHP/FI peut trouver avantage des
  gains  de  vitesse  apportes  par  ce  mecanisme. Comme module Apache,
  PHP/FI devient une alternative extremement puissante et brillante a la
  programmation CGI.

  +o  Enregistrement des acces Avec les possibilites d'enregistrement des
     acces de PHP/FI, les utilisateurs peuvent  entretenir  leur  propre
     compteur d'acces et l'enregistrer. Il n'utilise en aucune facon les
     fichiers de d'enregistrement des connexions du systeme central,  et
     il  permet  un  suivi  des  acces  en  temps  reel.  Le  Script  du
     Visualisateur de Connexions fournit un resume rapide des acces a un
     ensemble de pages possedees par un utilisateur individuel. De plus,
     le paquetage peut etre configure pour generer un pied de page,  sur
     chaque  page,  qui  montre l'information sur les acces. Regardez au
     bas de cette page pour en avoir un exemple.

  +o  Controle d'acces Un ecran de configuration  integre,  base  sur  le
     web, permet la configuration du controle des acces. Il est possible
     de creer des regles d'acces pour toutes ou quelques unes des  pages
     web   possedees   par   une  certaine  personne  qui  met  diverses
     restrictions sur qui peut voir ces pages et  comment  elles  seront
     vues.   Les  pages  peuvent  etre  protegees  par  un mot de passe,
     completement interdites, a connexion desactivee et l'acces base sur
     le   domaine   du   client,  le  butineur,  l'adresse  de  courrier
     electronique ou meme le document auquel on se refere.

  +o  Support de Postgres Postgres est un  SGBDR  (RDBMS)  avance  libre.
     PHP/FI  supporte les requetes Postgres95 et PostgreSQL SQL incluses
     directement dans les fichiers .html.

  +o  RFC-1867 Support du tele-chargement de fichier  Le  tele-chargement
     de  fichier  est  une  nouvelle fonctionnalite de Netscape 2.0.  Il
     permet aux  utilisateurs  de  tele-charger  des  fichiers  vers  le
     serveur  web.   PHP/FI  realise le decodage Mime reel pour faire ce
     travail et fournit aussi le cadre additionnel  pour  faire  quelque
     chose  d'utile  avec le fichier tele-charge une fois que celui-ci a
     ete recu.

  +o  Controle d'authentification base sur HTTP PHP/FI peut etre  utilise
     pour  creer  des  mecanismes d'authentification personnalises bases
     sur HTTP pour le serveur web Apache.

  +o  Variables,  Tableaux,  Tableaux  associatifs  PHP/FI  supporte  des
     variables  typees,  des tableaux et meme des tableaux associatifs a
     la Perl. Ils peuvent etre  passes  d'une  page  web  a  l'autre  en
     utilisant les methodes GET ou POST.

  +o  Conditions,  Boucles  Tant que (While) PHP/FI possede un langage de
     script aux fonctionnalites completes 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
     controler l'ordre logique et la maniere dont les pages html doivent
     etre affichees.

  +o  Expressions Regulieres etendues  Les  expressions  regulieres  sont
     tres  utilisees  pour  le filtrage, le remplacement de sequences et
     les  manipulations  generales  de  chaines  de  caracteres.  PHP/FI
     supporte   toutes  les  operations  communes  sur  les  expressions
     regulieres.

  +o  Controle de l'En-tete HTTP brute La possibilite d'envoyer a  partir
     de  pages  web  des en-tetes HTTP brutes personnalisees en fonction
     d'une condition est essentielle pour creer  un  site  web  de  haut
     niveau. Un usage frequent est l'envoi d'un emplacement: en-tete URL
     pour Rediriger le client appelant vers  une  autre  URL.   Il  peut
     aussi  etre  utilise  pour  stopper  le  stockage  ou  manipuler la
     derniere mise a jour de l'en-tete de pages.

  +o  Creation d'images  KIF  a  la  volee  PHP/FI  prend  en  compte  la
     bibliotheque   d'image  GD  de  Thomas  Boutell  ce  qui  offre  la
     possibilite de generer des images GIF a la volee.

  +o  Prise en charge du mode securite ("Safe Mode") ISP PHP/FI prend  en
     charge  un  "Mode  de  Securite" exceptionnel qui permet d'avoir de
     multiples utilisateurs executant des scripts PHP en toute  securite
     sur le meme serveur.

  +o  C'est Libre!  Pour finir, et c'est un point essentiel. Le paquetage
     est entierement 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 detailles.

  2222..22..  CCrreeddiittss

  *  De  grandes  parties  de  ce  code  ont  ete  developpees a et pour
  l'universite de Toronto. De grands Mercis a Lee Oattes du  Departement
  de  Developpement  des  Reseaux  a  l'universite  pour  ses  critiques
  constructives permanentes.

  * Le code de prise en charge  de  Postgres95  a  ete  ecrit  par  Adam
  Sussman asussman@vidya.com

  *  d'autres,  innombrables,  ont  participe  aux tests et a la mise au
  point du paquetage.

  PHP/FI Version 2.0

  2222..33..  BBrreeff HHiissttoorriiqquuee

  PHP a commence sa vie comme simple  petite  enveloppe  cgi  ecrite  en
  Perl.   Je  l'ai  ecrit  en un apres-midi, dans une periode entre deux
  contrats, alors que j'avais besoin d'un outil rapide  pour  avoir  une
  idee de la personne qui etait en train de lire mon curriculum vitae en
  ligne. Je n'avais pas eu l'intention de le voir utiliser en dehors  de
  mon  propre  usage.   Le serveur web sur lequel j'avais mon curriculum
  vitae etait extremement surcharge et avait des problemes constants  de
  creation de processus. Je reecris le petit programme Perl en C pour me
  debarrasser de la surcharge considerable generee par la creation  d'un
  processus  d'execution  du  programme  Perl  a  chaque  fois  que  mon
  curriculum vitae etait consulte.

  Par la suite d'autres personnes, sur  le  meme  serveur  web,  prirent
  connaissance  de mon petit programme et me demanderent s'ils pouvaient
  l'utiliser. Alors, comme cela devait arriver, ils  commencerent  a  me
  demander  plus  de fonctionnalites. J'ajoutais plus de fonctionnalites
  et finalement constituais une  semi-distribution  en  y  incluant  une
  documentation,  une  liste  de  diffusion  et  une  FAQ.  Le nom de ce
  paquetage etait "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 meme epoque, je commencais a m'amuser avec les bases  de  donnees
  et  j'ecrivis  un  outil pour inclure facilement des requetes SQL dans
  des pages web. C'etait fondamentalement un autre petit  programme  CGI
  qui   analysait   les  requetes  SQL  et  facilitait  la  creation  de
  formulaires et de tables bases sur ces requetes. Cet outil fut  appele
  FI "Interpreteur de Formulaire" (Form Interpreter).

  La  version  2.0  PHP/FI  est  une  reecriture  complete  de  ces deux
  paquetages combines pour former un simple programme. il  a  maintenant
  evolue  au point de devenir un simple langage de programmation integre
  dans les fichiers HTML.  L'acronyme original, PHP, lui est  reste.  Il
  n'est  plus reellement approprie.  PHP/FI est aujourd'hui plus utilise
  pour mettre en place des sites web entiers que pour de  petites  pages
  d'accueil personnelles. Quel que soit son nom, il elimine le besoin de
  recourir a de  nombreux  petits  programmes  cgi  Perl  en  permettant
  d'inserer de simples scripts directement dans vos fichiers HTML.  Ceci
  ameliore les  performances  globales  de  vos  pages  web  puisque  la
  surcharge  due  au  lancement  de  processus  Perl  successifs  a  ete
  eliminee. La gestion de larges sites web a egalement ete facilitee  en
  placant  tous  les  composants  d'une  page  web  dans un fichier html
  unique. En incluant le support de differentes  bases  de  donnees,  il
  devient  trivial  de  developper  des  pages web mettant en oeuvre des
  bases  de  donnees.  Nombreux  sont  ceux  qui  trouvent   que   cette
  integration  est  plus  facile  a  gerer  que  d'essayer  de creer des
  fichiers HTML et CGI separes.

  Tout au long de cette documentation, toute  reference  a  PHP,  FI  ou
  PHP/FI  traite  de  la  meme  chose. La difference entre PHP et FI est
  seulement conceptuelle. Les deux sont construits a partir de  la  meme
  distribution  du  code  source. Lorsque je construit le paquetage sans
  aucun support de connexion d'acces ou de restriction d'acces, je nomme
  mon  binaire FI.  Quand je le construit avec ces options, je l'appelle
  PHP.

  2222..44..  BBoonn,, qquuee ppuuiiss--jjee ffaaiirree aavveecc PPHHPP//FFII??

  La premiere chose que vous allez noter, si  vous  faites  tourner  une
  page par l'intermediaire de PHP/FI, c'est qu'il ajoute un pied de page
  vous informant du nombre d'acces a votre  page  (si  vous  incluez  le
  support des connexions d'acces dans votre binaire). C'est seulement un
  tout petit exemple de ce que PHP/FI peut  faire  pour  vous.  Il  joue
  egalement  le  role  tres  important d'interpreteur de formulaire cgi,
  d'ou la partie FI de son nom. Par exemple si vous creez un  formulaire
  dans  l'une  de  vos pages web, vous avez besoin de quelque chose pour
  traiter l'information  contenue  dans  ce  formulaire.  Meme  si  vous
  desirez  simplement  passer  l'information  a 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 donnees du formulaire
  pour en faire quelque chose.

  2222..55..  UUnn ssiimmppllee eexxeemmppllee

  Supposons que vous ayez le formulaire :

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

  Votre fichier display.html doit contenir quelque chose du genre :

  < ?echo "Hi $ name, vous avez $ age ans!

  " >

  C'est aussi simple que cela! PHP/FI cree automatiquement une  variable
  pour  chaque  champ  de  saisie de votre formulaire. Vous pouvez alors
  utiliser ces variables dans le fichier ACTION URL.

  L'etape suivante, apres avoir vu comment utiliser ces  variables,  est
  de  commencer  a jouer avec quelques balises de gestion du deroulement
  logique de vos pages. Par exemple, si vous voulez afficher  differents
  messages  dependants  de  des  informations entrees par l'utilisateur,
  vous pouvez utiliser la logique si/alors (if/else). Dans notre exemple
  ci-dessus,  on  peut  afficher  differentes  choses dependant de l'age
  entre par l'utilisateur en modifiant notre fichier display.html en :

       <?
           if($age>50);
               echo "Hi $name, vous etes un fossile!<p>";
           elseif($age>30);
               echo "Hi $name, vous etes tres vieux!<p>";
           else;
               echo "Hi $name.";
           endif;
       >

  PHP/FI fournit un langage de  script  tres  puissant  qui  peut  faire
  beaucoup plus que ce qui est expose dans l'exemple ci-dessus. Regardez
  la section sur le langage  de  Script  PHP/FI  pour  des  informations
  complementaires.

  Vous  pouvez  egalement utiliser PHP/FI pour configurer qui a le droit
  d'acceder a vos pages. Ceci  est  effectue  en  utilisant  l'ecran  de
  configuration  inclus.   Par  son  intermediaire  ,  vous pourrez, par
  exemple, specifier que seulement les gens  appartenant  a  un  certain
  domaine seront autorises a voir vos pages, vous pouvez egalement creer
  une regle protegeant certaines pages par un  mot  de  passe.  Voir  la
  section Controle d'Acces pour plus de details.

  PHP/FI est egalement capable de recevoir des fichiers tele-charges par
  n'importe  quel  butineur  conforme  a  la   norme   RFC-1867.   Cette
  fonctionnalite  permet aux gens de tele-charger egalement des fichiers
  de texte ou binaire.  Avec le controle  de  PHP/FI  et  les  fonctions
  logiques,  vous  disposez  d'un  controle total sur qui est autorise a
  tele-charger un fichier et sur ce que l'on peut faire  de  ce  fichier
  une  fois tele-charge. Voir la section Tele-chargement de fichier pour
  de plus amples details.

  PHP/FI supporte le paquetage Postgres95. Il supporte les requetes  SQL
  incluses  dans  vos  fichiers  .HTML.  Consultez  la  section  Support
  Postgres95 pour plus d'informations.

  PHP/FI supporte egalement le paquetage du SGBD mysql. Il supporte  les
  requetes  SQL  incluses  dans vos fichiers .HTML. Consultez la section
  Support mysql pour plus d'informations.

  2222..66..  RReeddiirreeccttiioonn CCGGII

  Notes Apache 1.0.x

  Une bonne maniere de faire tourner PHP/FI est d'utiliser un module  de
  redirection cgi avec le serveur Apache. Veuillez noter que vous n'avez
  pas a 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 developpe par Dave Andersen  angio@aros.net
  et                  est                  disponible                  a
  ftp://ftp.aros.net/pub/util/apache/mod_cgi_redirect.c    et    l'autre
  arrive  inclus  avec  Apache  et  est  appele  mod_actions.c. Ces deux
  modules sont extremement similaires.  Ils  different  tres  legerement
  dans  leur  utilisation.  Les deux ont ete testes et fonctionnent avec
  PHP/FI.

  Mise en garde importante: a la date de cette redaction (Apr.20/96), la
  version  actuelle  officielle  (1.0.5)  a  de  severes limitations qui
  empechent les requetes de redirection cgi d'avoir  des  donnees  post-
  method  associees.  J'ai  etudie  ce  problemes et l'ai resolu dans ma
  version d'Apache. Il y a une  rustine  officielle  dans  les  Fichiers
  Archives de la Page d'Accueil.

  Une  autre mise en garde particulierement importante au sujet d'Apache
  1.0.x est qu'il n'aligne pas correctement les  types  doubles  sur  la
  plupart  des architectures. Vous decouvrirez d'etranges erreurs de bus
  provenant de votre  httpd en utilisant mod_php. Comme  solution,  soit
  vous  passez  a  la  version  Apache  1.1, soit vous editez 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 a 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 la maniere d'ajouter un  module.
  En  general  vous  ajoutez  le  nom  de  module dans un fichier appele
  Configuration. La ligne a 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 creer 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 a ajouter
  doit etre quelque chose comme :

  application/x-httpd-php phtml

  Si vous vous appretez a  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  appretez  a  utiliser  mod_cgi_redirect.c  vous devrez
  ajouter cette ligne a srm.conf :

  CgiRedirect application/x-httpd-php /cgi-bin/php.cgi

  N'essayez   pas   d'utiliser   en   meme   temps   mod_actions.c    et
  mod_cgi_redirect.c .

  Une fois que vous avez l'un de ces modules de redirection cgi installe
  et configure correctement, vous pouvez specifier que vous voulez qu'un
  fichier  soit  filtre  par  php/fi  en  mettant simplement l'extension
  .phtml au fichier. De plus, si vous ajoutez index.phtml a votre  ligne
  de  configuration  DirectoryIndex dans votre fichier srm.conf alors la
  page de plus haut niveau d'un repertoire sera automatiquement  filtree
  par php si vous appelez votre fichier index index.phtml.

  HTTPD Netscape

  Vous  pouvez  rediriger automatiquement les requetes pour des fichiers
  ayant une extension donnee de facon a 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  PHP/FI.  Le  fichier  LISEZ_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. Une rustine pour faire cela avec NCSA 1.5 est
  disponible dans le fichier archives de PHP/FI.

  2222..77..  LLaanncceerr PPHHPP//FFII aa ppaarrttiirr ddee llaa lliiggnnee ddee ccoommmmaannddee

  Si vous fabriquez la version CGI de  PHP/FI,  vous  pouvez  l'utiliser
  simplement  a  partir  de  la  ligne  de  commande, en tapant: php.cgi
  nom_de_fichier ou  nom_de_fichier  est  le  fichier  que  vous  voulez
  filtrer.  Vous  pouvez egalement creer des scripts PHP/FI autonomes en
  faisant ressembler la premiere ligne de votre script a  quelque  chose
  comme :

           #!/usr/local/bin/php.cgi -q

  L'option  "-q"  supprime  l'impression  des en-tetes HTTP. Vous pouvez
  vous passer de cette option si vous le desirez.

  2233..  IInntteerrffaaccee PPyytthhoonn ppoouurr PPoossttggrreeSSQQLL

  PyGres95 est une  interface  pour  PostgreSQL.  Il  est  disponible  a
  <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 PostgresSQL pour Python

  PyGres95, version 1.0b Une interface Python pour la  base  de  donnees
  PostgresSQL.  Ecrit par Pascal Andre, andre@chimay.via.ecp.fr

  PostgresSQL est un SGBD derive de Postgres4.2. Il est conforme a (pour
  la plupart) ANSI SQL et offre beaucoup de  possibilites  interessantes
  (Liens  dynamiques  C  pour les fonctions ou les definitions de types,
  temps de reponse, ...). Ce paquetage est protege par un  copyright  de
  l'Universite  de Californie (Regents of the University of California),
  et est diffusable librement.

  Python est un langage de  programmation  interprete.  Il  est  oriente
  objet  et facile d'utilisation (syntaxe legere, simple et instructions
  simples), et dispose de  nombreuses  extensions  pour  construire  des
  GUIs,  des  interfaces  WWW,...  Un  butineur  web "intelligent" (a la
  HotJava) est actuellement en cours de developpement  (november  1995),
  et  cela  devrait ouvrir de nombreuses portes aux programmeurs. Python
  est protege  par  un  copyright  de  Stichting  Mathematisch  Centrum,
  Amsterdam, Pays-Bas, et est diffusable librement.

  PyGres95  est  un  module  python  d'interface  a  la  base de donnees
  PostgresSQL.  Il comprend une  bibliotheque  de  requetes  PostgresSQL
  permettant  une  utilisation  facile des fonctionnalites puissantes de
  PostgresSQL en cooperation avec tous les autres modules python.  Il  a
  ete  developpe  sur un systeme Linux 1.3/ELF, mais a ete teste sur une
  plate-forme Solaris 2.4. De toutes facons, il devrait fonctionner  sur
  toute plate-forme ou  python et postgres95 sont disponibles.

  2233..11..  OOuu llee ttrroouuvveerr ...... ??

  Les sites principaux des differents paquetages sont :

  +o  Python :      <ftp.python.org:/pub/python>

  +o  Postgres95 :  <ftp.s2k-ftp.cs.berkeley.edu:/pub/postgres95>

  +o  PyGres95 :    <ftp.via.ecp.fr:/pub/python/contrib>

  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 repertoires contrib
  des sites Python et PostgresSQL.

  2233..22..  IInnffoorrmmaattiioonn eett ssuuppppoorrtt

  Si vous avez besoin d'informations concernant ces paquetages  veuillez
  consulter leurs sites web:

  +o  Python :      <http://www.python.org/>

  +o  Postgres95                                                        :
     <http://epoch.cs.berkeley.edu:8000/postgres95/index.html>

  +o  PyGres95 :    <http://www.via.ecp.fr/via/products/pygres.html>

  Pour un support :

  +o  Python :     newsgroup comp.lang.python

  +o  PostgresSQL  :  mailing  list  (see   package   documentation   for
     information)

  +o  PyGres95   :     contact  me  andre@via.ecp.fr  pour  des  rapports
     d'erreurs, des idees et des remarques

     J'essaierai de repondre dans la mesure ou mon  temps  libre  me  le
     permettra.

  2244..  PPaasssseerreellllee eennttrree PPoossttggrreeSSQQLL eett WWWWWW -- WWDDBB--PP9955

  WDB-P95   -   Une   interface  Web  interface  aux  bases  de  donnees
  PostgresSQL.  C'est a   <http://www.eol.ists.ca/~dunlop/wdb-p95/>

  Voici un extrait de la page d'accueil de WDB-P95 :-

  Version 1.4b2 beta - Creee par J. Douglas Dunlop

  A propos de wdb-p95

  C'est une version modifiee de wdb-1.3a2 qui fournit une passerelle WWW
  a  PostgresSQL.  Cette version necessite egalement un Butineur capable
  de prendre en compte les Tables HTML pour avoir  une  sortie  tabulee.
  Ceci  n'est  pas  requis pour le  wdb original et on peut facilement y
  revenir.  (Je voulais seulement les tables parce que  je  n'etais  pas
  d'accord avec les commandes < et >!)

  Vous  pouvez  essayer ma Bande CASI et ma Requete d'Image. Vous pouvez
  jeter un coup d'oeil au Fichier de Definition de Formulaire (FDF)  que
  j'ai utilise pour creer la Bande CASI et egalement la Requete d'Image,
  qui comprends une jointure (JOIN) de 2 tables.

  Cette version contient tous les fichiers necessaires pour installer et
  faire  tourner  WDB-P95  en  tant  qu'interface a vos bases de donnees
  PostgresSQL. Le portage de ce systeme pour une autre base  de  donnees
  devrait etre relativement facile - a condition qu'elle supporte le SQL
  standard et possede une interface Perl.

  2244..11..  LLee sseerrvveeuurr PPoossttggrreessSSQQLL,, ppggppeerrll,, eett  hhttttppdd  ddooiivveenntt--iillss  rreessiiddeerr
  ssuurr llee mmeemmee hhoottee??

  Non - Le serveur PostgresSQL n'a pas a etre sur le  meme  hote.  Comme
  WDB-P95  est appele par le demon http, ils doivent resider sur le meme
  hote. - Et comme WDB-P95 a ete ecrit pour utiliser Pg.pm - pgperl doit
  etre  sur  le  meme hote egalement. Pgperl a ete ecrit en utilisant la
  bibliotheque libpq, donc, il sera capable d'acceder a  n'importe  quel
  serveur  Postgres95  n'importe ou sur le reseau, juste comme n'importe
  quel autre client PostgresSQL. Comme illustre ci-dessous

  {WWW Client (Netscape)} => {HTTP Server  (NCSA's  http)  +  WDB-P95  +
  pgperl + libpq}=> {PostgresSQL server}

  Les parentheses () representent les machines.

  Chaque  machine  peut etre d'un type different : NT, SUN, HP, ... mais
  il faut que vous ayez la bibliotheque d'interface libpq pour  le  type
  de  machine  sur  lequel  vous envisagez d'utiliser WDB-P95, puisqu'il
  vous faut compiler pgperl.  (Le systeme a ete concu pour utiliser  les
  tables HTML donc un client WWW recent est meilleur)

  2244..22..  NNoouuvveellllee VVeerrssiioonn

  Les  nouvelles  versions  du  logiciel  et  des  pages  ci-dessus sont
  toujours disponibles  a  partir  de  la  page  d'Accueil  de  WDB-P95.
  <http://www.eol.ists.ca/~dunlop/wdb-p95/>

  Pour  les  questions  et  pour  s'inscrire  aux  listes  de  diffusion
  contacter dunlop@eol.ists.ca

  2255..  IInntteerrffaaccee aauu llaannggaaggee ""CC"" ppoouurr PPoossttggrreeSSQQLL

  Elle est incluse dans la distribution et s'appelle 'libpq'.  Elle  est
  similaire   aux  bibliotheques  OCI  Oracle,  DB-lib  Sybase,  ou  CLI
  Informix.

  2266..  IInntteerrffaaccee aauu llaannggaaggee ""CC++++"" ppoouurr PPoossttggrreeSSQQLL

  Elle est incluse dans la distribution et est nommee 'libpq++'.

  2277..  EESSQQLL//CC ppoouurr PPoossttggrreeSSQQLL

  C'est un pre-compilateur C integre pour PostgreSQL ESQL/C comme  Pro*C
  d'Oracle, et ESQL/C d'Informix :

  +o  <ftp://ftp.lysator.liu.se/pub/linus>

  +o  Email : linus@epact.se

  ESQL/C pour PostgreSQLest une interface de programmation d'application
  SQL (API) qui permet  au  programmeur  C  de  creer  des  applications
  personnalisees  avec  des  possibilites de gestion de base de donnees.
  ESQL/C pour PostgreSQL vous permet d'utiliser un langage de  troisieme
  generation  avec  lequel  vous  etes familiarise tout en profitant des
  avantages d'un Langage de Requetes Structure (SQL).

  ESQL/C est compose des elements logiciels suivants:

  +o  Les bibliotheques ESQL/C de fonctions C fournissent  les  acces  au
     serveur de base de donnees.

  +o  Les   fichiers  d'en-tete  ESQL/C  apportent  les  definitions  des
     structures de donnees, les constantes et les macros utiles dans  un
     programme ESQL/C.

  +o  Le pre-processeur ESQL/C, qui est un pre-processeur de code source,
     transforme un fichier C contenant des instructions SQL  en  fichier
     executable.

  2288..  OOppeerraatteeuurrss BBiitt--ppaarr--BBiitt ppoouurr PPoossttggrreeSSQQLL

  Les  operateurs  Bit-par-Bit  ont  ete  ecrits  par  Nicolas Moldavsky
  nico@overnet.com.ar

  Ce sont des fonctions "C" qui implantent  les  operateurs  bit-par-bit
  (AND,  OR,  XOR,  bit  complement) dans pgsql. Si quelqu'un desire les
  utiliser, il peut les recuperer par ftp anonyme de
  +o  <ftp://ftp.overnet.com.ar/pub/utils/linux/bitpgsql.tgz>

  De plus, il y a un "Makefile" qui marche bien sous Linux.

  2299..  LLeess CCooddeess KKaannjjii JJaappoonnaaiiss ppoouurr PPoossttggrreeSSQQLL

  Sont tres utiles pour les Japonais.  On les trouvera au site suivant :
  <ftp://ftp.sra.co.jp/pub/cmd/postgres/>

  3300..  PPoorrttaaggee ddee PPoossttggrreeSSQQLL ppoouurr WWiinnddoowwss 9955//WWiinnddoowwss NNTT

  Un portage pour Windows 95/Windows NT est en cours de realisation.  Ce
  portage de fait en utilisant  gcc, gmake pour Win NT/95. Le  programme
  gnu-win32  est  utilise  pour compiler le code source sous win32.  GNU
  gcc est disponible pour win32. Consultez ce site -

  +o  <http://www.cygnus.com/misc/gnu-win32>

     Recuperez-y le fichier cdk.exe (fichier auto-extractible pour  gnu-
     win32)

  Le   portage   peut  egalement  etre  realise  en  utilisant   l'outil
  "Emulateur Unix sous NT" (Unix-Emulator on NT) suivant de

  +o  <http://www.softway.com>

  3311..  LLiisstteess ddee DDiiffffuussiioonn eett GGrroouuppeess ddee DDiissccuussssiioonn

  3311..11..  NNeewwssggrroouuppss

  Il y a un groupe de discussion pour PostgreSQL  a  news.postgresql.org
  Veuillez suivre les etapes suivantes pour vous inscrire

       1. Choisir : Fenetre | Netscape News
       2. Choisir : Fichier | Open News Host
       3. Taper news.postgresql.org dans la boite 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 boite de dialogue. Le
       groupe de discussion sera ajoute a la liste dans l'ecran de gauche.
       5. Les noms des Groupes de Discussion seront listes dans l'ecran de gauche.
       Tous les messages, dans les groupes selectionnes, seront affiches dans
       l'ecran de droite.

  3311..22..  OObbtteenniirr uunn ccoommppttee ee--mmaaiill GGrraattuuiitt

  Regardez  les  offres  gratuites  - obtenez des comptes e-mail gratuit
  chez

  +o  Yahoo  <http://www.yahoo.com> cliquer sur e-mail

  +o  Lycos  <http://www.lycos.com> cliquer sur nouveaux comptes e-mail

  +o  hotmail  <http://www.hotmail.com> cliquer sur nouveaux  comptes  e-
     mail

     Inscrivez  vous a la liste de diffusion PostgreSQL et Yahoo dispose
     de la  fonctionnalite  complementaire  de  creation  d'un  classeur
     separe  pour  les courriers electroniques PostgreSQL e-mails, ainsi
     votre e-mail habituel ne sera  pas  pollue.  Selectionnez  le  menu
     Email-  >  Options-  > Filters et prenez un classeur separe pour e-
     mail.  Avec ce compte e-mail vous pouvez  acceder  au  courrier  de
     n'importe  ou dans le monde a partir du moment ou vous avez acces a
     une page web.

  Si vous disposez d'un autre  e-mail, vous pouvez utiliser les "Filtres
  de  Courrier"  pour  recevoir automatiquement les courriers PostgreSQL
  dans un dossier separe.  De  cette  facon,  les  choses  seront  mieux
  organisees et vous eviterez de voir votre courrier pollue.

  3311..33..  LLiissttee ddee DDiiffffuussiioonn AAnnggllaaiissee

  Regardez les Titres des Listes de Diffusion sur la page web principale
  a : <http://www.postgresql.org/>

  +o  Envoyez  vos  questions  par  courrier   electronique   a:   pgsql-
     questions@postgresql.org

  +o  Developpeurs pgsql-hackers@postgresql.org

  +o  Questions specifiques a un portage pgsql-ports@postgresql.org

  +o  Questions concernant la documentation pgsql-docs@postgresql.org

     Vous  recevrez  une  reponse,  par  courrier  electronique, dans la
     journee qui suit!!

  Vous pouvez egalement vous inscrire aux  listes  de  diffusion.   Pour
  vous inscrire ou vous radier d'une liste, envoyez un courrier a

  +o  pgsql-questions-request@postgresql.org

  +o  pgsql-hackers-request@postgresql.org

  +o  pgsql-ports-request@postgresql.org

  +o  pgsql-docs-request@postgresql.org

     Le corps du message doit uniquement contenir la simple ligne

  subscribe

  (ou)

  unsubscribe

  3311..44..  AArrcchhiivvee ddeess lliisstteess ddee ddiiffffuussiioonn

  Il y a aussi des listes de diffusion qui sont archivees au format html
  a l'endroit suivant -

  +o  <ftp://ftp.postgresql.org> dans le repertoire /pub/majordomo

  3311..55..  LLiissttee ddee DDiiffffuussiioonn EEssppaaggnnoollee

  Il y a maintenant  une  liste  "non  officielle"  pour  postgreSQL  en
  Espagnol.    Consultez  egalement  la  section  'Compte  gratuit  pour
  Organiser vos e-mails PostgreSQL e-mails' ci-dessus.  Pour  souscrire,
  l'utilisateur doit envoyer un message a :

  +o  majordomo@tlali.iztacala.unam.mx

     Le corps du message doit contenir la simple ligne :

  inscripcion pgsql-ayuda

  3322..  LLiivvrreess eett DDooccuummeennttaattiioonnss

  3322..11..  GGuuiiddeess uuttiilliissaatteeuurr eett MMaannuueellss

  On  trouve  dans  la  distribution  PostgreSQL aux formats et pages de
  manuel unix les documents suivants. Si vous avez acces  a  l'internet,
  vous    pouvez   trouver   les   documents   indiques   ci-dessous   a
  <http://www.postgresql.org/docs>

  +o  Le 'Guide Utilisateur' pour PostgreSQL,

  +o  Le 'Guide de Realisation' detaillant  la  constitution  interne  de
     PostgreSQL.

  +o  Les manuels "en ligne".

  +o  Le manuels en ligne au format HTML.

  +o  Egalement  les manuels au format Postscript pour faire des editions
     papier.

  3322..22..  DDooccuummeennttaattiioonn eenn lliiggnnee

  +o  Liste et description des types de donnees  et  des  operateurs  par
     defaut

       Cela fera partie des commandes PSQL dans la prochaine version 6.3.  Maintenant
       effectue.

  +o  Liste des mots-cles SQL supportes

       Il y a un script dans le repertoire /tools qui fait cela

  +o  Liste des instructions supportees -

       Utilisez la commande psql \h

  +o  Concepts   de   base  des  bases  de  donnees  relationnelles  sous
     PostgreSQL (en implementation) et des tonnes  d'exemples  en  ligne
     (requetes) -

       Consultez les tests de regression dans src/test. La, vous y trouver les
       repertoires regress/sql et suite/*.sql.

  +o  Didacticiel pour PostgreSQL.

       Les scripts du didacticiel SQL sont dans le repertoire src/tutorial

  Voir egalement "Didacticiel SQL pour les debutants" dans l'appendice C
  de ce document ``''

  3322..33..  DDooccuummeennttss ddee RReeffeerreennccee:: OOuuvvrraaggeess ddee rreeffeerreennccee uuttiilleess ::

  +o  "Understanding  the  New  SQL:  A  Complete  Guide"  (Comprendre le
     Nouveau SQL: Un Guide Complet)- par Jim Melton et Alan R.Simon

       Morgan Kaufman Publisher. C'est un des meilleurs livres sur SQL. Il
       concerne SQL92.

  +o  "A Guide to THE SQL STANDARD" (Un Guide  du  STANDARD  SQL)  -  par
     C.J.Date

       Addison-Wesley Publishing company. C'est egalement un bon livre. Tres
       populaire en ce qui concerne SQL.

  +o  SQL - The Standard Handbook, (Le Manuel Standard) November 1992

       Stephen Cannan and Gerard Otten
       McGraw-Hill Book Company Europe , Berkshire, SL6 2QL, England

  +o  SQL Instant Reference, (Reference Immediate SQL) 1993

  Martin Gruber, Technical Editor: Joe Celko
  SYBEX Inc.  2021 Challenger Drive Alameda, CA 94501

  +o  C.J.Date,  "An  introduction to Database Systems" (Une introduction
     aux Systemes de Bases de Donnees)  (6th  Edition),  Addison-Wesley,
     1995, ISBN 0-201-82458-2

       Ce livre est la Bible des Systemes de Gestion de Bases de Donnees.
       Ce livre detaille la normalisation, SQL, la recuperation, la concurrence,
       la securite, l'integrite, les extensions au modele relationnel original,
       des sujets actuels tels que  les systemes client/serveur et le(s) modele(s)
       Oriente(s) Objet. De nombreuses references sont donnees pour des lectures
       complementaires. Recommande pour la plupart des utilisateurs.

  +o  Stefan  Stanczyk,  "Theory  and  Practice of Relational Databases",
     (Theorie et pratique des bases de Donnees Relationnelles) UCL Press
     Ltd, 1990, ISBN 1-857-28232-9

       Ce livre detaille la theorie des bases de donnees relationnelles, l'algebre
       relationnelle, le calcul et la normalisation. Mais il ne couvre pas les sujets
       du mode reel et les exemples sont un peu simplistes. Recommande pour la plupart
       des utilisateurs.

  +o  "The  Practical  SQL  Handbook"  (Le  Manuel Pratique de SQL) Third
     Edition, Addison Wesley Developers Press ISBN 0-201-44787-8

       Recommande pour la plupart des utilisateurs.

  +o  Michael Stonebraker, "Readings in Database Systems"  (lectures  sur
     les  Systemes  de  Bases  de  Donnees), Morgan Kaufmann, 1988, ISBN
     0-934613-65-6

       Ce livre est un recueil de papiers, sur les bases de donnees, qui ont ete
       publies sur plusieurs annees. Il n'est pas pour l'utilisateur occasionnel
       mais, c'est reellement une reference pour les etudiants en classes superieures
       (troisieme cycle) ou pour les developpeurs de systemes de bases de donnees.

  +o  C.J.Date, "Relational  Database  -  Selected  Readings"  (Bases  de
     Donnees  Relationnelles  - Morceaux choisis), Addison-Wesley, 1986,
     ISBN 0-201-14196-5

  Ce livre est un recueil de papiers, sur les bases de donnees, qui ont ete
  publies sur plusieurs annees. Il n'est pas pour l'utilisateur occasionnel
  mais c'est reellement une reference pour les etudiants en classes
  superieures (troisieme cycle) ou pour les developpeurs de systemes de
  bases de donnees.

  +o  Nick  Ryan  and  Dan   Smith,   "Database   Systems   Engineering",
     (Ingenierie de Systemes de Bases de Donnees), International Thomson
     Computer Press, 1995, ISBN 1-85032-115-9

       Ce livre traite des details des methodes d'acces, et des technique de stockage.

  +o  Bipin  C.  Desai,  "An  introduction  to  Database  Systems",  (Une
     introduction aux systemes de bases de donnees) West Publishing Co.,
     1990, ISBN 0-314-66771-7

       Il n'est pas pour l'utilisateur occasionnel mais c'est reellement une
       reference pour les etudiants en classes superieures (troisieme cycle)
       ou pour les developpeurs de systemes de bases de donnees.

  +o  Joe Celko "INSTANT SQL Programming" (Programmation SQL IMMEDIATE)

       Wrox Press Ltd.
       Unit 16, 20 James Road, Tyseley
       Birmingham, B11 2BA, England
       1995

  +o  Michael Gorman  "Database  Management  Systems:  Understanding  and
     Applying  Database"  (Systemes  de  Gestion  de  Bases de Donnees :
     comprendre et appliquer les bases de donnees)

       Technology
       QED and John Wiley
       1991

  +o  Michael   Gorman   "Enterprise   Database   for   a   Client/Server
     Environment"  (Base  de  Donnees d'Entreprise pour un Environnement
     Client/Serveur) QED and John Wiley

  Presente les exigences de construction d'applications de base de donnees
  client/server par l'intermediaire de meta-modeles d'entrepot et l'utilisation
  de la norme SQL ANSI 1993

  Des  centaines  d'autres  titres  concernant  SQL  sont   disponibles!
  Verifiez-le dans une librairie.

  3322..44..  DDooccuummeennttss ddee SSppeecciiffiiccaattiioonnss AANNSSII//IISSOO SSQQLL -- SSQQLL 11999922,, SSQQLL 11999988

  Les documents de Specifications ANSI/ISO SQL sont situes  a  l'endroit
  indique ci-dessous.

  +o  <http://www.naiua.org/std-orgs.html>

  +o  <http://www.ansi.org/docs>  et  cliquez  sur  le fichier cat_c.html
     puis rechercher "Database SQL"

  +o  Standard  SQL92  <http://www.jcc.com> et  cliquez  sur  le  fichier
     sql_stnd.html

  +o  Specifications                     ANSI/ISO                     SQL
     <http://www.contrib.andrew.cmu.edu/~shadow/sql.html> Vous trouverez
     la Reference SQL ici.

  3322..55..  SSyynnttaaxxee ddee ll''AANNSSII//IISSOO SSQQLL 11999922

  Voir l'Appendice A de ce document ``''

  3322..66..  SSyynnttaaxxee ddee ll''AANNSSII//IISSOO SSQQLL 11999988

  Voir l'Appendice B de ce document ``''

  3322..77..  DDiiddaaccttiicciieell SSQQLL ppoouurr lleess ddeebbuuttaannttss

  Vois l'Appendice C de ce document ``''

  3322..88..  EExxtteennssiioonn TTeemmppoorreellllee aa SSQQLL9922

  +o  Document      pour      l'Extension     Temporelle     a     SQL-92
     <ftp://FTP.cs.arizona.edu/tsql/tsql2/>

  +o  Specification                   SQL-3                    Temporelle
     <ftp://FTP.cs.arizona.edu/tsql/tsql2/sql3/>

  Ce   repertoire   contient   les  specifications  pour  une  extension
  temporelle au langage SQL-92 standard. Ce nouveau langage  est  appele
  TSQL2.

  Les  specifications  du  langage  presentees  ici  correspondent  a la
  version finale du langage.

  La correspondance doit etre adressee au bureau du Comite de Conception
  du Langage TSQL2, Richard T.Snodgrass, Department of Computer Science,
  University of Arizona,  Tucson,  AZ  85721,  rts@cs.arizona.edu.   Les
  affiliations  et  les  adresses electroniques des membres du Comite de
  Conception du langage TSQL2 peuvent etre trouvees,  dans  un  chapitre
  separe, a la fin des specifications du langage.

  Le contenu du repertoire est le suivant :

  spec.dvi,.ps     Specifications du langage TSQL2, publie en Septembre,
  1994

  bookspec.ps      Specifications  du  langage  TSQL2,  telles  qu'elles
  apparaissent  dans le livre sur TSQL2, publie en Septembre, 1995 (voir
  ci-dessous).

  sql3            proposition de modification soumise au comites ANSI et
  ISO SQL3.

  Un  ensemble  de commentaires, associes aux specifications du langage,
  parle des decisions de conception, fournit des exemples, et traite  de
  la  facon dont le langage peut etre implante. Ces commentaires sont, a
  l'origine, des propositions faites au Comite de Conception du  Langage
  TSQL2. Ils poursuivent actuellement un objectif different: fournir des
  exemples de syntaxe, expliquer les nombreuses decisions prises  durant
  la  conception  du  langage,  et  comparer TSQL2 aux nombreuses autres
  propositions de langage faites au cours des quinze  dernieres  annees.
  Il  faut  insister sur le fait que ces commentaires ne font pas partie
  integrante des specifications  du  langage  TSQL2  en  lui-meme,  mais
  plutot  qu'elles  le completent et constituent un apport. Le mot de la
  fin est donne par les specifications de TSQL2 proprement dit.

  Les commentaires, ainsi que les specifications du  langage,  plusieurs
  index, et d'autres elements de support ont ete publies dans un livre :

  Snodgrass, R.T., editeur,  The  TSQL2  Temporal  Query  Language,  (Le
  Langage de  Requetes Temporel TSQL2) Kluwer Academic Publishers, 1995,
  674+xxiv pages.

  Les commentaires d'evaluation sont donnes sous forme abregee  dans  le
  livre;  La  totalite  des  commentaires  est  fournie  dans le fichier
  eval.ps situe dans ce repertoire

  Le fichier tl2tsql2.pl est un programme prolog qui traduit la  logique
  temporelle  autorisee  en  TSQL2. Ce programme a ete ecrit par Michael
  Boehlen boehlen@iesd.auc.dk Il peut  etre  contacte  pour  obtenir  un
  papier  qui  decrit  cette  traduction.  C'est une version tout a fait
  ancienne du programme.  Les  nouvelles  versions  sont  disponibles  a
  <http://www.cs.auc.dk/general/DBS/tdb/TimeCenter/Software> (the TimeDB
  and Tiger systems).

  3322..99..  PPaarrttiiee 00 -- AAccqquuiissiittiioonn ddeess DDooccuummeennttss IISSOO//AANNSSII SSQQLL

    Ce document vous explique comment acquerir (legalement) une copie de la norme
  SQL-92 et comment acquerir une copie du Brouillon de Travail du SQL3 "actuel".

    La norme ANSI est protegee par un copyright de l'ANSI, et la norme ISO par un
  copyright de l'ISO.

    Il y a deux (2) normes SQL courantes, une  publication ANSI et
    une publication ISO. Les deux normes sont identiques mot-pour-mot
    excepte pour quelques sujets triviaux tel que le titre du document, les
    en-tete de page, la phrase "International Standard" au lieu de "American
    Standard", et ainsi de suite.

                      Achat du Standard SQL-92

    La norme ISO, ISO/IEC 9075:1992, Information Technology - Database
    Languages - SQL, est actuellement (Mars, 1993) disponible et en stock a
    l'ANSI :

       American National Standards Institute
       1430 Broadway
       New York, NY 10018 (USA)
       Phone (sales): +1.212.642.4900

    au prix de US$230.00. La version ANSI, ANSI X3.135-1992, American
    National Standard for Information Systems - Database Language SQL, n'etait
    pas disponible en stock au moment de la redaction, mais il
    devrait l'etre entre fin Mars et debut Mai, 1993). Il devrait couter
    US$225.00.

    Si vous achetez l'un ou l'autre document a l'ANSI, il y aura un supplement
    de 7% pour le traitement (soit environ US$9.10). Les frais d'envoi a l'etranger
    accroitront sans doute le cout. ANSI exige des societes un document de commande
    ecrit pour chaque commande; d'un autre cote, vous pouvez envoyer un cheque
    tire sur une banque US en dollars US, qu'ils encaisseront avant d'expedier votre
    commande. (Il y a une exception : si votre organisation est membre de l'ANSI,
    alors l'ANSI enverra les documents et une facture a votre compagnie.)

    La norme ISO est aussi disponible en dehors des Etats-Unis a partir de
    representations nationales locales (entites de standardisation du pays)
    qui sont membres soit de l'ISO (International Organization for Standardization)
    soit de l'IEC (International Electrotechnical Commission). Des copies de la
    liste des representations nationales, avec leurs adresses, sont disponibles
    de l'ANSI ou d'autres entites nationales.
    Ils sont aussi disponibles a l'ISO :

       International Organization for Standardization
       Central Secretariat
       1, rue de Varembi
       CH-1211 Geneve 20
       Switzerland

    Si vous preferez commander la norme d'une facon plus facile et plus rapide, il
    vous faudra payer pour ce privilege. Vous pouvez commander le ISO/IEC
    9075:1992, Information Technology - Database Languages - SQL, a :

       Global Engineering Documents
       2805 McGaw Ave
       Irvine, CA 92714 (USA)
       USA
       Telephone (accessible de partout): +1.714.261.1455
       Telephone (uniquement aux USA): (800)854-7179

    pour un prix de US$308.00. Je ne sais pas si le port est compris ou non,
    mais je parierais que l'envoi international (au moins) sera en supplement.
    Ils peuvent vous envoyer un document tres rapidement et acceptent meme
    les "plus grandes cartes de credit". Global n'a pas encore la version ANSI
    pas plus qu'un prix ou qu'une date previsible de disponibilite (bien que je
    l'attende dans les quelques semaines suivant la publication par l' ANSI et a
    un prix aux alentours de US$300.00).

               Achat d'une copie du Document de Travail SQL3
    Vous pouvez acheter une copie du document de travail SQL3 au secretariat de l'ANSI X3,
    CBEMA (Computer and Business Equipment Manufacturers
    Association). Leur objectif est d'avoir la "plus recente" version du document de
    travail de SQL3 disponible et de la vendre pour environ US$60.00 a US$65.00.
    Vous pouvez contacter CBEMA a:

       CBEMA, X3 Secretariat
       Attn: Lynn Barra
       1250 Eye St.
       Suite 200
       Washington, DC 20005 (USA)

    Lynn Barra peut aussi etre contactee par telephone au +1.202.626.5738 pour une
    demande de copie, bien qu'un courrier soit probablement plus courtois.

             Acces Electronique au Document de Travail SQL3
    La plus recente version (a la date de redaction) du document de travail SQL3
    (a la fois ANSI et ISO, et de toutes ses parties) est disponible par
    "ftp anonyme" ou par "ftpmail" sur:

       gatekeeper.dec.com

    dans

       /pub/standards/sql/

    Dans ce repertoire , il y a de nombreux fichiers.  Ce sont des fichiers PostScript
    et "texte ordinaire" (pas tres bien formates, mais lisibles sur un ecran sans
    logiciel specifique).

    En general, vous pouvez trouver des fichiers avec des noms tels que :

       sql-bindings-mar94.ps
       sql-bindings-mar94.txt
       sql-cli-mar94.ps
       sql-cli-mar94.txt
       sql-foundation-mar94.ps
       sql-foundation-mar94.txt
       sql-framework-mar94.ps
       sql-framework-mar94.txt
       sql-psm-mar94.ps
       sql-psm-mar94.txt

    A mesure que de nouvelles versions des documents sont produites le "mar94" changera
    pour indiquer la nouvelle date de publication (e.g., "aug94" est la date attendue
    de la prochaine publication suivant "mar94").

    De plus, pour les lecteurs ne pouvant pas obtenir une liste de repertoire par FTP,
    nous avons ajoute un fichier ayant pour nom :

       ls

    dans le meme repertoire.  Ce fichier (surprise!) contient une liste du repertoire.

                 Recuperer les Fichiers Directement par Ftp

    Voici un exemple sur la facon d'utiliser FTP. Specifiquement, il montre comment
    se connecter a gatekeeper.dec.com, aller au repertoire ou le document de base
    est garde et a transferer ce document sur votre machine. Notez que votre machine doit
    pouvoir acceder a l'internet pour faire cela. Le nom de connexion est 'ftp' et le mot
    de passe est votre adresse e-mail (on appelle quelquefois cela 'ftp anonyme'). La
    commande 'type binaire' est utilisee pour s'assurer qu'aucuns bits ne seront supprimes
    du (des) fichier(s) recu(s). La commande 'get' recupere un fichier a la fois.
    Les commentaires dans le script ci-dessous sont places entre les signes <...>, <comme ceci>.

    % ftp gatekeeper.dec.com
    Connected to gatekeeper.dec.com.
    220- *** /etc/motd.ftp ***
         Gatekeeper.DEC.COM is an unsupported service of DEC Corporate Research.
         <...il en va ainsi pendant un certain temps...>
    220 gatekeeper.dec.com FTP server (Version 5.83 Sat ... 1992) ready.
    Name (gatekeeper.dec.com:<votre nom de connexion ici>): ftp  <anonyme fonctionne egalement>
    331 Guest login ok, send ident as password.
    Password: <entrez votre adresse e-mail ici>
    230 Guest login ok, access restrictions apply.
    Remote system type is UNIX.  <ou autre>
    Using binary mode to transfer files.
    ftp> cd pub/standards/sql
    250 CWD command successful.
    ftp> dir
    200 PORT command successful.
    150 Opening ASCII mode data connection for /bin/ls.
    total 9529
    -r--r--r--  1 root     system     357782 Feb 25 10:18 x3h2-93-081.ps
    -r--r--r--  1 root     system     158782 Feb 25 10:19 x3h2-93-081.txt
    -r--r--r--  1 root     system     195202 Feb 25 10:20 x3h2-93-082.ps
    -r--r--r--  1 root     system      90900 Feb 25 10:20 x3h2-93-082.txt
    -r--r--r--  1 root     system    5856284 Feb 25 09:55 x3h2-93-091.ps
    -r--r--r--  1 root     system    3043687 Feb 25 09:57 x3h2-93-091.txt
    226 Transfer complete.
    ftp> type binary
    200 Type set to I.
    ftp> get x3h2-93-082.txt
    200 PORT command successful.
    150 Opening BINARY mode data connection for x3h2-93-082.txt (90900 bytes).
    226 Transfer complete.
    90900 bytes received in 0.53 seconds (166.11 Kbytes/s)
    ftp> quit
    % <le fichier est maintenant dans votre repertoire sous le nom x3h2-93-082.txt>

             Recuperation de Fichiers Sans Faire un ftp Direct
    Digital Equipment Corporation, comme plusieurs autres compagnies, fournit un service de ftp
    par courrier electronique. La reponse peut prendre plusieurs jours, mais cela fournit
    un service equivalent a ftp pour ceux qui n'ont pas un acces direct au ftp par Internet.
    L'adresse du serveur est:

       ftpmail@decwrl.dec.com

    Le script suivant recuperera la derniere version PostScript du document SQL3 :

       reply joe.programmer@imaginary-corp.com
       connect gatekeeper.dec.com anonymous
       binary
       compress
    Le script suivant recuperera la derniere version PostScript du document SQL3 :

       reply joe.programmer@imaginary-corp.com
       connect gatekeeper.dec.com anonymous
       binary
       compress
       uuencode
       chdir /pub/standards/sql
       get x3h2-93-091.ps
       quit

    La premiere ligne du script commande au serveur de vous retourner les fichiers demandes;
    vous devrez remplacer "joe.programmer@imaginary-corp.com" par votre adresse Internet.
    Le fichier x3h2-93-091.ps, dans cet exemple, est retourne sous forme de 34 messages e-mail
    separes, "compresses" et "uuencodes". Si votre environnement ne dispose pas des outils
    pour reconstruire de tels fichiers, alors, il vous faudra recuperer le fichier sous forme
    de texte pur en utilisant le script suivant:

       reply joe.programmer@imaginary-corp.com
       connect gatekeeper.dec.com anonymous
       chdir /pub/standards/sql
       get x3h2-93-091.ps
       quit

    Mais, attention, le fichier .ps vous sera probablement envoye en plus de 70 morceaux!

    Pour recuperer un fichier particulier, autre que x3h2-93-091.ps, remplacez
    simplement "x3h2-93-091.ps" par le nom du fichier desire. Pour obtenir la liste
    de tous les fichiers disponibles dans un repertoire, remplacez "get x3h2-93-091.ps"
    par "dir".

  3322..1100..  PPaarrttiiee 11 -- EEttaatt AAccttuueell ddee ll''IISSOO//AANNSSII SSQQLL

  Ce chapitre constitue une source d'information a propos du processus de
  normalisation de SQL et de son etat actuel.

  ----------------------------------------------------------------------------
  Etat Actuel

  Le developpement pour ameliorer SQL afin d'en faire un langage complet
  pour la definition et la gestion d'objets persistants et complexes.
  Ceci comprend : les hierarchies de generalisation et de specialisation,
  l'heritage multiple, les types de donnees definies par l'utilisateur,
  les declencheurs et les assertions, le support des systemes a base de
  connaissances, les requetes recursives, et des outils complementaires
  d'administration de donnees. Cela inclue egalement la specification
  des types de donnees abstraits (ADTs), des identificateurs d'objets,
  des methodes, de l'heritage, du polymorphisme, de l'encapsulation et
  de tous les autres moyens normalement associes a la gestion d'objets.

  A l'automne 1996, plusieurs parties de SQL3 ont ete soumises a un vote
  de l'ISO CD. Ce sont SQL/Framework, SQL/Foundation et SQL/Bindings.
  Ce vote echoua (comme prevu) avec environ 900 commentaires. Fin Janvier,
  un comite de redaction traita un grand nombre de solutions aux problemes
  qui furent soit incluses avec les commentaires du vote ou soumises
  en tant que documents separes. Depuis le comite de redaction DBL n'a pas
  pu traiter tous les commentaires et sa duree a ete augmentee. La fin
  du comite de redaction est prevue pour la fin Juillet 1997, a Londres.

  A la suite du comite de redaction de Juillet, on attend qu'un vote final du CD
  soit demande pour ces parties de SQL. Le processus du CD Final prendra environ
  6 mois et un comite de redaction du DBL, apres lesquels il y aura un vote IS
  et un tres rapide vote IS.

  Les procedures ISO ont change depuis SQL/92, et les comites SQL travaillent
  encore selon les regles du processus.

  Si tout va bien, ces parties du SQL3 deviendront une norme officielle ISO/IEC
  en fin 1998, mais le programme est tres serre.

  En 1993, les comites de developpement ANSI et ISO ont decide de d'eclater le
  developpement futur de SQL en une norme multi-parties. Ces parties sont :

     * Partie 1: Structure Description non technique de la maniere dont le document
       doit etre structure.
     * Partie 2: Base Specifications de base, incluant toutes les nouvelles
       fonctionnalites ADT.
     * Partie 3: SQL/CLI Interface du niveau appel (Call Level Interface).
     * Partie 4: SQL/PSM Specifications des procedures enregistrees
     * Partie 5: SQL/Bindings SQL Dynamique et SQL Embedded SQL liens venant de
       SQL-92.
     * Partie 6: SQL/XA Une specialisation de l'interface populaire XA developpee
       par X/Open
     * Partie 7:SQL/Temporal Ajoute les capacites liees au temps a la norme SQL.

  Aux  USA, la totalite de SQL3 est en cours de traitement a la fois comme projet
  ("D") national et comme projet ISO. La fin de SQL3 est attendue pour courant 1999.

  Le SQL/CLI et le SQL/PSM sont en cours de traitement aussi rapidement que possible
  comme addenda a SQL-92. Aux USA, ils sont traites uniquement comme projet
  International. SQL/CLI a ete termine en 1995. SQL/PSM devrait etre termine
  fin 1996.

  En plus du travail sur SQL3, quelques projets additionnels sont poursuivis :

     * SQL/MM Un effort en cours pour definir une norme multi-media utilisant
       les possibilites de SQL3 ADT.
     * Acces aux donnees a distance (RDA)
  ----------------------------------------------------------------------------

  Comites et Processus de Standardisation
  Il y a effectivement de nombreux comites de normalisation de par le
  monde. Il y a un groupe international de normalisation SQL faisant
  partie de l'ISO. Un certain nombre de pays on des comites qui se consacrent
  a SQL. Ces pays (habituellement) envoient des representants aux reunions
  ISO/IEC JTC1/SC 21/WG3 DBL. Les pays qui participent activement au
  processus de normalisation ISO SQL sont :

     * Australie
     * Bresil
     * Canada
     * France
     * Allemagne
     * Japon
     * Koree
     * Pays-Bas
     * Angleterre
     * Etats-Unis

  ----------------------------------------------------------------------------

  Validation NIST

  Les implementations SQL sont validees (aux Etats-Unis) par le National
  Institute of Standards and Testing (NIST). Le NIST possede une suite de
  tests de validation pour le niveau de base SQL-92. Les details exacts
  des exigences de la validation NIST sont definis comme un Federal Information
  Processing Standard (FIPS). Les exigences actuelles pour SQL sont definies
  dans le document FIPS 127-2. Les versions Postscript et Texte de ce document
  peuvent etre obtenues au NIST. La Liste des Produits Valides a jour peut
  egalement etre obtenue au NIST.

  ----------------------------------------------------------------------------

  Publications et Articles sur le Standard SQL

  Il y a deux versions de la norme SQL. Les deux sont disponibles a l'ANSI:

     * ISO/IEC 9075:1992, "Information Technology --- Database Languages ---
       SQL"
     * ANSI X3.135-1992, "Database Language SQL"

  Les deux versions de la norme SQL sont identiques sauf la page de garde et
  les references aux autres normes. Les deux versions sont disponibles au :

     * American National Standards Institute
       1430 Broadway
       New York, NY 10018
       USA
       Telephone (ventes): +1.212.642.4900

  En supplement a la norme SQL-92, il y a maintenant un Technical Corrigendum (correction
  d'erreurs) :

     * Technical Corrigendum 1:1994 to ISO/IEC 9075:1992

  Le TC 1 doit aussi etre disponible a l'ANSI. Il n'y a qu'une version du TC
  1 -- qui s'applique a la fois aux versions ISO et ANSI de SQL-92.

  En supplement a ces normes, plusieurs livres ont ete ecrits sur la norme
  SQL 1992. Ces livrent donnent une description bien plus lisible de la norme
  que celle donnee par le norme elle-meme.

  ----------------------------------------------------------------------------
  Standards connexes

  Un certain nombre d'autres normes presentent de l'interet pour la
  communaute SQL. Cette section contient des pointeurs donnant des informations
  sur ces efforts. Ces pointeurs seront plus nombreux a mesure que des
  informations complementaires seront disponibles sur le web.

     * SQL Environnements (FIPS 193) - (Environnements SQL)
     * Next Generation Repository Systems (X3H4) - (Systemes Depositaires
       de la Prochaine Generation)
       Une version des Nouvelles appelant a une participation au
       "Developpement des Standards pour les Systemes Depositaires de la Prochaine Generation."
  ----------------------------------------------------------------------------

  3322..1111..  PPaarrttiiee 22 -- FFoonnddeemmeennttss IISSOO//AANNSSII SSQQLL

       Une partie importante de l'effort pour SQL3 reside dans le document de base SQL :

          * Capacites de Base SQL/PSM (venant de SQL/PSM-92)
          * Nouveaux types de donnees
          * Declencheurs
          * Sous-tables
          * Types de Donnees Abstraits (ADT)
          * Capacites Orientees Objets

       Il y a plusieurs pre-requis pour les capacites orientees objets :

          * Capacite de pouvoir definir des operations complexes
          * Stockage des operations complexes dans la base de donnees
          * Appels de Procedures Externes  Quelques operations peuvent ne pas
            exister dans SQL ou peuvent necessiter des interactions externes

       Ces capacites sont definies comme faisant partie de SQL/PSM

       Une grande quantite de travail est en cours de realisation pour affiner le modele
       objet SQL-3 et l'aligner sur le modele objet propose par l'ODMG. Cet effort est decrit
       dans les papiers X3H2 et ISO DBL : Accommoder SQL3 et ODMG. Une mise a jour
       recente sur le Fusionneur SQL3/OQL est egalement disponible.

       Planification de SQL3

       Le travail sur SQL3 se poursuit normalement, mais la publication de la norme finale se situe
       encore a un horizon de plusieurs annees.

          * Le vote International pour passer du Brouillon de Travail au Brouillon du Comite (CD)
            aura lieu a l'automne 1996.
          * On s'attend a ce que le vote genere de nombreux commentaires
          * Un second vote sera probablement necessaire
          * Le vote pour le Brouillon du Standard International devrait avoir lieu a la mi-1998
          * Le Standard International doit etre termine a la mi-1999.

       Le programme de la version ANSI sera similaire.

       ----------------------------------------------------------------------------

  3322..1122..  PPaarrttiiee 33 -- IInntteerrffaaccee dd''AAppppeell SSQQLL IISSOO//AANNSSII

       SQL/CLI est une interface de programmation d'appel pour les bases de donnees SQL.
       Il est concu pour acceder aux bases de donnees a partir d'applications fermees.
       CLI a, a l'origine, ete cree par un sous-comite du groupe SQL Access (SAG).
       Les specifications de SAG/CLI ont ete publiees, en 1992, en tant que specifications
       Microsoft Open DataBase Connectivity (ODBC) en 1992. En 1993, le SAG a soumis le CLI
       aux comites ANSI et ISO SQL. (Le groupe "SQL Access Group" a maintenant ete fusionne
       avec le consortium X/Open.)

       SQL/CLI fournit une norme internationale pour :

          * Un CLI dependant de l'implementation pour acceder aux bases de donnees SQL
          * Des outils Client-serveur pour acceder facilement a une base de donnees au moyen
            de Bibliotheques de Lien Dynamique
          * Supporter et encourager un riche ensemble d'outils Client-serveur

       Planification de SQL/CLI

       Le processus de normalisation de SQL/CLI se poursuit a une vitesse aveuglante.

          * SQL/CLI est un addendum a la norme SQL de 1992 (SQL-92)
          * Acheve comme norme ISO en 1995
          * ISO/IEC 9075-3:1995 Information technology -- Database languages -- SQL
            -- Partie 3: Call-Level Interface (SQL/CLI)
          * L'effort actuel porte sur l'ajout des fonctionnalites SQL3 a SQL/CLI
       ----------------------------------------------------------------------------

  3322..1133..  PPaarrttiiee 44 -- MMoodduulleess MMeemmoorriisseess PPeerrssiissttaannttss IISSOO//AANNSSII SSQQLL

  SQL/PSM etend SQL en ajoutant :

     * Des extensions de langage procedural
     * Des procedures memorisees multi-instructions
     * Des appels de procedures et de fonctions externes

  SQL/PSM apporte, en plus du fait d'etre un bon outil de developpement d'application,
  une base pour des fonctionnalites orientees objet dans SQL3.

  Procedures memorisees et multi-instructions

  Multi-instructions et procedures memorisees offrent une grande variete d'avantages
  dans un environnement client/serveur :

     * Performance - Puisqu'une procedure memorisee peut effectuer de multiples
       instructions SQL, les interactions sur le reseau, avec le client, sont reduites.
     * Securite - On peut donner a un utilisateur le droit d'appeler une procedure memorisee
       qui met a jour une table ou un ensemble de tables mais lui refuser le droit de
       mettre a jour les tables directement
     * Code partage - Le code d'une procedure memorisee n'a pas a etre reecrit ni re-teste
       pour chaque outil d'un client qui accede a la base de donnees.
     * Controle - Fournit un point unique de definition et de controle dans la logique de
       l'application.

  Extensions de Langage Procedural

  Le langage procedural ajoute la puissance d'un langage de programmation traditionnel a SQL
  grace a des instructions de controle de flot et a d'autres constructions utilisees en
  programmation.

  Instructions de controle de flot

     * If-then-else  (si-alors-sinon)
     * Instructions de boucle
     * Prise en compte de erreurs
     * Instruction de choix multiple (Case)
     * Blocks (Begin-End blocks)

  Les extensions de langage procedural comprennent d'autres constructions des langages de
  programmation :

     * Declaration des variables
     * Instructions d'affectation de valeur
     * Lecture de diagnostiques sur les processus et l'etat

  De plus, toutes les instructions SQL traditionnelles peuvent etre inclues dans de procedures
  multi-instructions.

  Appels de Fonctions et de Procedures externes

  Une fonctionnalite souvent mentionnee dans la liste des souhaits pour de
  nombreuses base de donnees et produits et qui est implementee dans quelques-uns,
  est la capacite de pouvoir augmenter les fonctionnalites du logiciel de base de donnees
  d'origine par des appels a des procedures externes ecrites par les utilisateurs.

     * Cela permet a un site ou a une application en particulier d'ajouter leurs propres
       fonctions base de donnees
     * Peuvent etre utilisees tout au long des applications bases de donnees

  Le benefice de cette capacite est de donner acces, pour la base de donnees (et, par la,
  aux applications base de donnees), a un riche ensemble de procedures et de fonctions
  trop nombreuses pour etre definies par un comite de normalisation.

  Planification de SQL/PSM

  SQL/PSM evolue rapidement :
     * SQL/PSM est un addendum a SQL-92
     * Un vote international pour faire passer SQL/PSM de Brouillon de Norme Internationale
       a Norme Internationale s'est acheve en fin janvier 1996.
     * Une reunion de travail en mai 1996 n'a pas apporte de solution a tous les commentaires
     * La poursuite de la reunion de travail du PSM est programmee du 30 septembre au
       4 octobre 1996
     * Le programme est serre, mais il y a des chances que le PSM le publie en 1996.
     * Sa designation officielle sera :
       ISO/IEC DIS 9075-4:199? Information technology -- Database languages --
       SQL -- Partie 4: SQL Persistent Stored Modules (SQL/PSM)
     * L'ajout du support de SQL/PSM dans les fonctionnalites de SQL3 est en bonne voie.

  ----------------------------------------------------------------------------

  3322..1144..  PPaarrttiiee 55 -- IISSOO//AANNSSII SSQQLL//LLiieennss

       Pour en faciliter l'acces, la description des liens avec le langage de
       programmation a ete mise dans un document separe. La version actuelle
       consiste simplement en un extrait concernant les liens dynamiques et
       integres de SQL-92.

       Un certain nombre de sujets concernant les liens avec le langage de
       programmation restent en suspens.

       Pour les langage de programmation traditionnels, il existe des transformations
       pour les types de donnees de SQL-92. Cependant, des transformations doivent
       etre definis entre les objets SQL et les variables des langages de
       programmation.

       Pour les langages orientes objets, la transformation doit etre definie
       pour les types de donnees courants SQL et entre le modele objet SQL et le
       modele objet du langage oriente objet.

       Le modele objet doit se stabiliser avant de resoudre ces problemes.

       Les liens avec le langage feront partie integrante de SQL3.

       ----------------------------------------------------------------------------

  3322..1155..   PPaarrttiiee  66 -- IInntteerrffaaccee ddee SSppeecciiaalliissaattiioonn ((SSQQLL//XXAA)) IISSOO//AANNSSII SSQQLL
  XXAA))

  Cette specification devrait normaliser l'interface de programmation
  d'application (API) entre un Gestionnaire de Transaction global et
  le Gestionnaire de Ressources SQL. Il devrait normaliser les appels de
  fonction, en s'appuyant sur la semantique de l'ISO/IEC 10026,
  "Distributed Transaction Processing", qu'un Gestionnaire de Ressources SQL
  devrait supporter pour la validation en deux phases. Le document de
  base est derive d'une publication de l'X/Open, avec sa permission, qui
  specifie explicitement les parametres d'entree, de sortie et la semantique,
  en termes de types de donnees SQL, pour les fonctions suivantes :
  xa_close, xa_commit, xa_complete, xa_end, xa_forget,
  xa_open, xa_prepare, xa_recover, xa_rollback, et xa_start.

  ISO essaye actuellement de coller aux specifications XA de l'X/Open. Ce
  processus de suivi, au plus pres, consiste a adopter les specifications
  de l'industrie sans changements. Le vote pour l'XA a l'ISO SC21, JTC 1
  a debute le 27 avril 1995 et se termine le 27 octobre 1995. Si les
  specifications XA sont approuvees par 75% des votants, et par 2/3 des membres
  participants de JTC 1, cela deviendra une Norme Internationale. Si le vote est
  approuve, SQL/XA pourrait devenir une norme en 1996.
  ----------------------------------------------------------------------------

  3322..1166..  PPaarrttiiee 77 -- IISSOO//AANNSSII SSQQLL TTeemmppoorreell

  Le SQL Temporel traite des donnees en relation avec le temps. Conceptuellement,
  cela consiste a dire qu'il est utile d'aller chercher des donnees pour decouvrir
  l'allure qu'elles avaient a un certain moment. L'origine du SQL Temporel reside
  dans un papier de decembre 1994 de Rick Snodgrass qui en decrivait les concepts.

  X3 Annonce l'Approbation d'un Nouveau Projet, ISO/IEC 9075 Partie 7 :
  SQL/Temporel est un communique de presse concernant le SQL/Temporel.

  ----------------------------------------------------------------------------
                                  SQL Temporel
                                  ************
  Rick Snodgrass (President du comite TSQL2)
  31-Dec-1994

  Plusieurs personnes se sont pose la question de la necessite de la prise en
  charge de la gestion du temps dans SQL3 (comme cela a ete propose par DBL RIO-75,
  demandant qu'une nouvelle partie de SQL prenne en charge les bases de donnees
  temporelles). Le sentiment est que les types de donnees abstraits (ADT) sont
  suffisants pour gerer les questions de temps. Dans ce papier, je demontre,
  par des exemples concrets, que l'utilisation de colonnes typees, avec des
  types de donnees abstraits, est inadaptee pour des requetes temporelles.
  En particulier, beaucoup de requetes temporelles courantes sont soit
  difficiles a simuler en SQL, soit necessitent d'integrer SQL dans un langage
  procedural. Des solutions alternatives sont exposees dans TSQL2, une extension
  temporelle a SQL-92.

  1. INTRODUCTION

  La prise en charge d'un instant de validite va au-dela de celle de types de
  donnees temporels abstraits (ADT temporel). Avec ce dernier, on specifie
  qu'une colonne sera celle consacree au domaine temporel, tel que la DATE
  ou un INTERVALLE (je donnerai des exemples bientot). Avec un instant de validite,
  les lignes d'une table varient en fonction du temps, refletant les modifications
  de la realite. Le timbre dateur associe a une ligne d'une table a instant de
  validite est interprete par le langage d'interrogation comme l'instant ou
  la combinaison des valeurs dans les colonnes d'une ligne etait valide.
  Ce timbre dateur implicite permet d'exprimer des requetes de maniere
  simple et intuitive.

  2. ETUDE DE CAS

  2.1 ENREGISTREMENT DE L'INFORMATION COURANTE

  Le bureau du personnel (BP) salarie de l'universite de l'Arizona possede un certain
  nombre d'informations, dans une base de donnees, dont le nom de chaque employe,
  son salaire actuel ainsi que son titre. On peut representer cela dans une simple
  table.

          Employee(Name, Salary, Title)

  Etant donne cette table, retrouver le salaire d'un employe est une operation aisee.

          SELECT Salary

          FROM Employee

          WHERE Name = 'Bob'

  Maintenant, le BP souhaite enregistrer les dates de naissance. Pour ce faire, on ajoute
  une colonne a la table, ce qui donne le schema suivant.

          Employee(Name, Salary, Title, DateofBirth DATE)

  Retrouver la date de naissance d'un employe est analogue a retrouver son salaire.

          SELECT DateofBirth
          FROM Employee

          WHERE Name = 'Bob'

  2.2 ENREGISTREMENT DE L'INFORMATION HISTORIQUE

  Le BP souhaite informatiser l'historique de l'emploi. Pour ce faire,
  ils ajoutent deux colonnes, l'une pour indiquer quand l'information
  contenue dans le ligne est devenue valide, l'autre indiquant la fin
  de validite de cette information.

  Employee (Name, Salary, Title, DateofBirth, Start DATE, Stop DATE)

  Pour le modele de donnees, ces nouvelles colonnes sont identiques a
  la date de naissance. Cependant, leur presence a des consequences
  a grande echelle.

  2.3 PROJECTION

  Pour trouver le salaire actuel d'un salarie, les choses sont plus
  difficiles.

          SELECT Salary

          FROM Employee

          WHERE Name = 'Bob' AND Start <= CURRENT_DATE AND CURRENT_DATE <= Stop

  Cette requete est plus compliquee que la precedente. Le coupable se situe, de
  toute evidence, dans ces deux nouvelles colonnes. Le BP veut fournir a chaque
  employe l'historique de leur salaire. Pour chaque personne, specifiquement,
  il est necessaire de determiner les intervalles correspondants a chacun des
  salaires. Malheureusement, cela n'est pas possible en SQL. Un employe peut
  avoir un nombre arbitraire de changements de titre entre deux changements
  de salaire.

  Name    Salary  Title             DateofBirth   Start           Stop

  ----    ------  -----             -----------   -----           ----

  Bob     60000   Assistant Provost 1945-04-09    1993-01-01      1993-05-30

  Bob     70000   Assistant Provost 1945-04-09    1993-06-01      1993-09-30

  Bob     70000   Provost           1945-04-09    1993-10-01      1994-01-31

  Bob     70000   Professor         1945-04-09    1994-02-01      1994-12-31

                                 Figure 1

  Notez qu'il y a trois lignes pour lesquelles le salaire de Bob reste constant a
  $70,000. De la, le resultat sera de deux lignes pour Bob.

  Name    Salary  Start           Stop

  ----    ------  -----           ----

  Bob     60000   1993-01-01      1993-05-30

  Bob     70000   1993-06-01      1994-12-31

  Une alternative est de donner a l'utilisateur une edition des informations Salaire
  et Titre, et de laisser l'utilisateur determiner quand son salaire a change. Cette
  alternative n'est ni tres attirante ni tres realiste. Une seconde alternative est
  d'utiliser SQL autant que possible.

  CREATE TABLE Temp(Salary, Start, Stop)

  AS      SELECT Salary, Start, Stop

          FROM Employee;

  repeter

          UPDATE Temp T1

          SET (T1.Stop) = (SELECT MAX(T2.Stop)

                           FROM Temp AS T2

                           WHERE T1.Salary = T2.Salary AND T1.Start < T2.Start

                                  AND T1.Stop >= T2.Start AND T1.Stop < T2.Stop)

          WHERE EXISTS (SELECT *

                        FROM Temp AS T2

                        WHERE T1.Salary = T2.Salary AND T1.Start < T2.Start

                                  AND T1.Stop >= T2.Start AND T1.Stop < T2.Stop)

          jusqu'a ce qu'aucune ligne ne soit mise a jour;

  DELETE FROM Temp T1

  WHERE EXISTS (SELECT *

                FROM Temp AS T2

                WHERE T1.Salary = T2.Salary

                          AND ((T1.Start > T2.Start AND T1.Stop <= T2.Stop)

                          OR (T1.Start >= T2.Start AND T1.Stop < T2.Stop))

  La boucle trouve des intervalles qui se chevauchent ou sont adjacents et,
  doivent donc etre fusionnes. La boucle est executee log N fois dans le pire
  des cas, ou N est le nombre de lignes dans une chaine de lignes de valeur
  equivalente qui se chevauchent ou sont adjacentes. Le lecteur peut simuler
  cette requete sur la table de l'exemple pour se convaincre de sa verite.

  Une troisieme alternative consiste a utiliser SQL uniquement pour ouvrir un
  curseur sur la table. Une liste chainee de periodes est entretenue, chacune
  avec un salaire. La liste chainee doit etre initialisee vide.

  DECLARE emp_cursor CURSOR FOR

          SELECT Salary, Title, Start, Stop

          FROM Employee;

  OPEN emp_cursor;

  boucle:

          FETCH emp_cursor INTO :salary, :start, :stop;

          si pas-de-donnees est retourne alors aller a fin;

          trouver la position dans la liste chainee pour inserer cette information;

          aller a boucle;

  fin:

  CLOSE emp_cursor;

  Repeter tout au long de la liste chainee, edition des dates et des salaires

  La liste chainee peut ne pas etre necessaire au cas ou le curseur est ORDER BY
  Start.

  Dans tous les cas, la requete, tout ce qu'il y a de naturelle, est tout a fait
  difficile a exprimer en utilisant les possibilites offertes par SQL-92. La requete
  est triviale en TSQL2.

          SELECT Salary

          FROM Employee

  2.4 JOINTURE

  Une approche plus drastique consiste a eviter le probleme d'extraction de l'historique
  du salaire en reorganisant le schema pour separer les informations de salaire, de titre,
  et de date de naissance (dans ce qui suit, nous ignorerons la date de naissance pour
  raison de simplicite).

          Employee1 (Name, Salary, Start DATE, Stop DATE)

          Employee2 (Name, Title, Start DATE, Stop DATE)

  La table Employee1 est la suivante.

  Name    Salary  Start           Stop

  ----    ------  -----           ----

  Bob     60000   1993-01-01      1993-05-30

  Bob     70000   1993-06-01      1993-12-31

  Voici un exemple de la table Employee2.

  Name    Title                   Start           Stop

  ----    ------                  -----           ----

  Bob     Assistant Provost       1993-01-01      1993-09-30

  Bob     Provost                 1993-10-01      1994-01-31

  Bob     Professor               1994-02-01      1994-12-31

  Avec cette modification, aller chercher l'information de salaire d'un employe
  devient maintenant facile.

          SELECT Salary, Start, Stop

          FROM Employee1

          WHERE Name = 'Bob'

  Mais qu'en est-il si le BP veut une table des salaires, des intervalles de
  titre (c'est-a-dire, supposons que le BP veuille qu'une table soit calculee
  dans la forme de la Figure 1)? Une alternative est d'editer les deux tables,
  et de laisser l'utilisateur en calculer les combinaisons. Une seconde
  alternative est d'utiliser entierement SQL. Malheureusement, cette requete
  doit faire une etude de cas sur la maniere dont chaque ligne de Employee1 se
  chevauche avec chaque ligne de Employee2; il y a quatre cas possibles.

  SELECT Employee1.Name, Salary, Dept, Employee1.Start, Employee1.Stop

  FROM Employee1, Employee2

  WHERE Employee1.Name = Employee2.Name

       AND Employee2.Start <= Employee1.Start AND Employee1.Stop < Employee2.Stop

  UNION

  SELECT Employee1.Name, Salary, Dept, Employee1.Start, Employee2.Stop

  FROM Employee1, Employee2

  WHERE Employee1.Name = Employee2.Name

       AND Employee1.Start >= Employee2.Start AND Employee2.Stop < Employee1.Stop

          AND Employee1.Start < Employee2.Stop

  UNION

  SELECT Employee1.Name, Salary, Dept, Employee2.Start, Employee1.Stop

  FROM Employee1, Employee2

  WHERE Employee1.Name = Employee2.Name

       AND Employee2.Start > Employee1.Start AND Employee1.Stop < Employee2.Stop

          AND Employee2.Start < Employee1.Stop

  UNION

  SELECT Employee1.Name, Salary, Dept, Employee2.Start, Employee2.Stop

  FROM Employee1, Employee2

  WHERE Employee1.Name = Employee2.Name

       AND Employee2.Start > Employee1.Start AND Employee2.Stop < Employee1.Stop

  Prendre en compte tous les cas constitue une tache qui releve du challenge. En TSQL2, realiser
  une jointure temporelle correspond simplement a ce que l'on peut esperer.

          SELECT Employee1.Name, Salary, Dept

          FROM Employee1, Employee2

          WHERE Employee1.Name = Employee2.Name

  2.5 AGREGATS

  Maintenant, on demande au BP quel est le salaire maximum ? Avant d'ajouter les
  donnees de temps, c'etait facile.

          SELECT MAX(Salary)

          FROM Employee

  Maintenant que l'historique du salaire est enregistre, nous obtiendrons quelque chose
  comme l'historique du salaire maximum a travers le temps. Le probleme est que,
  naturellement, SQL ne fournit pas d'agregats temporels. Le moyen simple de realiser
  cela consiste a editer l'information, et a chercher, a la main, le maximum. Une
  alternative consiste a etre plus astucieux et a convertir l'instantane de la
  requete agregee en une requete non agregee, puis a convertir le resultat en
  requete temporelle. La requete non agregee retrouve les salaires pour lesquels
  un salaire plus eleve n'existe pas.

          SELECT Salary

          FROM Employee AS E1

          WHERE NOT EXISTS (SELECT *

                            FROM Employee AS E2

                            WHERE E2.Salary > E1.Salary)

  Convertir cette requete en une requete temporelle est loin d'etre evident. Ce qui
  suit constitue une approche possible.

  CREATE TABLE Temp (Salary, Start, Stop)

  AS      SELECT Salary, Start, Stop

          FROM Employee;

  INSERT INTO Temp

          SELECT T.Salary, T.Start, E.Start

          FROM Temp AS T, Employee AS E

          WHERE E.Start >= T.Start AND E.Start < T.Stop AND E.Salary > T.Salary;

  INSERT INTO Temp

          SELECT T.Salary, T.Stop, E.Stop

          FROM Temp AS T, Employee AS E

          WHERE E.Stop > T.Start AND E.Stop <= T.Stop AND E.Salary > T.Salary;

  DELETE FROM Temp T

  WHERE EXISTS (SELECT *

                FROM Employee AS E

                WHERE ((T.Start => E.Start AND T.Start < E.Stop)

                          OR (E.Start >= T.Start AND E.Start < T.Stop))

                      AND E.Salary > T.Salary;

  Cette approche cree une table auxiliaire. Nous ajoutons a cette table la
  periode inferieure soustraite d'une periode et la partie superieure
  soustraite d'une periode. Nous supprimons alors toutes les periodes
  qui se chevauchent avec une ligne definie dans la sous-requete, de ce fait
  realisant le NOT EXISTS(n'existe pas). Finalement nous generons a partir
  de la table auxiliaire les periodes maximales, de la meme facon que
  l'information de salaire avait ete calculee ci-dessus. Comme on peut
  l'imaginer, un tel code SQLest extremement inefficace a l'execution,
  compte tenu des requetes complexes imbriquees contenant des predicats
  d'inegalite.

  Une troisieme alternative consiste a utiliser le moins possible SQL, et plutot
  de calculer le maximum desire dans un langage hote en utilisant des
  curseurs.

  La requete en TSQL2 est de nouveau simple et intuitive.

          SELECT MAX(Salary)

          FROM Employee

  3. RESUME

  Dans la plupart des applications de base de donnees on manipule des donnees
  qui changent en fonction du temps. La prise en compte de l'instant de validite
  est absente de SQL. Beaucoup de requetes temporelles ordinaires sont
  difficiles a simuler en SQL, ou requierent du SQL integre dans un langage
  procedural, ceci etant du au manque de support des tables avec instant
  de validite dans son modele de donnees et dans la structure des requetes.

  Ailleurs, nous avons montre que l'ajout du support de l'instant de validite
  ne requiert que peu de modifications dans l'implementation des SGDB, peut
  radicalement simplifier un certain nombre de requetes et en permettre d'autres,
  et peut, plus tard, permettre des optimisations dans les structures de
  memoires, les methodes d'indexation et les strategies d'optimisation
  qui peuvent entrainer des ameliorations notables dans les performances.

  Avec une nouvelle partie de SQL3 supportant les informations qui varient avec
  le temps, permettant une meilleure gestion des donnees temporelles par SQL3,
  nous pouvons commencer a apporter une reponse a de telles application.

  ----------------------------------------------------------------------------
             Comite de Normalisation Accredite* X3, Technologie de L'Information
  COMMUNIQUE

  Doc. No.:       PR/96-0002

  Reply to:       Barbara Bennett at bbennett@itic.nw.dc.us

               X3 Annonce l'approbation d'un Nouveau Projet, ISO/IEC

                           9075 Partie 7:  SQL/Temporal

  Washington D.C., Janvier 1996 -- Le Comite de Normalisation Accredite

  X3, Technologie de l'Information, annonce l'approbation d'un nouveau

  projet concernant le support de SQL/Temporel , ISO/IEC 9075 Partie 7, le

  travail devant etre realise au sein du Comite Technique X3H2, Bases de Donnees.

  Cette proposition de norme concerne un nouvelle partie de la norme naissante

  SQL3, e.g., Partie 7, SQL Temporel, et specifie les extensions au langage

  SQL pour gerer le stockage, l'extraction et la manipulation des donnees

  temporelles dans un environnement de base de donnees SQL.

  La prochain reunion du comite X3H2 est planifie pour la periode du 11 au

  14 Mars 1996 dans le Kansas.

  Les questions concernant ce projet doivent etre envoyees au president de

  X3H2, Dr. Donald R. Deutsch, Sybase, Inc., Suite 800, 6550 Rock Spring

  Drive, Bethesda, MD  20817.  Email: deutsch@sybase.com.

  Un appel initial pour de possibles brevets ou autres sujets pertinents

  (copyrights, trademarks) est sur le point d'etre emis. Soumettez, s'il vous plait,

  les informations a ce propos au secretariat de X3 a 1250 Eye Street

  NW, Suite 200, Washington DC  20005. Email: x3sec@itic.nw.dc.us

  FAX:  (202)638-4922.

  ----------------------------------------------------------------------------

  X3 Press Index

  X3 Home Page

  3322..1177..  PPaarrttiiee 88 -- SSQQLL MMUULLTTIIMMEEDDIIAA IISSOO//AANNSSII ((SSQQLL//MMMM))

  Un nouveau projet international de normalisation ISO/IEC pour le
  developpement d'une bibliotheque de classe SQL pour les applications
  multi-media a ete approuve debut 1993. Cette nouvelle activite de
  normalisation, appelee SQL Multi-media (SQL/MM), specifiera les paquetages
  de definition de types de donnees abstraites SQL (ADT) en utilisant les
  fonctions fournies dans les specifications SQL3 naissantes pour ADT.
  SQL/MM a pour objectif de normaliser des bibliotheques de classes pour
  la science et l'ingenierie, le traitement des textes et des documents,
  ainsi que des methodes pour la gestion d'objets multi-media tels que
  les images, les sons, les animations, la musique et la video. Il fournira
  vraisemblablement un lien entre le langage SQL et les objets multi-media
  definis par les autres entites de normalisation du JTC1 (e.g. SC18 pour
  les documents, SC24 pour les images, et SC29 pour les photographies et
  les images animees).

  Le Plan du Projet pour SQL/MM prevoit que ce sera une norme multi-parties
  dont le nombre de parties pourra evoluer. La partie 1 consistera en un
  cadre specifiant comment les autres parties doivent etre architecture.
  Chacune de ces autres parties sera consacree a un paquetage d'application SQL
  specifique. En aout 1994, la structure existante etait la suivante :

     * Partie 1: Cadre - Description non technique de la maniere dont le document
       est structure.
     * Partie 2: Methodes pour le Texte et ADT (types de donnees abstraits) pour
       le traitement des textes. Environ 45 pages.
     * Partie 3: Methodes Spatiales et ADT pour la gestion des donnees spatiales
       Environ 200 pages avec l'active contribution d'experts en Donnees Spatiales
       de 3 entites nationales.
     * Partie 4: Methode a Usage General et ADT pour les nombres complexes,
       et des fonctionnalites incluant la trigonometrie et les fonctions exponentielles
       les vecteurs, les ensembles etc.
       Actuellement environ 90 pages.

  On assiste a des efforts de normalisation dans le domaine des informations
  Spatiales et Geographiques :

     * ANSI X3L1 - Systemes d'Information Geographique.
       Mark Ashworth de Unisys est charge de la liaison entre X3L1 et ANSI X3H2. Il est
       egalement le redacteur des parties 1, 3, and 4 du brouillon de SQL/MM.
     * ISO TC 211 - Information geographique/Geomatique.

  ----------------------------------------------------------------------------

  3333..  SSuuppppoorrtt TTeecchhnniiqquuee ppoouurr PPoossttggrreeSSQQLL

  Si  vous  avez  des  questions  techniques  ou  si vous rencontrez des
  problemes vous pouvez envoyer un  courrier  electronique  a  :  pgsql-
  questions@postgresql.org  et  vous  recevrez par courrier electronique
  une reponse dans la journee qui suit.  Comme  le  nombre  de  produits
  internet  est  tres  large,  et que les utilisateurs aident les autres
  utilisateurs, internet est capable d'apporter  facilement  un  support
  technique  a  des millions d'utilisateurs. Le support par Email est de
  loin beaucoup plus adapte que celui effectue par telephone car on peut
  recuperer  les  messages  d'erreur, les sorties de programme etc... et
  les transmettre facilement dans les listes de diffusion ou les forums.

  Dans  un  futur  proche,  l'organisation  PostgreSQL vendra un support
  technique aux petites et grandes  compagnies,  les  revenus  de  cette
  activite  serviront  a entretenir plusieurs sites miroirs (web et ftp)
  partout dans le monde. Ces revenus pourront aussi servir a  creer  une
  documentation imprimee, des guides, des livres pour aider les clients.
  Les   profits   seront   egalement   utilises   a    construire    des
  immeubles/salles  de  classe  et  a  offrir  des  cours techniques sur
  l'administration et la gestion des bases de donnees et a organiser des
  conferences  annuelles  pour  les  utilisateurs.   Ceci  devrait aider
  l'organisation PostgreSQL a se debrouiller toute seule.

  Vous pouvez aussi  vous  faire  aider  par  des  societes  de  conseil
  professionnelles telles que Anderson, WGS (Work Group Solutions). Pour
  de l'aide, contactez les a -

  +o  Work Group Solutions  <http://www.wgs.com>

  +o  Anderson Consulting  <http://www.ac.com>

  3344..  AAssppeeccttss EEccoonnoommiiqquueess eett CCoommmmeerrcciiaauuxx

  Les bases de donnees commerciales paient de  nombreuses  taxes  telles
  que  des taxes federales, d'etat, sur les ventes, sur les salaries, la
  securite sociale, les taxes pour les soins  medicaux,  des  indemnites
  pour  les  employes,  des couts de marketing et de publicite. Tous ces
  couts ne sont pas destines directement au developpement de la base  de
  donnee.  Quand vous achetez une base de donnees commerciale une partie
  du montant est  destine  aux  taxes,  aux  depenses  de  recherche  et
  developpement  (  R&D ). Donc la valeur reelle pour la base de donnees
  est beaucoup plus faible.

  De plus les bases de donnees commerciales  doivent  payer  pour  leurs
  immeubles/biens et pour l'achat de machines Unix, leur installation et
  leur maintenance. Tous ces couts sont repercutes sur les clients.

  PostgreSQL possede l'avantage, sur les bases de donnees  commerciales,
  de  ne  pas  supporter  de taxes puisque developpee sur l'internet. Un
  tres grand nombre de personnes contribuent a  son  developpement.  Par
  exemple, cas hypothetique, s'il y a un million de compagnies aux U.S.A
  et que chacune contribue pour environ $ 10 (en valeur de logiciel pour
  PostgreSQL)  alors, chaque compagnie recevra dix millions de dollars!!
  C'est cela la magie du developpement sur internet.

  Actuellement, le code source de PostgreSQL est constitue d'environ 200
  000  lignes  de  code "C" et "C++". Si le cout de chaque ligne de code
  "C" est evalue a $ 10, alors le cout total de  PostgreSQL,  tel  qu'il
  est aujourd'hui est de $ 2 000 000 (deux millions de dollars!!).

  De  nombreuses  compagnies  ont deja developpe de grandes quantites de
  code "C", "C++" maison. Donc, en prenant le code source de  PostgreSQL
  et  en  collaborant avec les autres compagnies sur internet, cela leur
  beneficierait beaucoup en leur faisant  economiser  du  temps  et  des
  efforts.

  3355..  LLiissttee ddeess aauuttrree BBaasseess ddee DDoonnnneeeess

  On  trouvera  ci-dessous la liste des autres bases de donnees SQL pour
  Unix, Linux.

  +o  Cliquez       et       allez       a       Applications->databases.
     <http://www.caldera.com/tech-ref/linuxapps/linapps.html>

  +o  Cliquez       et       allez       a       Applications->databases.
     <http://www.xnet.com/~blatura/linapps.shtml>

  +o  Ressources pour Bases de Donnees <http://linas.org/linux/db.html>

  +o  Liste       des        Bases        de        Donnees        libres
     <http://cuiwww.unige.ch:80/~scg/FreeDB/FreeDB.list.html>

  +o  Liste des SGBDR de Browne <http://www.hex.net/~cbbrowne/rdbms.html>
     ecrit par Christopher B. Browne cbbrowne@hex.net

  +o  Liste des SGBDR de SAL <http://SAL.KachinaTech.COM/H/1/>

  +o  Liste      des      SGBD      Orientes      Objets      de      SAL
     <http://SAL.KachinaTech.COM/H/2/>

  +o  Liste     des    Utilitaires    et    d'Autres    SGDB    de    SAL
     <http://SAL.KachinaTech.COM/H/3/>

  +o  Index des Logiciels de Base de Donnees  Publics   de  l'ACM  SIGMOD
     <http://bunny.cs.uiuc.edu/sigmod/databaseSoftware/>

  3366..  IInnddiiccaattiioonnss ppoouurr llaa rreecchheerrcchhee ssuurr llee WWoorrlldd WWiiddee WWeebb IInntteerrnneett

  Internet est immense, recele un tres grand nombre de logiciels  et  un
  ocean  d'informations.  Il  s'accroit  a la vitesse de 500% par an. On
  estime le nombre de sites Web a  environ  90  million  dans  le  monde
  entier!

  Utilisez  des  moteurs  de  recherche  tels  que  "Yahoo", "Netscape",
  "Lycos" etc. pour trouver une information. Allez sur Yahoo, et cliquez
  sur  recherche.  Utilisez  les  options  de  filtrage pour affiner vos
  criteres de recherche. La methode de recherche par defaut consiste  en
  une "recherche intelligente" qui est plus generale et donne toutes les
  possibilites. Cliquez sur "Options" et selectionnez la  recherche  par
  "EXACT  phrase"  , par "AND" , par "OR" , etc... De cette maniere vous
  trouverez l'information que vous cherchez beaucoup plus rapidement.

  3377..  CCoonncclluussiioonn

  Apres avoir cherche toutes les bases de donnees disponibles qui soient
  libres  et  dont  le code source soit disponible, j'ai trouve que SEUL
  PostgreSQL, le SGBDR (Relationnel Objet)SQL libre, est le PLUS  mature
  et  le  plus largement utilise au monde. PostgreSQL est tres attractif
  en ce que beaucoup de travail a deja ete effectue et qu'il possede des
  pilotes   ODBC   et   JDBC   permettant   d'ecrire   des  applications
  independantes des  bases  de  donnees.  Les  applications  ecrites  en
  PostgreSQL  qui  utilisent  les  pilotes  ODBC,  JDBC  sont facilement
  portables sur d'autres systemes tels que Oracle, Sybase  et  Informix.
  Et  les  applications  ecrites  pour  Oracle,  Sybase  et Informix qui
  utilisent les pilotes ODBC, JDBC sont facilement portables sur la base
  de donnees PostgreSQL.

  3388..  FFAAQQ -- QQuueessttiioonnss ssuurr PPoossttggrreeSSQQLL

  3388..11..  DDeerrnniieerree vveerrssiioonn ddeess QQuueessttiioonnss FFrreeqquueemmmmeenntt PPoosseeeess ((FFAAQQ)) -- QQuueess--
  ttiioonnss ssuurr PPoossttggrreeSSQQLL

  Cette  FAQ  est incluse ici puisque tous les utilisateurs n'ont pas de
  butineurs tels que Netscape et acces a  l'Internet.  Les  utilisateurs
  peuvent  utiliser GnuInfo, Ghostview, l'editeur vi ou la commande man.
  Ce document a ete genere en 10 formats differents  tels  que  GnuInfo,
  RTF,  Texte  standard, Man page, Postscript etc.. et est distribue sur
  les CDROM Linux. Veuillez consultez la derniere version de  cette  FAQ
  qui  se trouve a <http://www.postgresql.org/docs/faq-english.shtml> si
  vous avez acces a l'Internet."

  Cette FAQ a ete mise ici pour vous rendre service.

  3388..22..  EExxttrraaiitt ddee llaa FFAAQQ dduu ssiittee WWeebb pprriinncciippaall ddee PPoossttggrreeSSQQLL

  Si vous avez acces a l'internet, cliquez sur cette URL maintenant pour
  en obtenir la derniere version.

  +o  <http://www.postgresql.org/docs>

  Questions Frequemment Posees (FAQ) sur PostgreSQL

  Derniere mise a jour : Lundi 17 Novembre 1997 19:47:15 EST
  Version: 6.2.1

  Gestionnaire actuel : Bruce Momjian (maillist@candle.pha.pa.us)

  La version la plus recente de ce document peut etre consultee sur le site Web de
  postgreSQL, http://postgreSQL.org.

  Les reponses aux questions specifiques a Linux a
  http://postgreSQL.org/docs/FAQ-linux.shtml.

  Les reponses aux questions specifiques a Irix a
  http://postgreSQL.org/docs/FAQ-irix.shtml.

  Modifications dans cette versions (* = modifie, + = nouveau):

  ---------------------------------------------------------------------------

  Reponses aux questions :

  1) Questions d'ordre general

  1.1) Qu'est-ce que PostgreSQL ?
  1.2) Sur quelles machines tourne PostgreSQL ?
  1.3) Ou puis-je trouver PostgreSQL ?
  1.4) Quel est le regime de copyright de PostgreSQL ?
  1.5) Support pour PostgreSQL
  1.6) Derniere version de PostgreSQL
  1.7) Existe-t-il une version commerciale de PostgreSQL ?
  1.8) Quelle est la documentation disponible pour PostgreSQL ?
  1.9) Quelle version de SQL PostgreSQL utilise-t-il ?
  1.10) PostgreSQL fonctionne-t-il avec les versions precedentes de postgres ?
  1.11) Y-a-t'il des pilotes ODBC pour PostgreSQL ?
  1.12) Quels sont les outils disponibles pour connecter postgres aux pages Web ?
  1.13) PostgreSQL dispose-t-il d'une interface utilisateur graphique ? D'un generateur
  de rapport ? D'une interface de langage de requete integree ?

  2) Questions concernant l'installation/Configuration

  2.1) initdb ne tourne pas
  2.2) Quand je demarre le postmaster, j'ai le message  "FindBackend: could not find a
  backend to execute..." "postmaster: could not find backend to execute..."
  2.3) Le systeme parait perturbe par les virgules, les points decimaux, et le format
  des dates.
  2.4) Comment puis-je installer PostgreSQL ailleurs que dans /usr/local/pgsql ?
  2.5) Quand je lance postmaster, j'ai un message "Bad System Call core dumped".
  2.6) Quand j'essaie de lancer postmaster, j'ai des messages d'erreur
  "IpcMemoryCreate".
  2.7) J'ai modifie un fichier source, mais une recompilation ne reflete pas les
  modifications ?
  2.8) Comment puis-je me premunir contre les acces a PostgreSQL a partir d'autres ordinateurs ?
  2.9) Je ne peux pas acceder a la base de donnee en tant qu'utilisateur 'root'.
  2.10) Tous mes serveurs se crashent lors d'acces concurrents aux tables. Pourquoi ?
  2.11) Comment puis ajuster mon moteur de bases de donnees pour avoir de meilleures
  performances ?
  2.12) Quelles sont les dispositifs de mise au point de PostgreSQL ?
  2.13) Comment puis-je activer plus de 32 frontaux concurrents ?

  3) Questions operationnelles

  3.1) Est-ce que PostgreSQL supporte les sous-requetes imbriquees ?
  3.2) J'ai eu tout un tas de problemes en utilisant les regles.
  3.3) Il semble que l'ecriture au milieu de grands objets ne soit pas fiable.
  3.4) Comment puis-je ecrire des applications clientes pour PostgreSQL ?
  3.5) Comment mettre en place un pg_group ?
  3.6) Quelle est la difference exacte entre les curseurs binaires et les curseurs normaux ?
  3.7) Qu'est-ce qu'un index R-tree et a quoi est-il utilise ?
  3.8) Quelle est la taille maximum d'un  tuple ?
  3.9) J'ai defini des index mais mes requetes ne semblent pas les utiliser Pourquoi ?
  3.10) Comment faire des recherches d'expressions regulieres? et des recherches regexp
  ne tenant pas compte de la casse ?
  3.11) J'ai subi un crash du serveur pendant une reorganisation. Comment puis-je supprimer
  le fichier de verrouillage ?
  3.12) Quelle et la difference entre les differents types caracteres ?
  3.13) Dans une requete, comment puis-je detecter si un champ est NULL ?
  3.14) Comment puis-je voir que l'optimiseur de requete est en train d'evaluer ma requete ?
  3.15) Comment puis-je creer un champ serie ?
  3.16) A quoi correspondent les fichiers pg_psort.XXX dans le repertoire de ma base
  de donnees ?
  3.17) Comment puis-je me connecter a ma base de donnees a partir d'une autre machine ?
  3.18) Comment puis-je voir quels sont les index ou les operations qui sont definis
  dans la base de donnees ?
  3.19) Qu'est-ce que la caracteristique spacio-temporelle (time-warp) et en quoi cela
  est-il en rapport avec la reorganisation ?
  3.20) Qu'est-ce qu'un oid? Qu'est-ce qu'un tid ?
  3.21) Quel est le sens de quelques-uns des termes utilises dans Postgres ?
  3.22) Qu'est-ce que l'Optimisation de Requete Genetique ?
  3.23) Comment supprime-t-on une colonne d'une table ?
  3.24) Comment faire un SELECT uniquement sur les quelques premieres lignes d'une requete ?
  3.25) Pourquoi ne puis-je par creer une colonne dont le nom soit "time" ?

  4) Questions sur l'extension de PostgreSQL

  4.1) J'ai ecrit une fonction definie par l'utilisateur et quand je la fait tourner sous psql,
  j'ai un plantage avec vidage memoire.
  4.2) J'ai des messages du type "NOTICE-PortalHeapMemoryFree- 0x402251d0 not in alloc set"!
  4.3) J'ai ecrit quelques nouveaux types et quelques fonctions astucieux pour  PostgreSQL.
  4.4) Comment dois-je ecrire une fonction C qui retourne un tuple ?

  5) Bogues

  5.1) Comment rediger un rapport de bogue ?

  ---------------------------------------------------------------------------

  Section 1: Questions d'ordre general

  1.1) Qu'est-ce que PostgreSQL ?

  PostgreSQL est une amelioration du systeme de gestion de base de donnees POSTGRES,
  un prototype de recherche de SGBD de la prochaine generation. Alors que  PostgreSQL
  garde le  puissant modele de donnees et les riches types de donnees de POSTGRES, il
  remplace le langage de requetes PostQuel par un sous-ensemble etendu du langage
  SQL. PostgreSQL est libre et le code source est disponible.

  Le developpement de PostgreSQL est effectue par une equipe de developpeurs Internet
  qui sont tous inscrits a la liste de diffusion consacree au developpement de PostgreSQL. Le
  coordinateur actuel est Marc G. Fournier (<htmlurl url="mailto:scrappy@postgreSQL.org
  " name="scrappy@postgreSQL.org">). (Voir ci-dessous comment le joindre). Cette equipe
  est maintenant responsable de tous les developpements actuels et futurs de
  PostgreSQL.

  Les auteurs de PostgreSQL 1.01sont Andrew Yu et Jolly Chen. Beaucoup d'autres ont
  contribue au portage, aux tests, au debogage et aux ameliorations du code. Le code
  original de Postgres, a partir duquel PostgreSQL est derive, est le resultat de
  l'effort de nombreux etudiants de troisieme cycle, de deuxieme cycle et d'enseignants
  sous la direction du Professeur Michael Stonebraker de l'universite de Californie,
  Berkeley.

       Le nom original du logiciel a Berkeley etait Postgres. Lors de l'ajout des
  fonctionnalites SQL en 1995, il fut renomme Postgres95. Ce nom fut change a la fin
  de 1996 en PostgreSQL.

  1.2) Sur quelles machines tourne PostgreSQL ?

  Les auteurs ont compile et teste PostgreSQL sur les plates-formes suivantes(quelques
  unes de ces compilations requierent gcc 2.7.0) :

     * aix - IBM on AIX 3.2.5 or 4.x
     * alpha - DEC Alpha AXP on Digital Unix 2.0, 3.2, 4.0
     * BSD44_derived - OSs derived from 4.4-lite BSD (NetBSD, FreeBSD)
     * bsdi - BSD/OS 2.0, 2.01, 2.1, 3.0
     * dgux - DG/UX 5.4R4.11
     * hpux - HP PA-RISC on HP-UX 9.0, 10
     * i386_solaris - i386 Solaris
     * irix5 - SGI MIPS on IRIX 5.3
     * linux - Intel x86 on Linux 2.0 and Linux ELF SPARC on Linux ELF PPC on
       Linux Elf (For non-ELF Linux, see LINUX_ELF below).
     * sco - SCO 3.2v5
     * sparc_solaris - SUN SPARC on Solaris 2.4, 2.5, 2.5.1
     * sunos4 - SUN SPARC on SunOS 4.1.3
     * svr4 - Intel x86 on Intel SVR4 and MIPS
     * ultrix4 - DEC MIPS on Ultrix 4.4

  Pour les plates-formes suivantes, il y a des problemes/bogues connus :

     * nextstep - Motorola MC68K ou Intel x86 sous NeXTSTEP 3.2

  1.3) Ou puis-je trouver PostgreSQL ?

  Le premier site ftp anonyme pour PostgreSQL est :

     * ftp://ftp.postgreSQL.org/pub

  Il existe un site miroir a :

     * ftp://postgres95.vnet.net/pub/postgres95
     * ftp://ftp.luga.or.at/pub/postgres95
     * ftp://cal011111.student.utwente.nl/pub/postgres95
     * ftp://ftp.uni-trier.de/pub/database/rdbms/postgres/postgres95
     * ftp://rocker.sch.bme.hu

  1.4) Quel est le regime de copyright de PostgreSQL?

  PostgreSQL est sujet au COPYRIGHT suivant.

  Systeme de Gestion de Base de Donnees PostgreSQL

  Copyright (c) 1994-6 Universite de Californie. Tous droits reserves

  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 ecrite est accordee, a 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 PARTICULIEREMENT 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.

  1.5) Support pour PostgreSQL

  Il n'y a aucun support officiel pour PostgreSQL de la part des de l'equipe de
  support initiale de l'Universite de Californie, Berkeley. Il est maintenu
  uniquement grace a l'effort de volontaires.

  La liste de diffusion est : questions@postgreSQL.org.
  Elle est disponible pour des discussions sur
  des sujets concernants PostgreSQL, incluant les rapports
  d'erreurs et corrections, mais non limites a ceux-ci. Pour avoir des informations sur
  la maniere de s'inscrire, envoyer un courrier electronique avec les lignes suivantes
  dans le corps du message (pas dans la ligne sujet)

          subscribe
          end

  a questions-request@postgreSQL.org.

  Il y a aussi une liste resumee. Pour s'inscrire a cette liste, envoyez un
  courrier electronique a : questions-digest-request@postgreSQL.org avec,
  dans le CORPS du message :

          subscribe
          end

  Des resumes sont envoyes aux membres de cette liste chaque fois que la liste
  principale a recu environ 30k de messages.

  Il y a une liste de diffusion des erreurs. Pour s'inscrire a cette liste,
  envoyez un courrier electronique a bugs-request@postgreSQL.org avec, dans le
  CORPS du message :

  Il y a aussi un forum de discussion pour les developpeurs. Pour s'inscrire a
  cette liste, envoyer un courrier electronique a hackers-request@postgreSQL.org
  avec, dans le CORPS du message :

          subscribe
          end

  Des informations complementaires sur PostgreSQL peuvent etre trouvees via la
  page d'accueil WWW de PostgreSQL a :

       http://www.postgreSQL.org

  1.6) Derniere version de PostgreSQL

  La derniere version de PostgreSQL est la version 6.2.1, qui est disponible
  depuis le 17 octobre 1997. Pour avoir des informations sur les nouveautes
  de la version  6.2.1, consulter le fichier TODO sur notre page WWW.

  Nous nous proposons de diffuser une revision majeure tous les trois mois.

  1.7) Existe-t-il une version commerciale de PostgreSQL ?

  Illustra Information Technology (filiale possedee totalement par Informix
  Software, Inc.) vend un SGBD Relationnel Objet appele Illustra qui etait, a
  l'origine, base sur postgres. Illustra a des similarites d'aspect avec
  PostgreSQL mais possede plus de fonctionnalites, est plus robuste, plus
  performant et dispose de documentation et d'un support reels. D'un autre cote,
  il coute de l'argent.
  Pour de plus informations, contactez sales@illustra.com

  1.8) Quelle documentation est disponible pour PostgreSQL ?

  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 particulierement importantes.

  La page www contient des liens sur un guide d'implementation et sur cinq papiers
  concernants les concepts d'architecture et les fonctionnalites de postgres .

  1.9) Quelle version de SQL PostgreSQL utilise-t-il ?

  PostgreSQL supporte un sous-ensemble de SQL-92. Ils en possede les constructions
  les plus importantes mais manque de certaines fonctionnalites. Les differences
  les plus visibles sont :

     * les sous-requetes imbriquees ne sont pas supportees
     * pas de clause HAVING sous un GROUP BY

  D'un autre cote, vous pouvez creer des types definis par l'utilisateur, des
  fonctions, de l'heritage etc. Si vous souhaitez participer a la programmation de
  PostgreSQL, vous pouvez ajouter les fonctionnalites manquantes enumerees
  ci-dessus.

  1.10) PostgreSQL fonctionne-t-il avec les versions precedentes de postgres?

  PostgreSQL v1.09 est compatible avec les bases de donnees creees avec la version
  v1.01.

  Une mise a niveau de la version pre-6.2 vers la version 6.2.1  necessite de faire
  un vidage et une restauration.

  Une mise a niveau de la version 6.2 vers la version 6.2.1  ne necessite pas
  de faire un vidage et une restauration, mais consultez le fichier /migration
  de la distribution.

  Ceux qui font une mise a niveau de versions anterieures a 1.09 doivent d'abord
  faire une mise a niveau vers la version 1.09 sans vidage/restauration, puis
  vider les donnees de la version 1.09, et enfin les recharger dans la version
  6.2.1.

  1.11) Y-a-t'il des pilotes ODBC pour PostgreSQL?

  Deux pilotes ODBC sont disponibles, PostODBC et OpenLink ODBC.

  Pour tous les gens interesses par PostODBC, il y a maintenant deux
  liste de diffusion consacrees aux discussions concernant PostODBC.
  Ces listes de diffusion sont :

     * postodbc-users@listserv.direct. net
     * postodbc-developers@listse rv.direct.net

  ce sont des listes de diffusion ordinaires gerees par majordomo. Vous pouvez
  y souscrire en envoyant un mail a :

     * majordomo@listserv.direct.net

  OpenLink ODBC est tres populaire. Vous pouvez le trouver sur
  http://www.openlinksw.com/postgres.html. Il fonctionne avec notre
  logiciel client standard ODBC donc, vous aurez Postgres ODBC disponible
  sur chaque plate-forme client que nous supportons (Win, Mac, Unix, VMS).

  Nous vendrons probablement ce produit aux gens qui ont besoin d'un support
  de qualite commerciale, mais une version libre sera toujours disponible
  Les questions sont a adresser a postgres95@openlink.co.uk.

  1.12) Quels sont les outils disponibles pour connecter postgres aux pages Web ?
  Pour l'integration au web, PHP est une excellente interface. Son URL est
  http://php.iquest.net

  PHP est tres bien pour des choses simples, mais pour des choses plus
  compliquees, certains utilisent encore l'interface perl interface et CGI.pm.

  Une passerelle WWW basee sur WDB et utilisant perl peut etre tele-chargee de :

     * http://www.eol.ists.ca/~dunlop/wdb -p95

  1.13) PostgreSQL a-t-il une interface utilisateur graphique ? Un generateur de rapport ?
  Une interface de langage de requete integree ?

  Non. Non. Non. Au moins, pas dans la distribution officielle. Quelques utilisateurs
  ont indique quelques succes dans l'utilisation de 'pgbrowse' et de 'onyx' comme
  frontaux a PostgreSQL. Plusieurs contributeurs travaillent sur des outils frontaux
  bases sur Tk. Posez la question dans la liste de diffusion.

  ---------------------------------------------------------------------------

  Section 2: Questions concernant l'installation

  2.1) Initdb ne tourne pas

     * verifiez que vous avez les chemins appropries
     * verifiez que l'utilisateur 'postgres' dispose des droits necessaires sur
       les fichiers
     * assurez-vous qu'il y a des fichiers dans \*(dR PGDATA/files, et qu'ils ne
       sont pas vides. S'ils n'y sont pas, c'est que "gmake install" a echoue pour
       une raison quelconque

  2.2) Quand je demarre le postmaster, j'ai le message "FindBackend- could not find a
  backend to execute..." "postmaster- could not find backend to execute..."

  Le bon chemin n'est probablement pas specifie. L'executable 'postgres'
  doit etre dans vos chemins par defaut.

  2.3) Le systeme parait perturbe par les virgules, les points decimaux, et le format
  des dates.

  Verifiez votre configuration locale. PostgreSQL utilise les options locales
  choisies par l'utilisateur qui a lance le processus postmaster. Adaptez-les
  selon votre environnement de travail.

  2.4) Comment puis-je installer PostgreSQL ailleurs que dans /usr/local/pgsql?

  Il vous faut editer le fichier Makefile.global et modifier POSTGRESDIR suivant
  vos souhaits, ou creer un fichier Makefile.custom et definir POSTGRESDIR ici.

  2.5) Quand je lance postmaster, j'ai un message "Bad System Call core dumped".

  Cela peu etre du a de nombreux problemes, mais, en premier lieu, verifiez que
  vous disposez bien des extensions system V dans votre noyau. PostgreSQL
  necessite un support de la memoire partage dans le noyau.

  2.6) Quand j'essaie de lancer postmaster, j'ai des messages d'erreur
  "IpcMemoryCreate".

  Soit votre gestion de la memoire partagee n'est pas configuree correctement
  dans le noyau soit vous avez besoin d'etendre la memoire partagee disponible dans
  le noyau. La quantite dont vous avez besoin depend de l'architecture de votre
  systeme et du nombre de tampons avec lesquels postmaster a ete configure pour
  tourner. Pour la plupart des systemes, avec des tampons de la taille par defaut,
  vous avez besoin d'un minimum de ~ 760K.

  2.7) J'ai modifie un fichier source, mais une recompilation ne reflete pas les
  modifications?

  Les fichiers Makefile ne contiennent pas les dependances correctes pour les
  fichiers inclus. Il vous faut executer 'make clean' puis un autre 'make'.

  2.8)  Comment puis-je me premunir contre les acces a PostgreSQL a partir
  d'autres ordinateurs ?

  Utilisez l'authentification des ordinateurs en modifiant le fichier $PGDATA/pg_hba
  en consequence.

  2.9) Je ne peux pas acceder a la base de donnees en tant qu'utilisateur 'root'.

  Vous ne devez pas creer de bases de donnees utilisateurs ayant un identificateur
  utilisateur 0(root). Ils seraient incapables d'acceder a la base de donnees.
  C'est une precaution dictee par un souci de securite puisque n'importe quel
  utilisateur peut lier dynamiquement des modules objets au moteur de base de donnees.

  2.10) Tous mes serveurs se crashent lors d'acces concurrents aux tables. Pourquoi ?

  Ce probleme peut etre du a un noyau qui n'a pas ete configure pour supporter les
  semaphores.

  2.11) Comment puis-je ajuster le moteur de base de donnees pour obtenir de meilleures
  performances ?

  Vous pouvez faire deux choses. Vous pouvez utiliser l'option d'Openlink pour desactiver
  fsync() en lancant le postmaster avec les options '-o -F'. Ceci evitera a fsync() de
  mettre a jour le disque apres chaque transaction.

  Vous pouvez aussi utiliser l'option -B de postmaster -B pour augmenter le nombre de tampons
  de memoire partagee partages entre les differents processus de fond de plan. Si vous
  donnez une valeur trop elevee a ce parametre, les processus ne demarreront pas ou se
  crasheront de maniere inattendue. Chaque tampon a une taille de 8K et il y a 64 tampons
  par defaut.

  Vous pouvez aussi utiliser l'option -S du postmaster pour augmenter la taille maximum
  de la memoire utilisee par chaque processus de fond de plan pour les tris temporaires.
  Chaque tampon a une taille de 1K et il y a 512 tampons par defaut.

  2.12) Quelles sont les dispositifs de mise au point de PostgreSQL?

  PostgreSQL dispose de plusieurs fonctions qui donnent des informations sur son etat
  qui peuvent etre utiles pour des besoins de debogage.

  Tout d'abord, en faisant tourner configure avec l'option -enable-cassert, de nombreux
  assert()'s permettent de suivre l'avancement du processus de fond de plan et arretent
  le programme quand quelque chose d'inattendu se produit.

  A la fois le postmaster et postgres ont plusieurs options de debogage. Premierement,
  a chaque fois que lancez le postmaster, assurez-vous de rediriger la sortie standard
  et les messages d'erreurs vers un fichier d'enregistrement, comme :

          cd /usr/local/pgsql
          ./bin/postmaster >server.log 2>&1 &

  Ceci creera un fichier server.log en tete de l'arborescence du repertoire de
  PostgreSQL. Ce fichier peut contenir des informations utiles concernant les problemes
  et les erreurs rencontres par le serveur. Postmaster possede une option -d qui permet
  d'obtenir des informations plus detaillees. L'option -d peut prendre une valeur de 1
  a 3 qui specifie le niveau de debogage. Faites attention au fait qu'un
  niveau de debogage de 3 entraine la generation de fichiers de compte-rendus
  volumineux.

  Vous pouvez , en realite, faire tourner le processus de fond de plan postgres a partir
  de la ligne de commande, et taper vos instructions SQL directement. Ceci n'est
  recommande que SEULEMENT dans des situations de debogage. Notez qu'un caractere saut
  de ligne termine la requete, pas un point-virgule. Si vous avez effectue la compilation
  avec l'option de debogage, vous pouvez utiliser un debogueur pour voir ce
  qui se passe. Le processus de fond de plan n'ayant pas ete lance par le postmaster,
  il ne tourne pas dans un environnement identique et les problemes d'interaction
  processus de fond de plan/verrouillage peuvent ne pas etre reproduits. Quelques
  systemes d'exploitation peuvent se connecter a un processus de fond de plan
  directement pour diagnostiquer les problemes.

  Le programme postgres possede les options a -s, -A, -t qui peuvent etre tres utiles
  pour la mise au point et pour la mesure de performances.

  La commande EXPLAIN (Voir dans cette FAQ) permet de voir comment PostgreSQL
  interprete votre requete.

  2.13) Comment puis-je activer plus de 32 frontaux concurrents ?

  Editez le fichier include/storage/sinvaladt.h, et modifiez la valeur de
  MaxBackendId. Dans le futur, nous projetons de rendre ce parametre
  configurable.

  ---------------------------------------------------------------------------

  Section 3 : Fonctionnalites de PostgreSQL

  3.1) Est-ce que PostgreSQL supporte les sous-requetes imbriquees?

  Les sous-requetes imbriquees ne sont pas encore implantees, mais elles
  peuvent etre simulees en utilisant des fonctions sql.

  3.2) J'ai eu un tas de problemes dans l'utilisation des regles.

  Actuellement, le systeme de regles dans PostgreSQL n'est pratiquement pas
  fonctionnel. Il fonctionne suffisamment pour supporter le mecanismes de vue,
  mais c'est tout. Vous utilisez les regles PostgreSQL a vos risques et perils.

  3.3) Il ne me semble pas possible d'ecrire au milieu de grands objets de maniere fiable.

  Le systeme de gestion des grands objets n'est egalement pas fonctionnel dans
  PostgreSQL. Il fonctionne juste assez pour stocker de grands paquets de donnees et
  les relire, mais l'implementation souffre de quelques problemes sous-jacents.
  Vous utilisez les grands objets PostgreSQL a vos risques et perils.

  3.4) Comment puis-je ecrire une application cliente pour PostgreSQL?

  PostgreSQL supporte une bibliotheque d'interfacage que l'on peut appeler a partir de
  C nommee libpq et beaucoup d'autres. Consultez le repertoire /src/interfaces.

  D'autres ont contribue a une interface perl et a une passerelle WWW a PostgreSQL.
  Consulter la page d'accueil PostgreSQL pour plus de details.

  3.5) Comment puis-je mettre en place un pg_group?

  Actuellement, il n'y a pas d'interface aisee pour mettre en place des groupes d'utilisateurs.
  Vous devez explicitement inserer/mettre a jour la table pg_group. Par exemple :

          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=>

  Les champs dans le fichier pg_group sont :

     * groname : le nom de groupe. C'est un char16 et il doit etre purement alphanumerique.
                 Ne pas inclure de soulignes ou d'autres ponctuations.
     * grosysid : l'identificateur de groupe. C'est un int4. Il doit etre unique pour
                  chaque groupe.
     * grolist : la liste des identificateurs de pg_user qui appartiennent au groupe.
                C'est un int4[].

  3.6) Quelle l'exacte difference entre les curseurs binaires et les curseurs normaux?

  Consultez la page de manuel sur declare pour en avoir une description.

  3.7) Qu'est-ce qu'un index R-tree et a quoi est-il utilise?

  Un index R-tree est utilise pour indexer les donnees spatiales. Un index obtenu par
  hachage ne peut pas effectuer de recherches dans une gamme de donnees. Un index B-tree
  peut seulement effectuer des recherches dans une gamme de donnees sur une dimension.
  Les index R-tree permettent de traiter des donnees multi-dimensionnelles. Par
  exemple, si un index R-tree peut etre construit sur un attribut de type 'point' le
  systeme peut repondre plus efficacement a des requetes telles que selectionner tous
  les points a l'interieur d'un rectangle.

  Le papier de reference qui decrit 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 egalement trouver ce papier dans le livre de Stonebraker "Readings in Database
  Systems" (Lectures sur les Systemes de Gestion de Base de Donnees)

  Les R-Trees intrinseques peuvent prendre en compte les polygones et les boites.
  En theorie, les R-trees peuvent etre etendus pour manipuler un plus grand nombre
  de dimensions. En pratique, l'extension des R-Tree necessite pas mal de travail
  et nous n'avons pas actuellement de documentation pour le faire.

  3.8) Quelle est la taille maximum d'un tuple?

  Les Tuples sont limites a 8K octets. En tenant compte des attributs du systeme et
  autres surcharges, il faut rester bien a l'ecart des 8,000 octets pour etre
  tranquille. Pour utiliser des attributs superieurs a 8K, essayez d'utiliser
  l'interface pour les grands objets.

  Les Tuples ne doivent pas franchir la frontiere des 8k donc un tuple de 5k necessitera
  un espace de stockage de 8k.

  3.9) J'ai defini des index, mais mes requetes ne paraissent pas en faire usage. Pourquoi?

  PostgreSQL n'entretient pas automatiquement de statistiques. On doit realiser un
  appel a une "reorganisation" explicite pour mettre les statistiques a jour. Apres
  que les statistiques aient ete mises a jour, l'optimiseur fera un meilleur usage des
  index. Notez que l'optimiseur est limite et n'utilise pas les index dans certaines
  circonstances (telles que les dans les clauses OR). Pour les statistiques sur
  l'optimisation specifique aux colonnes, utilisez 'analyse de la reorganisation'.

  Si le systeme ne voit toujours pas l'index, c'est probablement parce que vous avez
  cree un index sur un champ du type impropre  *_ops . Par exemple, vous avez cree un
  champ CHAR(4), mais vous avez specifie un index char_ops de type_class.

  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 previent pas l'utilisateur quand un index incorrect est cree.

  Les index ne sont pas utilises dans les operations ORDER BY.

  3.10)
  Comment faire des recherches d'expressions regulieres ? et des recherches regexp ne tenant
  pas compte de la casse ?

  Consultez la page de manuel pgbuiltin. Rechercher le terme expression reguliere.

  3.11) J'ai subit un crash du serveur pendant une reorganisation. Comment puis-je supprimer
  le fichier de verrouillage?

  Consultez la page de manuel sur la reorganisation.

  3.12) Quelle et la difference entre les differents types caracteres?

  Type            Nom Interne     Notes
  --------------------------------------------------
  CHAR            char            1 caractere   )
  CHAR2           char2           2 caracteres  )
  CHAR4           char4           4 caracteres  ) optimises pour une longueur fixe
  CHAR8           char8           8 caracteres  )
  CHAR16          char16          16 caracteres )
  CHAR(#)         bpchar          complete par des blancs jusqu'a la longueur fixe specifiee
  VARCHAR(#)      varchar         la taille specifie la longueur maximum, pas de remplissage
  TEXT            text            longueur limitee 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  creez des index
  sur ces champs ou quand vous effectuez d'autres operations internes.

  Les quatre derniers types ci-dessus sont des types "varlena" (i.e. les quatre
  premiers octets donnent la longueur, suivie par les donnees). CHAR(#) et VARCHAR(#)
  allouent le nombre maximum d'octets quelle que soient les donnees stockees dans le
  champ.
  TEXT et BYTEA sont les seuls types caracteres qui ont une longueur variable sur le
  disque.

  3.13) Dans une requete, comment puis-je detecter si un champ est NULL?

  Vous faites un test sur la colonne en utilisant IS NULL et IS NOT NULL.

  3.14) Comment puis-je voir que l'optimiseur de requete est en train d'evaluer ma requete?

  Consultez la page de manuel traitant de explain

  3.15) Comment puis-je creer un champ serie?

  Postgres ne permet pas a l'utilisateur de specifier 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 donnees, vous serez obliges d'utiliser pgdump avec l'option -o'ou COPY avec l'option
  WITH OIDS pour conserver les oids.

  Il y a aussi une fonction SEQUENCE qui est similaire a SERIAL. consultez la page
  de manuel sur create_sequence.

  Une autre maniere valide de le faire est de creer 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 a l'esprit qu'il y a competition ici ou un serveur peut
  effectuer une mise a jour, puis un autre serveur en effectuer une et que
  les deux selectionnent le meme nouvel identificateur. Cette instruction doit etre
  effectuee dans le cadre d'une transaction.

  Une autre maniere de le faire consiste a utiliser la fonction de declenchement generale
  autoinc() de contrib/spi/autoinc.c.

  3.16) Que sont les fichiers pg_psort.XXX dans le repertoire de ma base de donnees?

  Ce sont les fichiers temporaires crees par l'executeur de requete.
  Par exemple, si un tri doit etre effectue pour realiser une instruction ORDER BY,
  quelques fichiers temporaires sont crees en resultat du tri.

  Si vous n'avez pas de transactions ou de tri en cours a cet instant, vous pouvez
  supprimer ces fichiers temporaires pg_psort.XXX sans risques.

  3.17) Pourquoi ne puis-je pas me connecter a ma base de donnees a partir d'une autre machine ?

  La configuration par defaut n'autorise seulement les connexions que de l'hote
  tcp/ip ordinateur-local (localhost). Vous devez ajouter une entree pour l'ordinateur
  hote dans le fichier pgsql/data/pg_hba. Consultez la page de manuel sur hba_conf.

  3.18) Comment puis-je trouver quels index et quelles operations sont definis dans
  la base de donnees?

  Executez le fichier pgsql/src/tutorial/syscat.source. Il donne l'illustration de
  beaucoup de 'selections' ('select's) a faire pour obtenir des informations sur les
  tables du systeme de gestion de base de donnees.

  3.19)  Qu'est-ce que la caracteristique spacio-temporelle (time-warp) et en quoi
  cela est-il en rapport avec la reorganisation ?

  PostgreSQL traite les modifications de donnees de maniere differente de la plupart
  des systemes de gestion de bases de donnees. Quand une ligne est modifiee dans une
  table, la ligne originale est marquee avec un timbre dateur au moment ou cette
  modification est intervenue, et une nouvelle ligne est creee avec les donnees
  actuelles. Par defaut, seules les donnees actuelles sont utilisees dans une table.
  Si vous specifiez une donnee date/heure a la suite du nom de la table dans une clause
  FROM, vous pouvez avoir acces aux donnees qui etaient "actuelles" a ce moment la,
  i.e.

          SELECT *
          FROM employees ['July 24, 1996 09:00:00']

  affiche les lignes des employes dans la table au moment specifie. Vous pouvez
  specifier des intervalles tels que [date,date], [date,], [,date], ou [,]. Cette
  derniere option permet d'acceder a toutes les lignes qui ont existe.

  L'insertion (INSERT) de lignes recoit egalement un horodatage, donc, les lignes qui
  n'etaient pas dans la table a l'instant desire ne seront pas affichees.

  La reorganisation supprime les lignes qui ne sont plus "actuelles" (courantes). La
  caracteristique spacio-temporelle est utilisee par le moteur du SGBD pour l'annulation des
  modifications et pour la restauration apres un plantage. Les dates/heures
  d'expiration peut etre indiques dans la commande purge.

  En 6.0, apres le nettoyage d'une table, la date de creation d'une ligne peut etre
  incorrecte, causant l'echec d'un parcours de la base de donnees base sur les dates
  (time-travel).

  Cette fonctionnalite de parcours dans le temps a ete supprimee dans la version 6.3.

  3.20) Qu'est-ce qu'un oid ? Qu'est-ce qu'un tid ?

  Les Oid sont la reponse de Postgres a des identificateurs de ligne uniques ou a des
  colonnes serielles. Chaque ligne qui est creee dans Postgres recoit un oid unique.
  Tous les oids generes par initdb sont inferieurs a 16384 (voir
  backend/access/transam.h). Tous les oids post-initdb (crees par un utilisateur) sont
  egaux ou superieurs a cette valeur. Tous ces oids sont uniques, non pas seulement dans
  une table,  ou une base de donnees, mais uniques a l'interieur de l'installation
  postgres toute entiere.

  Postgres utilise les oids dans ses tables systeme internes pour relier les lignes de
  tables separees. Ces oids peuvent etre utilises pour identifier des lignes
   specifiques a 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 utilises pour identifier des lignes physiques specifiques contenant des
  valeurs de bloc ou de decalage. Les tids changent apres une modification ou un
  rechargement des lignes. Ils sont utilises par des enregistrements d'index pour pointer
  sur des lignes physiques. On ne peut pas y acceder par sql.

  3.21) Quel est le sens de quelques termes utilises dans Postgres ?

  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, selectionner
     * replace, update              remplacer, mettre a jour
     * append, insert               ajouter, inserer
     * oid, serial value            oid, valeur serielle
     * portal, cursor               portail, curseur
     * range variable, table name, table alias
                                    variable indiquant une etendue, nom de la
                                    table, alias de la table

  Merci de me faire savoir si vous pensez a d'autres.

  3.22) Qu'est-ce que l'Optimisation de Requete Genetique ?

  Le module GEQO dans PostgreSQL est sense resoudre le probleme d'optimisation de requete
  sur la jointure de plusieurs tables au moyen d'un Algorithme Genetique  (GA). Il permet
  le traitement de grandes jointures par l'intermediaire d'une recherche non--exhaustive.

  Pour de plus amples informations voir README.GEQO <utesch@aut.tu-freiberg.de>.

  3.23) Comment supprimer une colonne d'une table ?

  Il n'est pas possible d'utiliser ALTER TABLE DROP COLUMN, mais, faites ceci :

          SELECT ...  -- selectionne toutes les colonnes sauf celle que vous voulez supprimer
          INTO TABLE new_table
          FROM old_table;
          DROP TABLE old_table;
          ALTER TABLE new_table RENAME TO old_table;

  3.24) Comment faire un SELECT uniquement sur les quelques premieres lignes d'une requete ?

  Consultez la page de manuel concernant fetch.

  Ceci evite seulement de transferer toutes les lignes du resultat au client.
  La requete complete doit etre evaluee, meme si vous ne desirez que les
  premieres lignes. Envisageons une requete qui utilise l'instruction
  ORDER BY. Il n'y a aucun moyen de donner un resultat tant que la requete
  complete n'aura pas ete evaluee et triee.

  3.25) Pourquoi ne puis-je par creer une colonne dont le nom soit "time" ?

  La version 6.2.1 comporte quelques mots-cles reserve nouveaux pour rendre PostgreSQL
  plus conforme a ANSI-92. La prochaine version verra ces restriction supprimees. Il existe
  une rustine sur ftp.postgresql.org qui offre cette possibilite des maintenant.
  ---------------------------------------------------------------------------

  Section 4: Extension de PostgreSQL

  4.1) J'ai ecrit une fonction definie par l'utilisateur et quand je la fait tourner sous psql,
  j'ai un plantage avec vidage memoire.

  Ce probleme peut provenir d'un certains nombre de causes. Tout d'abord, essayez de
  tester votre fonction dans un programme de test independant. Assurez-vous egalement
  que vous n'etes pas en train d'envoyer des MESSAGES elog quand le frontal attend des
  donnees, comme dans les fonctions type_in() or type_out()

  4.2) J'ai des messages du type "NOTICE-PortalHeapMemoryFree- 0x402251d0 not in alloc set"!

  Vous etes en train de liberer (pfree) quelque chose qui n'a pas ete alloue (palloc).
  Quand vous ecrivez des fonctions definies par l'utilisateur, n'incluez pas le fichier
  "libpq-fe.h". Si vous faites cela, va entrainer que votre  palloc soit un malloc a la
  place d'un free. Puis, quand la tache de fond libere (pfrees) la memoire, vous recevez
  le message d'avertissement NOTICE.

  4.3) J'ai ecrit quelques nouveaux types et quelques fonctions astucieux pour  PostgreSQL.

  S'il vous plait, partagez-les avec les autre utilisateurs de PostgreSQL. Envoyez vos
  extensions dans la liste de diffusion, et elles finiront peut-etre dans le
  sous-repertoire contrib/.

  4.4) Comment dois-je ecrire une fonction C qui retourne un tuple?

  Cela necessite beaucoup de genie, tellement que les auteurs n'ont jamais essayer, bien
  que, en principe, cela soit possible. Une reponse breve sera ... vous ne pouvez pas.
  Cette possibilite est envisagee dans le future.

  ---------------------------------------------------------------------------

  Section 5 : Bogues

  5.1) Comment dois faire un rapport de bogue?

  Regardez la FAQ actuelle a http://www.postgreSQL.org

  Regardez aussi a notre site ftp://ftp.postgreSQL.org/pub pour voir s'il
  n'y a pas une version plus recente de PostgreSQL.

  Vous pouvez aussi remplir le fichier formulaire "bug-template" et l'envoyer a :

     * bugs@postgreSQL.org

  C'est l'adresse de la liste de diffusion des developpeurs.

  3399..  FFAAQQ LLiinnuuxx--PPoossttggrreeSSQQLL

  3399..11..  DDeerrnniieerree vveerrssiioonn ddee llaa FFAAQQ LLiinnuuxx--PPoossttggrreeSSQQLL

  Cette FAQ est incluse ici puisque tous les utilisateurs n'ont  pas  de
  butineurs  tels  que  Netscape et acces a l'Internet. Les utilisateurs
  peuvent utiliser GnuInfo, Ghostview, l'editeur vi ou la commande  man.
  Ce  document  a  ete genere en 10 formats differents tels que GnuInfo,
  RTF, Texte standard, Man page, Postscript etc.. et est  distribue  sur
  les  CDROM  Linux. Veuillez consultez la derniere version de cette FAQ
  qui se trouve a <http://www.postgresql.org/docs/faq-english.shtml>  si
  vous avez acces a l'Internet."

  Cette FAQ a ete mise ici pour vous rendre service.

  3399..22..  EExxttrraaiitt ddee llaa FFAAQQ dduu ssiittee WWeebb pprriinncciippaall ddee PPoossttggrreeSSQQLL

  Si vous avez acces a l'internet, cliquez sur cette URL maintenant pour
  en obtenir la derniere version.

  +o  <http://www.postgresql.org/docs>

  =====================================================

  Foire Aux Questions (FAQ) de PostgresSQL V6.1
  Specifique Linux
  A LIRE EN PARALLELE AVEC LA FAQ NORMALE

  =====================================================

  Derniere mise a jour:     Mercredi 1er octobre 20:16:00 BST 1997

  Gestionnaire actuel:      Andrew C.R. Martin (martin@biochem.ucl.ac.uk)
  Auteur original:          Andrew C.R. Martin (martin@biochem.ucl.ac.uk)

  Modifications dans cette version (* = modifie, + = nouveau, - = supprime):

  +3.9)   Pourquoi Query 32 dure-t-il si longtemps dans les tests de regression ?

  Ce fichier a ete approximativement divise comme suit :
  1.*)    Installation de PostgreSQL
  2.*)    Compilation des programmes accessoires
  3.*)    Problemes d'execution

  Reponses aux questions :
  1.1)    Quelles modifications dois-je apporter a src/Makefile.global ou a
          src/Makefile.custom et d'autres modifications sont-elles necessaires?
  1.2)    Pourquoi ai-je des problemes avec "libreadline" manquant ?
  1.3)    [REDHAT]  Pourquoi ai-je des problemes avec libdl and dlfcn.h manquants ?
  1.4)    [SLACKWARE 3.1] Pourquoi ai-je des problemes avec libdl and dlfcn.h manquants ?
  1.5)    Ma compilation echoue en reclamant le "fichier include" manquant dlfcn.h
  1.6)    GCC se plaint d'une option inexistante -fpic
  1.7)    J'ai des messages d'avertissement du type
          "warning- cast from pointer to integer of different size"
  1.8)    [SuSE-Linux 4.2-4.4] Ou sont curses et termcap ?
  1.9)    Pourquoi ai-je des problemes avec ld.so ?
  1.10)   Pourquoi ai-je les erreurs `yy_flush_buffer undefined' ?
  1.11)   Comment dois-je compiler PostgreSQL sur un systeme a.out ?
  1.12)   Pourquoi make echoue-t-il avec -
          yacc -d /disk2/PostgreSQL/src/backend/parser/gram.y
          make- /usr/bin/make- cannot execute binary file
  1.13)   Que sont les references a libsocket dans X11_LIB  et libnsl dans src/Makefile.global ?
  1.14)   [DEBIAN] Ou se trouve libtermcap ?
  1.15)   [REDHAT] Puis-je obtenir PostgreSQL au format RPM?
  1.16)   Quand j'essaie de compiler une version de developpement sous Linux, cette compilation
          echoue avec un message du style :
          In file included from /usr/include/sys/sem.h:8,
                   from ipc.c:37:
          /usr/include/asm/bitops.h:32: warning: no previous prototype for Set_bit'
          ....
          make: *** [ipc.o] Error 1
  1.17)   En compilant  postgres, gcc retourne un message signal 11 et s'interrompt..
  1.18)   Puis-je installer la version 6.1.1 sous MkLinux?
  2.1)    L'editeur de lien ne trouve pas libX11 quand on compile pgtclsh
  3.1)    J'ai une erreur indiquant _fUnKy_POSTPORT_sTuFf_ non defini quand j'execute
          les scripts tels que createuser
  3.2)    Je lance postmaster et ensuite le systeme affiche 'Bad system call(Core
          dumped)'
  3.3)    Quand j'essaie de lancer le Postmaster, pourquoi ai-je une erreur de la forme
          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.
  3.4)    Pourquoi createuser ne fonctionne-t-il pas ?
  3.5)    Pourquoi ai-je une erreur comme :
          IpcMemoryCreate: memKey=155356396 , size=760632 ,
          permission=384IpcMemoryCreate: shmget(..., create, ...)
          failed: Invalid argument
  3.6)    Pourquoi psql echoue avec :
          psql: can't load library 'libpq.so.1'
  3.7)    Autre comportement etrange
  3.8)    Si l'on arrete le systeme alors que PostgreSQL est en cours d'execution,
          alors, Linux lance toujours un fsck sur le disque au redemarrage.
  3.9)    Pourquoi Query 32 dans le test de regression dure-t-il si longtemps ?

  ----------------------------------------------------------------------
  Section 1:      Compilation de PostgreSQL
  ----------------------------------------------------------------------

  1.1)    Quelles modifications dois-je apporter a src/Makefile.global ou
          src/Makefile.custom et est-il necessaire de faire d'autres modifications ?

          Ces modifications sont realisees plus facilement en executant le
          script d'adaptation dans le repertoire src qui creera un fichier
          Makefile.custom pour vous.

          La seule autre modification que vous pouvez avoir a faire consiste
          a remplacer Flex si vous avez la version 2.5.3 qui a un bogue se
          manifestant generalement par un echec de createuser (Voir la Question 3.4)

          Si vous le faites par vous-meme, vous *devez* renseigner la variable
          suivante :
                  PORTNAME=       linux

          Il vous faudra aussi modifier celle-ci pour refleter 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 systeme Slackware3.0, ces donnees 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 toutes les autres modifications dont vous avez
          besoin, ceci etant documente dans les fichiers
           INSTALL et Makefile.global

  1.2)    Pourquoi ai-je des problemes avec "libreadline" manquant ?

          Les systemes Linux ne sont generalement pas livres avec la bibliotheque
          GNU readline installee. Soit vous vous assurez que vous n'avez pas
          active les options readline dans src/Makefile.global ou
          src/Makefile.custom soit vous installez la bibliotheque GNU
          readline.

          Notez que Debian Linux (comme FreeBSD) est livre avec readline
          installe.

  1.3)    [REDHAT] Pourquoi ai-je des problemes avec libdl and dlfcn.h manquants ?

          La bibliotheque libdl est utilisee pour la liaison dynamique de
          fonctions fournies par l'utilisateurs au moment de l'execution.
          Pour une raison quelconque, cette bibliotheque a ete oubliee dans
          la distribution Redhat. Il semble que ce probleme a ete resolu
          dans la version Redhat 4.0 (Colgate).

          RedHat possede maintenant un nouveau paquetage ld.so RPM sur
          son site FTP. Recuperez simplement :

                  ftp://ftp.redhat.com/pub/redhat/devel/i386/RedHat/RPMS/ld.so-1.7.14-4.i386.rpm

          Installez le fichier RPM de la maniere habituelle et c'est tout!

          Il y a eu des rapports indiquant que des systemes ont ete abimes
          suite a l'acces a ces bibliotheques par certains programmes pendant
          leur mise a jour (ce qui n'est pas tout a fait surprenant). En
          consequence, c'est une bonne idee de redemarrer le systeme avant
          l'installation de nouvelles bibliotheques et d'avoir le minimum de
          choses en fonction pendant ces mises a niveau. Passer en mode
          mono-utilisateur est certainement aussi une bonne idee!

          Si vous voulez le faire de la maniere difficile, vous pouvez
          obtenir la bibliotheque et le fichier en-tete a :

                  ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ld.so-1.7.14.tar.gz

          Autrement, vous pouvez obtenir les binaires pre-compiles dans
          distributions/debian/buzz/binary-i386/base/ld.so-1.7.14-4.deb
          sur le meme site, ou suivre les instructions donnees pour la
          question 1.2 de correction de la meme erreur avec les premieres
          versions de Slackware 3.1.
          Ne pas utiliser cette methode, a moins que vous sachiez ce que
          vous faites!

  1.4)    [SLACKWARE 3.1] Pourquoi ai-je des problemes avec libdl and dlfcn.h manquants ?

          Ceci se manifeste par l'impossibilite de faire l'edition de lien avec des
          fonctions comme dlopen(), dlclose(), etc. pendant la derniere phase de la
          compilation.

          Voir la reponse a la question 1.3. Slackware jusqu'a la
          version 3.0 etait fourni avec cette bibliotheque et le fichier
          "include" et ils ont semble revenir en arriere avec les
          dernieres versions 3.1. Mais les premieres livraisons 3.1
          (avant le 9 Septembre 1996) ne les avaient pas et beaucoup
          de versions CD-ROM ont ete realises a partir de ces premieres
          versions 3.1.

          Il y a eu des rapports indiquant que des systemes ont ete
          abimes suite a l'acces a ces bibliotheques par certains
          programmes pendant leur mise a jour (ce qui n'est pas
          tout a fait surprenant). En consequence, c'est une bonne idee
          de redemarrer le systeme avant l'installation de nouvelles
          bibliotheques et d'avoir le minimum de choses en fonction
          pendant ces mises a niveau. Passer en mode mono-utilisateur
          est certainement aussi une bonne idee!

          La meilleure maniere de corriger cela est d'obtenir le fichier
          ldso.tgz du disque a4 d'une distribution plus recente de
          Slackware 3.1, de decompacter ce fichier a partir du repertoire
          root (/), puis de faire

                  sh install/doinst.sh

          pour terminer l'installation, a 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 recente) 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 systemes (dependant de la configuration de GCC)
          il peut etre necessaire de faire :

                  cd /usr/lib
                  ln -sf /lib/libdl.so .

          Finalement

                  ldconfig

  1.5)    Ma compilation echoue en reclamant le "fichier include" manquant dlfcn.h

          Voir la reponse aux questions 1.3/1.4. N'oubliez pas que si
          vous utilisez un systeme a.out vous devez auparavant avoir
          installe le paquetage dld (qui n'est pas fourni avec la plupart
          des systemes a.out) pour avoir dlfcn.h en entier. Voir Question 1.11.

  1.6)    GCC se plaint d'une option inexistante -fpic

          Les premieres versions de GCC acceptaient soit -fpic soit -fPIC.
          Il apparait que les plus recentes versions (V2.7.2?) requierent -fPIC.
          Si vous utilisez une version ELF de Linux, on peut ignorer cela sans
          probleme, puisque -fPIC est la valeur par defaut.

          Vous pouvez apporter une correction a cela en editant le fichier
          src/Makefile.global et en changeant CFLAGS_SL

  1.7)    J'ai des messages d'avertissement du type :
          "warning- cast from pointer to integer of different size"

          Ils apparaissaient dans les premieres versions de Postgres95 et
          peuvent, sans risque, etre ignores. PostgreSQL V6.0 doit pouvoir
          se compiler sans messages d'avertissement sauf ceux relatifs aux
          fichiers en-tetes systeme (qui peuvent egalement etre ignores
          sans risque).

  1.8)    [SuSE-Linux 4.2-4.4] Ou sont curses et termcap?

          SuSE-Linux 4.2 dispose de ncurses et non pas curses, la version 4.4 possede
          les deux. SuSE-Linux a aussi la bibliotheque termcap dans le repertoire
          /usr/lib/termcap a la plac ede /usr/lib.

          PostgreSQL (jusqu'a V6.0)
          -------------------------
          Renseigner la valeur de CURSES_LIB dans src/Makefile.custom a -lncurses
          (ou faites ceci par l'intermediaire d'un script personnalise).

          Ajouter la ligne suivante a src/Makefile.custom:

                  LDADD_BE+= -L/usr/lib/termcap

          Vous pouvez avoir besoin d'editer src/bin/psql/Makefile et d'effectuer
          la modification de:

                  ifeq ($(PORTNAME), linux)
                     LD_ADD+= -ltermcap
          en:
                  ifeq ($(PORTNAME), linux)
                     LD_ADD+=

          PostgreSQL (V6.1)
          -----------------
          Le script de configuration ne sait pas regarder dans /usr/lib/termcap
          pour trouver la bibliotheque termcap, donc, vous devrez le specifier
          au moment ou l'on vous demande d'indiquer les repertoires complementaires
          dans lesquels il faut chercher.

          Si cela ne marche pas (Je n'ai pas SuSE pour verifier ce qu'il fait),
          alors, apres avoir execute configure, il faudra editer src/Makefile.global
          et ajouter -ltermcap dans la ligne LDFLAGS (a la suite de -lreadline).

          Vous pouvez aussi imposer l'utilisation de ncurses plutot que de curses en
          changeant -lcurses en -lncurses.

  1.9)    Pourquoi ai-je des problemes avec ld.so?

          Si vous avez des problemes avec ld.so, une autre bibliotheque necessaire
          en format ELF pour les liens dynamiques, alors c'est que vous avez bricole
          votre systeme ou (plus vraisemblablement) effectue une mise a niveau de
          Linux.

          Voyez les reponses 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  1.7.14 est la version stable la plus recente du paquetage ld.
          Au moment de la redaction de ce texte, les versions 1.8.x de ld sont
          experimentales.

  1.10)   Pourquoi ai-je les erreurs `yy_flush_buffer undefined'?

          Ce n'est pas reellement specifique a Linux, mais c'est courant sur les
          installations Linux les plus anciennes. Il vous faut une version recente
          de flex (2.5.2 ou suivantes) pour compiler PostgreSQL. Notez que
          flex 2.5.3 a un bogue: voir la Question 3.4.

  1.11)   Comment dois-je compiler PostgreSQL sur un systeme a.out?

          Premierement, vous devez installer la bibliotheque dld. On peut
          l'obtenir sur le site Sunsite sous le nom :
          Linux/libs/dld.3.2.7.tar.gz
          (ftp://sunsite.unc.edu/pub/Linux/libs/dld.3.2.7.tar.gz)

          Deuxiemement, ajouter la ligne suivante au fichier src/Makefile.custom:
                  LINUX_ELF=
          (ou utilisez un script adapte)

  1.12)   Pourquoi make echoue-t-il avec le message :
          yacc -d /disk2/PostgreSQL/src/backend/parser/gram.y
          make- /usr/bin/make- cannot execute binary file

          Ce fut un probleme des premieres versions de Postgres95. Pour PostgreSQL
          on utilise  bison -y par defaut plutot que yacc.

          yacc est generalement implante comme script qui invoque bison -y
          Pour une raison quelconque (certaines versions de make ? certaines
          versions de bash ?) make est incapable d'executer ce fichier script.

          Pour corriger cela, editez simplement src/mk/port/postgres.mk.linux
          et, a la fin du fichier, changez :
                  # YACC = bison -y
          en
                  YACC = bison -y

  1.13)   Que sont les references a libsocket dans X11_LIB  et libnsl dans src/Makefile.global?

          Ce fut un probleme dans la version 1.08 (elles sont specifiques a Sun Solaris).
          Cela a ete corrige dans 1.09 et 6.0

  1.14)   [DEBIAN] Ou se trouve libtermcap?

          Le Linux de Debian est livre sans bibliotheque termcap et utilise ncurses
          (qui a 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 (a la difference de SuSE-Linux --- voir
          la Question 1.8).

          Vous pouvez avoir besoin d'editer src/bin/psql/Makefile et de changer:

                  ifeq ($(PORTNAME), linux)
                     LD_ADD+= -ltermcap
          en:
                  ifeq ($(PORTNAME), linux)
                     LD_ADD+=

  1.15)   [REDHAT] Puis-je trouver PostgreSQL en format RPM ?

          Oui ! Michal Mosiewicz
          (http://www.pdi.lodz.pl/~mimo) a gentiment realise un RPM
          de PostgreSQL V6.0 pour les architectures Intel et l'a telecharge sur
          ftp://ftp.redhat.org/pub/Incoming/Postgres-6.0-1.i386.rpm

          C'est une version pre-compilee, le source RPM est en cours de realisation au
          moment de cette redaction (3 fevrier 1997).

  1.16)   Quand j'essaie de compiler une version de developpement sous linux, la compilation
          echoue en donnant un message du type :
          In file included from /usr/include/sys/sem.h:8,
                   from ipc.c:37:
          /usr/include/asm/bitops.h:32: warning: no previous prototype for Set_bit'
          ....
          make: *** [ipc.o] Error 1

          Le probleme vient du fait que linux ne fournit pas de prototypes pour ces
          fonctions en ligne. La solution consiste a aller dans le repertoire
          .../src/backend/storage/ipc et d'editer le fichier Makefile.
          Changez la ligne
             CFLAGS+=$(INCLUDE_OPT)
          en
             CFLAGS+=$(INCLUDE_OPT) -Wno-error

          Faites la meme chose dans le repertoire ../src/backend/storage/lmgr.

  1.17)   Quand on compile postgres, gcc renvoie le message 'signal 11' et s'interrompt.
          Plus precisement :
             gcc: Internal compiler error: program cc1 got fatal
                  signal 11

          Ceci peut etre du a un probleme de materiel/memoire. PostgreSQL est un gros
          programme, et de grandes compilations gcc (telles que compiler
          PostgreSQL ou recompiler le noyau) sollicitent la memoire plus que
          la plupart des autres programmes entrainant des erreurs qui ne se
          produisent pas en utilisation normale. Peu de systemes d'exploitation
          se trouvent dans la situation de solliciter le materiel de cette facon
          et donc, vous pouvez ne jamais voir ce type de problemes sous DOS/Windows.

          Pour des informations complementaires sur ce sujet consulter :
             http://www.bitwizard.nl/sig11

  1.18)   Puis-je installer la version 6.1.1 sous MkLinux?

          Tatsuo Ishii  l'a fait sous MkLinux DR2.1 update2 apres application d'une
          petite rustine disponible a :
          ftp://ftp.sra.co.jp/pub/cmd/postgres/6.1.1/mklinux.patch.gz

  ----------------------------------------------------------------------
  Section 2:      Compilation des programmes accessoires
  ----------------------------------------------------------------------

  2.1)    L'editeur de liens n'arrive pas a trouver libX11 quand on compile pgtclsh

          Ajoutez ce qui suit a src/Makefile.custom
                  X11_LIBDIR = /usr/X11R6/lib

  ----------------------------------------------------------------------
  Section 3:      Problemes d'execution
  ----------------------------------------------------------------------

  3.1)    J'ai une erreur indiquant _fUnKy_POSTPORT_sTuFf_ non defini quand
          j'execute des scripts tels que createuser

          C'est un bogue dans la V1.06-V1.07 de Postgres et il est corrige dans
          les versions V1.08 et au-dessus.

  3.2)    Je lance postmaster et ensuite le systeme affiche 'Bad system call(Core
          dumped)'

          Ceci indique que vous n'avez pas compile le support de la memoire partagee
          dans votre noyau. Il vous faut recompiler le noyau Linux en incluant cette
          fonctionnalite.

  3.3)    Quand j'essaie de lancer le Postmaster, pourquoi ai-je une erreur de la forme
          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

  3.4)    Pourquoi createuser ne fonctionne-t-il pas?

          Il y a un probleme avec la Version 2.5.3 de GNU flex et de createuser.
          Vos options sont soit de revenir a la version V2.5.2 de flex, d'appliquer une
          rustine a la version V2.5.3 (fournie dans doc/README.flex) soit d'attendre
          la version V2.5.4 qui corrigera ce bogue.

  3.5)    Pourquoi ai-je une erreur du type :
          IpcMemoryCreate- memKey=155356396 , size=760632 ,
          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.

  3.6)    Pourquoi psql echoue avec
          psql- can't load library 'libpq.so.1'

          Psql a ete compile pour etre lie dynamiquement avec la bibliotheque libpq.

          Pour remedier a cela, vous devez vous connecter en tant que root et editer le
          fichier
                  /etc/ld.so.conf
          Ajouter une simple ligne a la fin qui donne le nom du repertoire de la bibliotheque
          PostgreSQL (le sous-repertoire lib de votre installation pour
          PostgreSQL) et executer
                  /sbin/ldconfig -v

          Autrement, (et si vous n'avez pas l'acces root), vous pouvez utiliser la variable
          d'environnement LD_LIBRARY_PATH.

          La variable LD_LIBRARY_PATH contient une liste des chemins, separes par le
          signe : (deux points) qui doivent etre utilises pour retrouver les bibliotheques
          partagees. Les chemins indiques dans cette liste sont parcourus avant ceux specifies
          par ldconfig.

          Par consequent, sous Bash, vous devrez faire quelque-chose comme :
                  export LD_LIBRARY_PATH='PathToPGSQL'/lib
          ou, si vous utilisez tcsh
                  setenv LD_LIBRARY_PATH 'PathToPGSQL'/lib
          en remplacant 'PathToPGSQL' par le chemin approprie du sommet de
          votre repertoire PostgreSQL.

          Notez que la commande ldd peut etre utilisee pour visualiser, dans le cas
          d'un executable lie dynamiquement, la liste des chemins de toutes les
          bibliotheques partagees dont depend l'executable.

  3.7)    Autres comportements etranges

          Je ne suis pas certain du genre de symptomes que cela peut donner,
          sauf que rien ne fonctionne correctement, mais il a ete indique
          qu'il faut etre vigilant a ce que le chargeur dynamique charge
          la bonne version de la bibliotheque libpq. Si vous en avez une
          version ancienne apparaissant dans le chemin de vos bibliotheques
          (par exemple dans /usr/lib) elle peut etre chargee en lieu et place
          de la nouvelle version que vous avez l'intention de charger.
          Soyez surs de la tenir en dehors du chemin et consultez la
          question 3.6 concernant les details du chargement d'une bibliotheque.

  3.8)    Si l'on arrete le systeme alors que PostgreSQL est en cours d'execution,
          alors, Linux lance toujours un fsck sur le disque au re-demarrage.

          Ce comportement a ete signale quelques fois et il semble que cela
          resulte du lancement de PostgreSQL dans /etc/inittab comme on
          le suggere dans le document d'installation : INSTALL.

          En consequence, nous vous recommandons de lancer le postmaster a partir
          d'un script rc . Avec une version de type Slackware, il faudra modifier
          /etc/rc.d/rc.local pour demarrer lepostmaster. Avec une version de type
          RedHat vous devrez creer un script de style SysV style dans
          /etc/rc.d/rc3.d base sur le fichier squelette /etc/rc.d/init.d.

          Il y a un exemple de fichier dans contrib/linux/postgres.init

          Voici un autre exemple de fichier fourni par John Robinson
          qu'il faudra modifier selon vos besoins :

  #!/bin/sh
  #
  # postgreSQL.init Ce script shell script est charge de lancer et de stopper
  #               le postmaster PostgreSQL.
  #

  # Bibliotheque de fonctions.
  \&. /etc/rc.d/init.d/functions

  # Configuration reseau.
  \&. /etc/sysconfig/network

  # Verification du fonctionnement du reseau.
  [ $(NETWORKING) = "no" ] && exit 0

  # Regarder comment on a ete appele.
  case "$1" in
    start)
          # Start daemons.
          echo -n "Demarrage du demon Postmaster postgres:"
          if [ -z "`pidofproc postmaster`" ]
          then
                  su postgres -c "/usr/local/pgsql/bin/postmaster
                                        -D /home/postgreSQL/data -p 5432 &"
                  echo -n " postmaster"
          else
                  echo -n " (deja en fonctionnement)"
          fi
          echo
          touch /var/lock/subsys/postgres
          ;;
    stop)
          # Arret des demons.
          echo -n "Arret du demon Postmaster postgres: "
          killall -TERM postmaster 2>/dev/null
          killall -TERM postgres 2>/dev/null
          echo
          rm -f /var/lock/subsys/postgres
          ;;
    *)
          echo "Usage: postgres (start|stop)"
          exit 1
  esac

  exit 0

  3.9)    Pourquoi Query 32 dans le test de regression dure-t-il si longtemps ?

          Ceci est du a un bogue dans les scripts de regression qui ne se produit
          que sur les machines sous Linux. A ma connaissance, il y a deux moyens de
          les contourner
          (information donnee par Tatsuo Ishii ):

          1. remplacer ce qui suit dans regress.sh:
                  time postgres -texecutor -tplanner -Q bench < bench.sql
          par :
                  postgres -texecutor -tplanner -Q bench < bench.sql

          2. apres avoir execute le test, enlever la toute derniere ligne a la fin du
          fichier bench.out, quelquechose comme :
                  85.86user 114.47system 4:49.20elapsed 69%CPU (0avgtext+0avgdata 0maxresident)k
          et tapez :
                  sh ./perquery < bench.out > & bench.out.perquery

  ----------------------------------------------------------------------------
  Dr. Andrew C.R. Martin                             University College London
  EMAIL: (Work) martin@biochem.ucl.ac.uk    (Home) andrew@stagleys.demon.co.uk
  URL:   http://www.biochem.ucl.ac.uk/~martin
  Tel:   (Work) +44(0)171 419 3890                    (Home) +44(0)1372 275775

  4400..  FFAAQQ IIRRIIXX--PPoossttggrreeSSQQLL

  4400..11..  DDeerrnniieerree vveerrssiioonn ddee llaa FFAAQQ IIRRIIXX--PPoossttggrreeSSQQLL

  Cette  FAQ  est incluse ici puisque tous les utilisateurs n'ont pas de
  butineurs tels que Netscape et acces a  l'Internet.  Les  utilisateurs
  peuvent  utiliser GnuInfo, Ghostview, l'editeur vi ou la commande man.
  Ce document a ete genere en 10 formats differents  tels  que  GnuInfo,
  RTF,  Texte  standard, Man page, Postscript etc.. et est distribue sur
  les CDROM Linux. Veuillez consultez la derniere version de  cette  FAQ
  qui  se trouve a <http://www.postgresql.org/docs/faq-english.shtml> si
  vous avez acces a l'Internet."

  Cette FAQ a ete mise ici pour vous rendre service.

  4400..22..  EExxttrraaiitt ddee llaa FFAAQQ IIRRIIXX dduu ssiittee WWeebb pprriinncciippaall ddee PPoossttggrreeSSQQLL

  Si vous disposez d'un acces a internet, veuillez cliquez sur cette URL
  maintenant pour obtenir la derniere version

  +o  <http://www.postgresql.org/docs>

  ======================================================
  Foire Aux Questions (FAQ) for PostgresSQL >=V6.1
  Specifique IRIX
  A LIRE EN PARALLELE AVEC LA FAQ NORMALE
  ======================================================
  Derniere mise a jour :           Lundi 4 decembre 1997 10:20:00 GMT

  Gestionnaire actuel :     Andrew C.R. Martin (martin@biochem.ucl.ac.uk)
  Auteur original     :     Andrew C.R. Martin (martin@biochem.ucl.ac.uk)

  Modifications dans cette version (* = modifie, + = nouveau, - = supprime):
  +1.9)   Pourquoi IRIX5 lex echoue avec PostgreSQL 6.2.1?

  Ce fichier est divise approximativement comme suit :
  1.*)    Installation de PostgreSQL
  2.*)    Des-installation de PostgreSQL
  3.*)    Extension de PostgreSQL

  Reponses aux questions :
  1.1)    De quels elements supplementaires ai-je besoin pour installer Postgres95 sous Irix ?
  1.2)    Quelles modifications dois-je apporter a src/Makefile.global ?
  1.3)    Quelles sont les references a libsocket dans X11_LIB et a libnsl dans
          src/makefile.global ?
  1.4)    Dois-je faire d'autres modifications ?
  1.5)    Puis-je installer PostgreSQL sous Irix 6.x ?
  1.6)    Le make echoue avec le message suivant :
          ld32: ERROR 4: Conflicting flag setting: -call_shared
  1.7)    Pourquoi l'edition de liens ne peut-elle se faire ? (Problemes avec lorder)
  1.8)    J'ai des problemes majeurs avec Irix 6!
  1.9)    Pourquoi lex echoue-t-il avec PostgreSQL 6.2.1 ?
  2.1)    Pourquoi ne puis-je pas deplacer les fichiers executables ?
  3.1)    Comment compiler un programme C pour creer une fonction pour etendre PostgreSQL ?

  ----------------------------------------------------------------------
  Section 1:      Installation de PostgreSQL
  ----------------------------------------------------------------------

  1.1)    De quels elements supplementaires ai-je besoin pour installer Postgres95 sous Irix?

          Vous *devez* avoir les elements suivants installes:
          a) Gnu make (installe sous le nom gmake)

          Nous vous recommandons d'installer ce qui suit :
          a) GNU install (installe sous le nom ginstall)
             ( fait partie du paquetage GNU fileutils )

          Vous pouvez choisir d'installer :
          a) La bibliotheque GNU readline (si vous desirez que psql ait le
             support de readline).
          b) Tcl/Tk (si vous souhaitez compiler pgtclsh)

  1.2)    Quelles modifications dois-je apporter a src/Makefile.global ou
          src/Makefile.custom?

          La maniere la plus simple de faire cela est d'utiliser le script
          personnalise dans le repertoire src.

          Vous *devez* renseigner les variables suivantes :
                  PORTNAME=       irix5

          Vous aurez aussi besoin de changer ce qui suit pour l'adapter a
          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 egalement faire toutes les autres modifications dont vous avez besoin
          comme indique dans le fichier INSTALL et dans Makefile.global

  1.3)    Que sont les references a libsocket dans X11_LIB et a libnsl dans
          src/Makefile.global?

          Ce fut un probleme dans la version 1.08 (elles sont specifiques a Sun Solaris).
          Cela a ete corrige dans 1.09 et au-dessus.

  1.4)    Dois-je faire d'autres modifications ?

          Si vous avez installe le programme GNU install (ginstall), vous
          devriez ajouter la ligne suivante a src/Makefile.custom:
                  CUSTOM_INSTALL=ginstall

          Pour une explication sur ce point, voir la Question 2.1
          Ginstall fait partie du paquetage GNU fileutils.

  1.5     Puis-je installer PostgreSQL sous Irix 6.4 ?

          Irix 6.2-6.4 a un bogue dans ld qui l'empeche de prendre en compte
          correctement les adresses des procedures statiques quand les fichiers
          objets sont assembles en fichiers objets plus grands en utilisant 'ld -r'.
          Ce bogue a ete rapporte a Silicon Graphics.

          Une possibilite consiste a utiliser la version GNU de ld. Autrement,
          la rustine suivante peut etre appliquee pour le contourner.
          (Fourni par Bob Bruccoleri

  *** ./backend/Makefile.orig     Thu May 22 00:00:15 1997
  --- ./backend/Makefile  Thu Jun  5 16:47:27 1997
  ***************
  *** 54,60 ****
    all: postgres $(POSTGRES_IMP) global1.bki.source local1_template1.bki.source

    postgres: $(OBJS) ../utils/version.o
  !       $(CC) -o postgres $(OBJS) ../utils/version.o $(LDFLAGS)

    $(OBJS): $(DIRS:%=%.dir)

  --- 54,64 ----
    all: postgres $(POSTGRES_IMP) global1.bki.source local1_template1.bki.source

    postgres: $(OBJS) ../utils/version.o
  ! #     $(CC) -o postgres $(OBJS) ../utils/version.o $(LDFLAGS)
  !       -rm -f *.o
  !       find . -name "*.o" -exec cp \(\) . \;
  !       rm -f SUBSYS.o
  !       $(CC) -o postgres *.o ../utils/version.o $(LDFLAGS)

    $(OBJS): $(DIRS:%=%.dir)

  1.6)    Le make echoue avec le message suivant :
          ld32: ERROR 4: Conflicting flag setting: -call_shared

          Si gmake echoue dans .../src/backend pendant la construction de
          obj/ACCESS.o avec un message de ld32, vous pouvez corriger cela
          en utilisant ld comme variable d'environnement LD au lieu de cc.

          Le probleme a ete observe sous Irix 5.3 lors de la compilation de
          Postgres95-1.09 et de PostgreSQL-6.2Beta6, mais sur quelques
          systemes ils se compilent sans de tels problemes.

          Une correction est fournie par Brian Sanders (bsanders@netcom.com,
          brian@fresnelsoft.com)

  1.7)    Pourquoi l'edition de liens ne peut-elle se faire ? (Problemes avec lorder)

          Selon les pages de manuel d'IRIX, lorder est inutile, mais inoffensif
          sous IRIX. Cependant, il a cause des problemes a quelques-uns qui
          utilisent IRIX 6.2.

          La solution consiste a ajouter la ligne suivante a
          .../src/makefiles/Makefile.irix5

          MK_NO_LORDER=true

  1.8)    J'ai des problemes majeurs avec IRIX 6!

          Ce qui suit est cite directement de Bob Bruccoleri

  Il y a un bogue reellement serieux dans le compilateur (7.1)
  sur Irix 6.x, et l'erreur indiquee par Lasse Petersen en est le resultat.
  Voici le message original. Je ne sais pas si toutes les modifications ont ete
  integrees dans la version actuelle.

  Date: vendredi 06 Juin 1997 17:12:20 -0400 (EDT)
  From: bruc@bms.com (Robert Bruccoleri)
  Subject: [PORTS] Rustines pour Irix 6.4

  J'ai trouve comment compiler PostgreSQL sur Irix 6.4 en utilisant le mode -n32
  du compilateur et la version 7.1 du compilateur C. (Le compilateur n32 utilise
  un adressage sur 32 bits, mais permet d'acceder a tout le jeu d'instructions
  de MIPS4 instruction.)
  Il y avait plusieurs problemes  :

  1) La commande ld n'est pas referencee comme macro dans tous les fichiers Makefiles.
  Sur cette plate-forme, il faut ajouter -n32 a toutes les commandes ld. Les fichiers
  Makefile ont ete modifies en consequence.

  2) Il y a un bogue dans "ld" qui prend mal en compte les adresses des procedures
  statiques quand les fichiers objets sont assembles pour fabriquer des fichiers objets
  plus grands en utilisant "ld -r". A cause de cela, j'ai insere un bidouillage dans
  src/backend/Makefile pour eviter tous les fichiers SUBSYS.o et ne lier que les
  objets. J'ai contacte SGI a propos de ce probleme, et, heureusement, il sera
  corrige dans un futur proche.

  3) Un paquet de messages d'alerte (warnings) sont generes par le compilateur. Depuis
  que les tests de regression s'executent sans erreurs, je n'ai plus chercher a y
  remedier. Si quelqu'un desire le journal de bord de la compilation, qu'il me le fasse
  savoir, je lui enverrai par email.

  La version de postgresql etait 970602. Voici le fichier Makefile.custom :

  CUSTOM_COPT = -O2 -n32
  MK_NO_LORDER = 1
  LD = ld -n32
  CC += -n32

  Voici les rustines :

  *** ./backend/access/Makefile.orig      Sun Nov 10 00:00:15 1996
  - --- ./backend/access/Makefile Tue Jun  3 10:22:32 1997
  ***************
  *** 8,13 ****
  - --- 8,16 ----
    #
    #-------------------------------------------------------------------------

  + SRCDIR = ../..
  + include ../../Makefile.global
  +
    OBJS = common/SUBSYS.o gist/SUBSYS.o hash/SUBSYS.o heap/SUBSYS.o \
           index/SUBSYS.o rtree/SUBSYS.o nbtree/SUBSYS.o transam/SUBSYS.o

  *** ./backend/bootstrap/Makefile.orig   Fri Apr 18 06:00:23 1997
  - --- ./backend/bootstrap/Makefile      Tue Jun  3 10:23:59 1997
  ***************
  *** 38,44 ****
    all: SUBSYS.o

    SUBSYS.o: $(OBJS)
  !       ld -r -o SUBSYS.o $(OBJS)

    # bootstrap.o's dependency on bootstrap_tokens.h is computed by the
    # make depend, but we state it here explicitly anyway because
  - --- 38,44 ----
    all: SUBSYS.o

    SUBSYS.o: $(OBJS)
  !       $(LD) -r -o SUBSYS.o $(OBJS)

    # bootstrap.o's dependency on bootstrap_tokens.h is computed by the
    # make depend, but we state it here explicitly anyway because

  *** ./backend/Makefile.orig     Thu May 22 00:00:15 1997
  - --- ./backend/Makefile        Thu Jun  5 16:47:27 1997
  ***************
  *** 54,60 ****
    all: postgres $(POSTGRES_IMP) global1.bki.source local1_template1.bki.source

    postgres: $(OBJS) ../utils/version.o
  !       $(CC) -o postgres $(OBJS) ../utils/version.o $(LDFLAGS)

    $(OBJS): $(DIRS:%=%.dir)

  - --- 54,64 ----
    all: postgres $(POSTGRES_IMP) global1.bki.source local1_template1.bki.source

    postgres: $(OBJS) ../utils/version.o
  ! #     $(CC) -o postgres $(OBJS) ../utils/version.o $(LDFLAGS)
  !       -rm -f *.o
  !       find . -name "*.o" -exec cp \(\) . \;
  !       rm -f SUBSYS.o
  !       $(CC) -o postgres *.o ../utils/version.o $(LDFLAGS)

    $(OBJS): $(DIRS:%=%.dir)

  ***************
  *** 116,122 ****
    install: $(LIBDIR) $(BINDIR) $(HEADERDIR) postgres $(POSTGRES_IMP) fmgr.h\
             global1.bki.source local1_template1.bki.source \
             libpq/pg_hba.conf.sample optimizer/geqo/pg_geqo.sample
  !
          $(INSTALL) $(INSTL_EXE_OPTS) postgres $(BINDIR)/postgres
    ifeq ($(MAKE_EXPORTS), true)
          $(INSTALL) $(INSTLOPTS) $(POSTGRES_IMP) $(LIBDIR)/$(POSTGRES_IMP)
  - --- 120,126 ----
    install: $(LIBDIR) $(BINDIR) $(HEADERDIR) postgres $(POSTGRES_IMP) fmgr.h\
             global1.bki.source local1_template1.bki.source \
             libpq/pg_hba.conf.sample optimizer/geqo/pg_geqo.sample
  !
          $(INSTALL) $(INSTL_EXE_OPTS) postgres $(BINDIR)/postgres
    ifeq ($(MAKE_EXPORTS), true)
          $(INSTALL) $(INSTLOPTS) $(POSTGRES_IMP) $(LIBDIR)/$(POSTGRES_IMP)

  *** ./backend/optimizer/Makefile.orig   Wed Feb 19 12:00:34 1997
  - --- ./backend/optimizer/Makefile      Tue Jun  3 10:39:47 1997
  ***************
  *** 8,13 ****
  - --- 8,16 ----
    #
    #-------------------------------------------------------------------------

  + SRCDIR= ../..
  + include ../../Makefile.global
  +
    all: submake SUBSYS.o

    OBJS = path/SUBSYS.o plan/SUBSYS.o prep/SUBSYS.o util/SUBSYS.o geqo/SUBSYS.o

  *** ./backend/libpq/pqcomprim.c.orig    Mon May 26 00:00:23 1997
  - --- ./backend/libpq/pqcomprim.c       Fri Jun  6 16:02:24 1997
  ***************
  *** 32,40 ****
    #    define hton_l(n) (ntoh_l(n))
    #  else       /* BYTE_ORDER != BIG_ENDIAN */
    #    if BYTE_ORDER == PDP_ENDIAN
  ! #      #error PDP_ENDIAN macros not written yet
    #    else     /* BYTE_ORDER !=  anything known */
  ! #      #error BYTE_ORDER not defined as anything understood
    #    endif    /* BYTE_ORDER == PDP_ENDIAN */
    #  endif      /* BYTE_ORDER == BIG_ENDIAN */
    #endif                /* BYTE_ORDER == LITTLE_ENDIAN */
  - --- 32,40 ----
    #    define hton_l(n) (ntoh_l(n))
    #  else       /* BYTE_ORDER != BIG_ENDIAN */
    #    if BYTE_ORDER == PDP_ENDIAN
  ! #      error PDP_ENDIAN macros not written yet
    #    else     /* BYTE_ORDER !=  anything known */
  ! #      error BYTE_ORDER not defined as anything understood
    #    endif    /* BYTE_ORDER == PDP_ENDIAN */
    #  endif      /* BYTE_ORDER == BIG_ENDIAN */
    #endif                /* BYTE_ORDER == LITTLE_ENDIAN */

  *** ./backend/storage/Makefile.orig     Sun Nov 10 00:01:06 1996
  - --- ./backend/storage/Makefile        Tue Jun  3 10:41:29 1997
  ***************
  *** 8,13 ****
  - --- 8,16 ----
    #
    #-------------------------------------------------------------------------

  + SRCDIR= ../..
  + include ../../Makefile.global
  +
    all: submake SUBSYS.o

    OBJS = buffer/SUBSYS.o file/SUBSYS.o ipc/SUBSYS.o large_object/SUBSYS.o \

  1.9)    Pourquoi lex echoue-t-il avec PostgreSQL 6.2.1 ?

          On a indique que IRIX 5.3 lex echouait dans postgresql-6.2.1/src/backend/parser
          avec l'erreur :

          lex scan.l
          "scan.l":line 86: Error: Invalid request %x xc
          gmake[2]: *** [scan.c] Error 1

          La reponse est qu'il faut utiliser GNU flex 2.5.4 ou ulterieur. Utilisez la
          commande
             flex --version
          pour verifiez que votre version de flex est assez recente

  ----------------------------------------------------------------------
  Section 2:      Des-installation de PostgreSQL
  ----------------------------------------------------------------------

  2.1)    Pourquoi ne puis-je pas deplacer les fichiers executables?

          Par defaut, 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 destinee a l'utilisateur final; il possede l'effet de bord
          interessant de changer le proprietaire des fichiers qu'ils installe en root.

          Vous devriez encore pouvoir detruire les fichiers puisque vous (utilisateur
          postgres) etes proprietaire du repertoire dans lequel ils sont stockes.

          Le programme install normal de IRIX ne peut pas etre utilise 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

  ----------------------------------------------------------------------
  Section 3:      Extension de PostgreSQL
  ----------------------------------------------------------------------

  3.1)    Comment dois-je compiler un programme C pour creer une fonction d'extension a
          Postgres95

          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

  ----------------------------------------------------------------------------
  Dr. Andrew C.R. Martin                             University College London
  EMAIL: (Work) martin@biochem.ucl.ac.uk    (Home) andrew@stagleys.demon.co.uk
  URL:   http://www.biochem.ucl.ac.uk/~martin
  Tel:   (Work) +44(0)171 419 3890                    (Home) +44(0)1372 275775

  4411..  NNoottiiccee ddee CCooppyyrriigghhtt

  Copyright (c) 1997 Al Dev (Alavoor Vasudevan). Tous droits reserves.

  AUCUNE RESPONSABILITE  NE  SAURAIT  ETRE  RETENUE  POUR  DES  DOMMAGES
  CONSECUTIFS A L'UTILISATION DE TOUT OU PARTIE DE CE DOCUMENT. En aucun
  cas l'auteur ou le traducteur de ce document ne pourra etre tenu  pour
  responsable  vis-a-vis  de de qui que ce soit pour tous dommages quels
  qu'ils  soient  (y  compris  et  sans  limitation,  special,  fortuit,
  consecutif,  blessures  directes  ou  indirectes  pour  les personnes,
  pertes  financieres  dues  au  manque  a  gagner,   a   l'interruption
  d'activite, pertes d'informations commerciales ou toutes autres pertes
  financieres) resultant de l'utilisation de ce document.

  L'auteur  et   le   traducteur   n'offrent   aucunes   garanties   sur
  l'adequation,  l'utilite  ou  la  valeur marchande de ce document. Les
  marques, les compagnies et les noms de  produits  mentionnes  dans  ce
  document sont des marques de fabrique ou des marques deposees de leurs
  proprietaires  respectifs.  Veuillez  vous  referer  aux  notices   de
  copyright individuelles des marques, compagnies et produits mentionnes
  dans ce document. Il  est  de  votre  responsabilite  de  lire  et  de
  comprendre        les       notices       de       copyright       des
  organisations/compagnies/produits/auteurs mentionnes dans ce  document
  avant d'utiliser leurs informations respectives.

  4422..  AAppppeennddiiccee AA -- SSyynnttaaxxee ddee ll'' AANNSSII//IISSOO SSQQLL 11999922

  Ce fichier contient la grammaire en BNF du langage, arborescence
  exploree d'abord en profondeur, realisee le 27-AOUT-1992 11:03:41.64.
  La version specifique de BNF donnee 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>

  4433..  AAppppeennddiiccee BB -- SSyynnttaaxxee ddee ll''AANNSSII//IISSOO SSQQLL 11999988 -- SS

  Specification de la syntaxe SQL ANSI/ISO SQL 1998 egalement appele 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 represente l'etat de l'implantation pour la plupart
  des vendeurs.  Il n'y a que peu de differences entre SQL-92 ENTRY LEVEL
  et SQL-89 Niveau II, mais deux d'entre elles sont tres importantes:

     - Les identificateurs delimites

     - Le traitement de l'option WITH CHECK sur les vues CASCADE par defaut.
       Dans SQL-89 la valeur par defaut etait [en realite] LOCAL.

  pour le langage, et effectuees aux environs du  1-SEP-1993 15:13:55.88.
  La version BNF specifique incluse ici correspond a :
    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>

  4444..  AAppppeennddiiccee CC -- TTuuttoorriieell SSQQLL aa ll''uussaaggee ddeess ddeebbuuttaannttss

       Le didacticiel SQL est inclus dans la distribution de PostgreSQL.
       Les scripts du didacticiel SQL se trouvent dans le repertoire src/tutorial

  On       peut       trouver       ce       didacticiel      SQL      a
  <http://w3.one.net/~jhoffman/sqltut.htm>

  Pour les commentaires ou suggestions, envoyer un courrier electronique
  a jhoffman@one.net

  Vous     pouvez     egalement    souhaiter    jeter    un    oeil    a
  <http://w3.one.net/~jhoffman/index.html>

  John Hoffman suggere de visiter les sites suivants :

  <http://www.contrib.andrew.cmu.edu/~shadow/sql.html> Reference SQL

  <http://www.inquiry.com/techtips/thesqlpro/> Demandez le Pro. de SQL

  <http://www.inquiry.com/techtips/thesqlpro/usefulsites.html>     Sites
  utiles au Pro. du SGBD Relationnel SQL

  <http://infoweb.magi.com/~steve/develop.html>  Les Sites de sources du
  programmeur SGBD

  <http://info.itu.ch/special/wwwfiles>  Allez-y et regardez le  fichier
  comp_db.html

  <http://www.compapp.dcu.ie/databases/f017.html> Ingredients pour SGBD

  <http://www.stars.com/Tutorial/CGI/> Creation Web

  <http://wfn-shop.princeton.edu/cgi-bin/foldoc>            Dictionnaire
  d'Informatique

  <http://www-ccs.cs.umass.edu/db.html> DBMS Lab/Liens

  SQL  FAQ   <http://epoch.CS.Berkeley.EDU:8000/sequoia/dba/montage/FAQ>
  Allez-y et regardez le fichier SQL_TOC.html

  <http://chaos.mur.csu.edu.au/itc125/cgi/sqldb.html> SGBD SQL

  <http://www.it.rit.edu/~wjs/IT/199602/icsa720/icsa720postings.html>
  Page de Conception de Bases de Donnees RIT

  <http://www.pcslink.com/~ej/dbweb.html> Site de liens vers  des  Bases
  de Donnees <http://www.eng.uc.edu/~jtilley/tutorial.html> Didacticiels
  de programmation sur le Web

  <http://www.ndev.com/ndc2/support/resources.htp>  Ressources  pour  le
  Developpement

  <http://ashok.pair.com/sql.htm> Liste de Requetes

  <http://jazz.external.hp.com/training/sqltables/main.html>  IMAGE  SQL
  Diverses

  <http://www.eit.com/web/netservices.html> Liste de Ressources Internet

  Voici, ci-dessous, un extrait de la page d'accueil du didacticiel SQL.

  Introduction au Langage de Requete Structure

  Version 3.31

  Cette page contient un didacticiel du Langage de Requete Structure( Structured
  Query Language, egalement connu sous le nom de SQL). Ce didacticiel constitue
  une nouveaute sur le World Wide Web, car c'est le premier didacticiel SQL
  complet disponible sur l'Internet. SQL permet l'acces aux donnees dans les
  systemes  de gestion de bases de donnees relationnels tels que Oracle,
  Sybase, Informix, Microsoft SQL Server, Access, et autres en permettant aux
  utilisateurs de decrire les donnees qu'ils desirent obtenir. SQL permet aussi
  aux utilisateurs de definir l'organisation des donnees dans la base et de les
  manipuler. Le but de cette page est de decrire l'utilisation de SQL, et de
  donner des exemples. C'est le langage ANSI SQL, ou standard SQL, qui sera
  utilise dans ce document. Il ne sera pas question ici des fonctionnalites
  specifiques a un SGBD particulier, qui seront traitees dans la section "SQL
  non-standard". Nous vous recommandons d'imprimer cette page afin de pouvoir
  vous referer facilement aux differents exemples.
  ----------------------------------------------------------------------------
  Table des matieres

       Principes fondamentaux de l'instruction SELECT
       Selection Conditionnelle
       Operateurs Relationnels
       Conditions Composees
       IN & BETWEEN
       Utilisation de LIKE

       Jointures
       Cles
       Realisation d'une Jointure
       Elimination des Doubles
       Alias & In/Sous-requetes

       Fonctions d'Agregation
       Vues
       Creation de Nouvelles Tables
       Modification des Tables
       Ajout de Donnees
       Suppression de Donnees
       Mise a Jour des Donnees

       Index
       GROUP BY & HAVING
       Sous-requetes Supplementaires
       EXISTS & ALL
       UNION & Jointures Externes
       SQL Integre
       Questions Courantes sur SQL
       SQL Non-standard
       Resume de la Syntaxe
       Liens Importants

  ----------------------------------------------------------------------------
  Principes fondamentaux de l'instruction SELECT

  Dans une base de donnees relationnelle, les donnees sont stockees dans des
  tables. Par exemple,  une table pourrait mettre en relation le Numero de
  Securite Sociale, le Nom et l'Adresse:

                          TableAdresseEmploye

   NSS      Prenom    Nom       Adresse        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 employe.
  On utilisera SELECT, comme ceci :

  SELECT Prenom, Nom, Adresse, Ville, Etat
  FROM TableAdresseEmploye;

  Voici le resultat de l'interrogation de notre base de donnees :

   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 donnees de la table TableAdresseEmploye les colonnes nommees Prenom, Nom,
  Adresse, Ville et Etat. Noter que les noms de colonnes et les noms de tables
  sont sans espaces... ils doivent etre saisis en un seul mot; et que
  l'instruction se termine par un point-virgule (;). La forme generale 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 a taper tous les noms
  de colonne, utiliser :

  SELECT * FROM NomTable;

  Chaque Systeme de Gestion de Base de Donnees (SGBD) et chaque logiciel de
  base de donnees utilisent differentes methodes pour se connecter a la base
  de donnee et pour entrer les instructions SQL; consultez le "guru" de votre
  ordinateur pour qu'il vous aide a vous connecter de facon a pouvoir utiliser
  SQL.
  ----------------------------------------------------------------------------
  Selection Conditionnelle

  Pour etudier plus avant l'instruction SELECT , jetons un oeil a un nouvel exemple de table
  (exemple uniquement hypothetique) :

                        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

  ----------------------------------------------------------------------------
  Operateurs Relationnels

  Il y a six Operateurs Relationnels en SQL, et, apres les avoir presentes,
  nous verrons comment les utiliser :

   =            Egal
   <> or !=
   (voir le manuel) Different
   <            Plus Petit Que
   >            Plus Grand Que
   <=           Plus Petit Que ou Egal a

   >=           Plus Grand Que ou Egal a

  La clause WHERE est utilisee pour specifier que l'on affichera seulement
  certaines ligne de la table, selon un critere definit par cette clause WHERE.
  Ce sera plus clair en prenant une paire d'exemples.

  Si l'on desire voir les numeros d'identification des employes (EMPLOYEEIDNO)
  dont le salaire est egal ou superieur a 50 000, on utilisera la requete
  suivante :

  SELECT EMPLOYEEIDNO
  FROM EMPLOYEESTATISTICSTABLE
  WHERE SALARY >= 50000;

  Noter que le symbole >= (plus grand que ou egal a) est utilise, puisque l'on
  desire voir tout ceux qui gagnent plus de 50 000, ou 50 000, sur la meme
  liste. On aura l'affichage :

  EMPLOYEEIDNO
  ------------
  010
  105
  152
  215
  244

  La description de WHERE, SALARY >= 50000, est appelee une condition. On pourrait
  effectuer le meme traitement sur des colonnes de texte :

  SELECT EMPLOYEEIDNO
  FROM EMPLOYEESTATISTICSTABLE
  WHERE POSITION = 'Manager';

  Ceci entrainera l'affichage des Numeros d'Identification de tous les Managers.
  En general, avec les colonnes contenant du texte, n'utiliser que egal a ou
  different de, et assurez vous que tout texte apparaissant dans l'instruction
  est entoure d'apostrophes (').

  ----------------------------------------------------------------------------
  Conditions plus complexes: Conditions Composees

  L'operateur AND (ET) combine deux ou plusieurs conditions et n'affiche une
  ligne que si cette ligne satisfait TOUTES les conditions requises (i.e. ou
  toutes les conditions sont realisees). Par exemple, pour afficher tout le
  personnel gagnant plus 40 000, ecrire :

  SELECT EMPLOYEEIDNO
  FROM EMPLOYEESTATISTICSTABLE
  WHERE SALARY > 40000 AND POSITION = 'Staff';

  L'operateur 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 recoivent moins de 10
  000 en participation aux benefices, utilisez la requete suivante :

  SELECT EMPLOYEEIDNO
  FROM EMPLOYEESTATISTICSTABLE
  WHERE SALARY < 40000 OR BENEFITS < 10000;

  Les operateurs AND et OR peuvent etre combines, 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 superieure a 60 000 et celle de position est egale a
  Manager, puis, a partir de cette liste de lignes, SQL recherche alors celles
  qui satisfont a la condition AND (ET) precedente ou a la condition specifiant
  que la colonne Indemnites est superieure a  12 000. En consequence, SQL n'affiche
  seulement que cette seconde liste de lignes, en gardant a l'esprit que tous ceux
  dont les Indemnites sont superieures a 12 000 en feront partie puisque l'operateur
  OR (OU) inclue la ligne si l'une des conditions est verifiee. Notez en passant
  que l'operation AND (ET) est effectuee en premier.

  Pour generaliser ce processus, SQL effectue l(es) operation(s) AND pour determiner
  les lignes ou l(es) operation(s) AND sont verifiees (souvenez-vous bien : toutes
  les conditions sont verifiees), puis ces resultats sont utilises pour tester les
  conditions OR, et, ne seront affichees que les lignes ou les conditions requises
  par l'operateur OR seront verifiees.

  Pour que les OR's soient effectues avant les AND's, par exemple si vous vouliez voir
  une liste des employes dont le salaire est eleve (>50 000) OU beneficiant d'indemnites
  importantes (>10 000), ET qui soient cadres, utilisez des parentheses :

  SELECT EMPLOYEEIDNO
  FROM EMPLOYEESTATISTICSTABLE
  WHERE POSITION = 'Manager' AND (SALARY > 50000 OR BENEFIT > 10000);

  ----------------------------------------------------------------------------
  IN et BETWEEN

  Une methode plus facile pour utiliser les conditions composees consiste a utiliser
  IN ou BETWEEN. Par exemple, si vous desirez 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 superieur ou egal a 30 000, mais inferieur
  ou egal a 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 criteres, essayez :

  SELECT EMPLOYEEIDNO
  FROM EMPLOYEESTATISTICSTABLE
  WHERE SALARY NOT BETWEEN 30000 AND 50000;

  De la meme facon, NOT IN donne la liste de toutes les lignes exclues de la liste
  obtenue par l'operateur 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 utilise pour representer n'importe quel caractere
  possible (nombre, lettre, ou signe de ponctuation) ou ensemble de caracteres
  qui peut apparaitre apres le "L". Pour trouver les gens dont le Nom se termine
  avec "L", utiliser '%L', ou si vous desirez le "L" au milieu du mot, essayez
  dont la position est relative par rapport a des caracteres donnes. NOT LIKE
  affiche les lignes qui ne correspondent pas a la description donnee. Il y a
  d'autres manieres d'utiliser LIKE, de meme que n'importe lesquelles des
  conditions composees dont nous venons de parler, bien que cela depende du SGBD
  que vous utilisez; comme d'habitude, consultez un manuel ou le gestionnaire ou
  administrateur de votre systeme pour en connaitre les fonctionnalites, ou
  simplement, assurez vous que ce que vous essayer de faire est possible et
  autorise. Cet avertissement est aussi valable pour les fonctionnalites de SQL
  exposees ci-dessous. Cette section est donnee a titre d'exemple des requetes
  qui peuvent etre ecrites en SQL.
  ----------------------------------------------------------------------------
  Jointures

  Dans cette section, nous allons parler uniquement des jointures internes et
  des equi-jointures, dans la mesure ou ce sont les plus utiles. Pour avoir plus
  d'informations, voyez les liens sur des sites SQL au bas de cette  page.

  On suggere qu'une bonne maniere de concevoir une base de donnees implique que
  chaque table ne contienne des donnees qui ne concernent qu'une seule entite,
  et que des informations detaillees peuvent etre obtenues, dans une base de
  donnees relationnelle, en utilisant des tables supplementaires et en effectuant
  une jointure.

  Premierement, jetons un oeil a 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

  ----------------------------------------------------------------------------
  Cles

  En premier lieu, nous allons parler du concept de cles. Une cle primaire est
  une colonne ou en ensemble de colonnes qui identifie de maniere unique les
  autres donnees d'une ligne donnee. Par exemple, dans la table AntiqueOwners,
  la colonne OwnerID identifie de maniere unique cette ligne. Ceci signifie deux
  choses: que deux lignes ne peuvent avoir le meme OwnerID, et que, meme si
  deux proprietaires les memes noms et prenoms la colonne OwnerID garantit que
  ces deux proprietaires ne seront pas confondus l'un avec l'autre, puisque la
  colonne OwnerID unique sera utilisee a travers la base de donnees pour se
  referer a un proprietaire, plutot que son nom.

  Une cle externe est une colonne d'une table qui est cle primaire d'une autre
  table, ce qui signifie que toutes les donnees d'une cle externe doivent avoir
  des donnees correspondantes dans l'autre table, ou cette colonne est la cle
  primaire.
  Pour parler SGBD, cette correspondance est connue sous le nom d'integrite
  referentielle. Par exemple, dans la table Antiques, BuyerID et SellerID sont
  tous les deux des cles externes a la cle primaire de la table AntiqueOwners
  (OwnerID; pour les besoins de notre argumentation, on doit d'abord etre
  reference dans la table AntiqueOwners avant de pouvoir acheter ou vendre quoi
  que ce soit), puisque, dans les deux tables, les colonnes ID sont utilisees
  pour identifier les proprietaires, les acheteurs ou les vendeurs, et que
  OwnerID est la cle primaire de la table AntiqueOwners. En d'autres termes,
  toutes ces donnees "ID" sont utilisees pour se referer aux proprietaires,
  acheteurs et vendeurs sans avoir a utiliser les noms effectifs.

  ----------------------------------------------------------------------------
  Realisation d'une jointure

  Le but de ces cles est ainsi de pouvoir mettre en relation les donnees a
  travers les tables sans avoir a repeter les donnees dans chaque tables,
  --c'est toute la puissance des bases de donnees relationnelles. Par exemple,
  on peut trouver les noms de ceux qui ont achete une chaise sans avoir a lister
  la totalite du nom de l'acheteur dans la table Antiques... vous pouvez trouver
  ce nom en mettant en relation ceux qui ont achete une chaise avec les noms
  dans la table AntiqueOwners en utilisant le OwnerID, qui met en relation les
  donnees dans les deux tables. Pour trouver les noms de ceux qui ont achete
  une chaise, utilisez la requete suivante :

  SELECT OWNERLASTNAME, OWNERFIRSTNAME
  FROM ANTIQUEOWNERS, ANTIQUES
  WHERE BUYERID = OWNERID AND ITEM = 'Chair';

  Notez ce qui suit au sujet de cette requete... notez que les deux tables mise
  en jeux dans cette relation sont listees 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 a ceux qui ont achete (et, dans cet exemple, de ce
  fait possedent) une chaise. En second lieu, notez comment les colonnes ID sont
  mises en relation d'une table a la suivante par l'utilisation de la clause
  BUYERID = OWNERID. Ne seront listes que les noms  de la table AntiqueOwners
  dont les ID correspondent a travers les tables et dont l'article achete est
  une chaise (a cause du AND). Parce que la condition de jointure utilisee est
  un signe egal, cette jointure est appelee une equi-jointure. le resultat de
  cette requete donnera deux noms: Smith, Bob et Fowler, Sam.

  La notation avec un point (.) fait reference a l'utilisation du nom de colonne
  en suffixe du nom de table pour eviter toute ambiguite, 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 differents dans chaque table,
  cela n'etait pas necessaire.

  ----------------------------------------------------------------------------
  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 antiquite. Evidemment, vous ne desirez
  une liste ou chaque vendeur n'apparait qu'une fois--vous ne voulez pas savoir
  combien d'antiquites ont ete vendues par une personne, mais uniquement le fait
  que cette personne en a vendu une (pour les comptages, voir la fonction
  d'Agregation ci-dessous). Cela signifie qu'il vous faudra dire a SQL d'eliminer
  les doubles des lignes des ventes, et de ne seulement lister chaque personne
  qu'une fois. Pour realiser cela, utilisez le mot-cle DISTINCT.

  Premierement, vous aurez besoin de faire une equi-jointure sur la table
  AntiqueOwners pour obtenir les donnees concernant le Nom et le Prenom de la
  personne. Cependant, gardez a l'esprit que, puisque la colonne SellerID dans
  la table Antiques est une cle externe de la table AntiqueOwners, un vendeur
  ne sera liste que s'il y a une ligne dans la table AntiqueOwners contenant les
  ID et les noms. Nous voulons egalement eliminer les multiples occurrences du
  SellerID dans notre liste, donc, nous utiliserons le mot-cle DISTINCT pour les
  colonnes ou les repetitions peuvent se produire.

  Pour ajouter une difficulte, nous voulons aussi que cette liste soit classee
  par ordre alphabetique des Noms, puis des Prenoms (a l'interieur des noms),
  puis des  OwnerID (a l'interieur des noms et des prenoms). 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 proprietaires, classes par ordre alphabetique sur les noms.
  Pour reference ulterieure (au cas ou quelqu'un le demande), ce type de jointure
  est considere comme appartenant a la categorie des jointures internes.

  ----------------------------------------------------------------------------
  Alias et In/Sous-requetes

  Dans cette section, nous parlerons des Alias, In et de l'utilisation des
  sous-requetes, et de la maniere de les utiliser dans un exemple de 3-table.
  En premier lieu, regardez cette requete qui imprime le nom des proprietaires
  qui ont passe une commande et la nature de cette commande, en ne listant
  seulement que les commandes qui peuvent etre satisfaites (c'est a dire qu'il
  y a un vendeur qui possede l'article commande) :

  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 a noter a propos de cette requete :

    1. Tout d'abord, les mots "Last Name" et "Item Ordered" dans les lignes
       SELECT donnent les en-tetes du rapport.
    2. Les mots OWN et ORD sont des alias; ce sont de nouveaux noms pour les
       deux tables donnees dans la clause FROM qui sont utilises comme prefixes
       pour toutes les notations point (.) de noms de colonnes dans les requetes
       (voir ci-dessus). Ceci elimine les risques ambiguite, specialement dans
       l'equi-jointure de la clause WHERE ou les deux tables ont une colonne
       nommee OwnerID, et cette notation point (.) precise a SQL que nous
       designons deux OwnerID differents de deux tables differentes.
    3. Notez que la table des commandes (ORDERS) est indiquee la premiere dans
       la clause FROM; ceci apporte la certitude que la liste sera realisee a
       partir de cette table, et que la table AntiqueOwners
       est utilisee uniquement pour obtenir les informations detaillees (Last
       Name / Nom).
    4. Plus important, la clause AND dans la clause WHERE (OU) force l'utilisation
       de la Sous-requete  In ("= ANY" ou "= SOME" sont deux utilisations
       equivalentes de IN). Cela entraine que la sous-requete est effectuee,
       retournant une liste de tous les articles (Items) appartenant a 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_desire) doit etre
       dans la liste retournee des articles appartenant a la table Antiques, et
       donc un article ne sera liste que si la commande ne peut etre honoree
       que par un autre proprietaire. On peut se le representer comme ceci: la
       sous-requete retourne un ensemble d'articles (Items) auquel chaque
       ItemDesired (Article_Desire) dans la table des commandes (ORDERS) est
       compare; la condition IN (DANS) n'est vraie que si le ItemDesired
       appartient a l'ensemble provenant de la table ANTIQUES.
    5. Notez egalement, comme c'est le cas ici, qu'il y a un objet ancien pour
       chaque demande, ce qui, evidemment, n'est pas toujours le cas... De plus,
       notez aussi que, lorsque  IN, "= ANY", ou "= SOME" est utilise, ces
       mots-cles font reference a toutes les lignes qui conviennent, pas aux
       colonnes... c'est a dire que vous ne pouvez pas mettre de multiples
       colonnes dans un clause SELECT de sous-requete, pour tenter de faire
       correspondre la colonne de la clause WHERE externe avec l'une des
       multiples valeurs de colonnes possibles de la sous-requete; une seule
       colonne peut etre indiquee dans la sous-requete, 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 requetes SELECT complexes pour l'instant.
  Maintenait, voyons d'autres instructions SQL.
  ----------------------------------------------------------------------------
  Instructions SQL Diverses

  Fonctions d'Agregation

  Je parlerai de cinq fonctions d'agregation importantes: SUM, AVG, MAX, MIN, et
  COUNT. On les appelle fonctions d'agregation parce qu'elles resument les
  resultats d'une requete, plutot que de donner une liste de toutes les lignes.

     * SUM () donne la somme, pour une colonne donnee, de toutes les lignes qui
  satisfont aux conditions requises, et ou la colonne donnee est numerique.
     * AVG () donne la moyenne de la colonne donnee.
     * MAX () donne la plus grande valeur dans la colonne donnee.
     * MIN () donne la plus petite valeur dans la colonne donnee.
     * COUNT(*) donne le nombre de lignes qui satisfont aux conditions.

  En utilisant les tables du debut de ce document, regardons trois exemples :

  SELECT SUM(SALARY), AVG(SALARY)
  FROM EMPLOYEESTATISTICSTABLE;

  Cette requete donne la somme des de salaires tous les salaries presents dans
  la table et le salaire moyen.

  SELECT MIN(BENEFITS)
  FROM EMPLOYEESTATISTICSTABLE
  WHERE POSITION = 'Manager';

  Cette requete donne le chiffre de la colonne indemnites le plus faible des
  employes qui sont Managers, cette valeur est 12 500.

  SELECT COUNT(*)
  FROM EMPLOYEESTATISTICSTABLE
  WHERE POSITION = 'Staff';

  Cette requete vous donne le nombre d'employes ayant le statut de cadre (Staff,
  i.e. 3).

  ----------------------------------------------------------------------------
  Les Vues

  En SQL, vous pouvez (verifiez aupres de votre Administrateur de Base de Donnees,
  DBA) avoir acces a la creation de vues par vous-meme. Une vue vous permet d'affecter
  les resultats d'une requete a une nouvelle table personnelle, que vous pourrez
  utiliser dans d'autres requetes, pour laquelle vous donnez le nom de la vue dans
  votre clause FROM. Quand vous accedez a une vue, la requete qui est definie dans
  l'instruction de creation de la vue est effectuee (generalement), et les resultats
  de cette requete ont la meme allure qu'une autre table dans la requete que vous
  avez ecrit en invoquant la vue. Par exemple, pour creer une vue :

  CREATE VIEW ANTVIEW AS SELECT ITEMDESIRED FROM ORDERS;

  Maintenant, ecrivons une requete utilisant cette vue comme une table, ou la
  table est seulement une liste de tous les articles desires (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 ou l'article (Item) dans cette table apparait dans la vue ANTVIEW,
  qui consiste justement en tous les Articles Desires (Items Desired) dans la
  table ORDERS. La liste est cree en parcourant les articles AntiquesItems un
  par un jusqu'a ce qu'il y ait correspondance avec la vue ANTVIEW. Les vues
  peuvent etre utilisees pour restreindre les acces a la base de donnees,
  ainsi que, dans ce cas, pour simplifier une requete complexe.

  ----------------------------------------------------------------------------
  Creation de Nouvelles Tables

  Toutes les tables, dans une base de donnees doivent etre creees a un certain
  moment... voyons comment mous pourrions creer la table des commandes (ORDERS) :

  CREATE TABLE ORDERS
  (OWNERID INTEGER NOT NULL,
  ITEMDESIRED CHAR(40) NOT NULL);

  Cette instruction donne un nom a la table et renseigne le SGBD sur la nature
  de chaque colonne de la table. Veuillez noter que cette instruction utilise
  des types de donnees generiques, et que les types de donnees peuvent etre
  differents, selon le SGBD que vous utilisez. Comme d'habitude, verifiez vos
  conditions locales. Voici quelques types de donnees generiques courants:

     * Char(x) - Une colonne de caracteres, ou x est un nombre indiquant le
       nombre maximum de caracteres permis (taille maximale) de la colonne.
     * Integer - Une colonne de nombres entiers, positifs ou negatifs.
     * Decimal(x, y) - Une colonne de nombre decimaux, ou x est la taille
       maximum, en digits, des nombres decimaux dans cette colonne, et y le
       nombre maximal de digits autorises apres la virgule. Le nombre maximal
       (4,2) sera 99.99.
     * Date - Une colonne de date dans un format specifique 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 utilise NULL (nul),
  cette colonne peut etre laissee vide dans certaines lignes.

  ----------------------------------------------------------------------------
  Modification des tables

  Ajoutons une colonne a la table ANTIQUES pour permettre la saisie du prix d'un
  article donne :

  ALTER TABLE ANTIQUES ADD (PRICE DECIMAL(8,2) NULL);

  On verra plus tard comment les donnees pour cette nouvelle colonne peuvent
  etre mises a jour ou ajoutees.

  ----------------------------------------------------------------------------
  Ajout de Donnees

  Pour inserer des lignes dans une table, faites ce qui suit :

  INSERT INTO ANTIQUES VALUES (21, 01, 'Ottoman', 200.00);

  Ceci insere les donnees dans la table, en tant que nouvelle ligne, colonne
  par colonne, dans un ordre pre-definit. Au lieu de cela, changeons cet ordre
  et laissons le Prix vide:

  INSERT INTO ANTIQUES (BUYERID, SELLERID, ITEM)
  VALUES (01, 21, 'Ottoman');

  ----------------------------------------------------------------------------
  Suppression de donnees

  Supprimons cette nouvelle ligne de la base de donnees :

  DELETE FROM ANTIQUES
  WHERE ITEM = 'Ottoman';

  Mais s'il y a une autre ligne qui contient 'Ottoman', cette ligne sera
  egalement supprimee. Supprimons toutes les lignes (une, dans ce cas) qui
  contient les donnees specifiques que nous avons ajoute plus
   tot :

  DELETE FROM ANTIQUES
  WHERE ITEM = 'Ottoman' AND BUYERID = 01 AND SELLERID = 21;

  ----------------------------------------------------------------------------
  Mise a Jour des Donnees

  Mettons un Prix a 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) a 500.00. Comme indique
  ci-dessus, conditions WHERE supplementaires, utilisation de AND, il faut
  utiliser ces conditions pour limiter la mise a jour a des lignes specifiques.
  De plus, des colonnes supplementaires peuvent etre renseignees en separant
  les instructions "egal" par des virgules.

  ----------------------------------------------------------------------------
  Considerations Diverses

  Index

  Les Index permettent a un SGBD d'acceder au donnees plus rapidement (veuillez
  noter que cette fonctionnalite est non-standard/indisponible sur certains
  systemes). Le systeme cree une structure de donnee interne (l'index) qui
  entraine une selection de lignes beaucoup plus rapide, quand la selection
  est basee sur des colonnes indexees. Cet index indique au SGBD ou se trouve
  une certaine ligne dans une table etant donne une valeur de colonne indexee,
  exactement comme l'index d'un livre vous indique a quelle page un mot donne
  se trouve. Creons 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 etre debarrasse 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 detruite). Dans le second exemple, l'index est
  construit a partir des deux colonnes, agregees ensembles--un comportement
  bizarre peut resulter de cette situation... verifiez dans votre manuel avant
  d'effectuer une telle operation.

  Quelques SGBD n'imposent pas l'utilisation de cles primaires; en d'autres
  termes, l'unicite d'une colonne n'est pas imposee automatiquement. Cela
  signifie que, par exemple, j'aurais pu essayer d'inserer une autre ligne
  dans la table  AntiqueOwners avec un OwnerID de 02, quelques systemes me
  permettent de faire cela, bien qu'il ne le faille pas, puisque cette colonne
  est supposee etre unique dans cette table (chaque valeur de ligne est supposee
  etre differente). Une maniere de contourner cela est de creer un index unique
  sur la colonne que nous souhaitons voir etre la cle primaire pour forcer le
  systeme a interdire les doubles :

  CREATE UNIQUE INDEX OID_IDX ON ANTIQUEOWNERS (OWNERID);

  ----------------------------------------------------------------------------
  GROUP BY et HAVING

  Une utilisation speciale de la clause GROUP BY est l'association d'une fonction
  agregee (specialement COUNT; qui compte le nombre de lignes dans chaque groupe)
  avec des groupes de lignes. Premierement, supposons que la table ANTIQUES
  possede 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 achete
  par chaque proprietaire. Il nous faut donc dire a SQL de grouper les achats de
  chacun des proprietaires, 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
  depasse 1000, nous devrons utiliser la clause HAVING :

  SELECT BUYERID, MAX(PRICE)
  FROM ANTIQUES
  GROUP BY BUYERID
  HAVING PRICE > 1000;

  ----------------------------------------------------------------------------
  Sous-requetes Supplementaires

  Un autre usage commun des sous-requetes amene a l'utilisation des operateurs
  pour permettre a une condition WHERE d'inclure la sortie SELECT d'une
  sous-requete. En premier, demandons la liste des acheteurs ayant achete un
  article cher (le prix de cet article est superieur de 100 au prix moyen de tous
  les articles achetes) :

  SELECT OWNERID
  FROM ANTIQUES
  WHERE PRICE >

       (SELECT AVG(PRICE) + 100
       FROM ANTIQUES);

  La sous-requete calcule le Prix moyen, ajoute 100, et, et en utilisant ce
  chiffre on imprime un OwnerID pour chaque article coutant plus que ce chiffre.
  On peut utiliser DISTINCT OWNERID, pour eliminer les doubles.

  Listons les Noms (Last Names) de ceux qui sont dans la table AntiqueOwners,
  SEULEMENT s'ils ont achete un article :

  SELECT OWNERLASTNAME
  FROM ANTIQUEOWNERS
  WHERE OWNERID =

       (SELECT DISTINCT BUYERID
       FROM ANTIQUES);

  Cette sous-requete retourne une liste des acheteurs, et le Nom du proprietaire
  d'un objet ancien est imprime seulement si l'identificateur du Proprietaire
  (Owner's ID) dans la liste obtenue par la sous-requete (appelee quelquefois
  liste des candidats).

  Voici un exemple de mise a jour: nous savons que la personne qui a achete la
  bibliotheque a un Prenom errone dans la base de donnees... Ce devrait etre
  John :

  UPDATE ANTIQUEOWNERS
  SET OWNERFIRSTNAME = 'John'
  WHERE OWNERID =

       (SELECT BUYERID
       FROM ANTIQUES
       WHERE ITEM = 'Bookcase');

  Tout d'abord, la sous-requete trouve le BuyerID pour la (les) personne(s) qui
  a (ont) achete(s) la bibliotheque, puis la requete externe met a jour son
  Prenom.

  Souvenez vous de cette regle a propos des sous-requetes: quand vous avez une
  sous-requete faisant partie d'une condition WHERE, la clause SELECT dans la
  sous-requete doit avoir des colonnes qui correspondent en nombre et en type
  a celle de la clause WHERE de la requete externe. En d'autres termes, si vous
  avez "WHERE ColumnName = (SELECT...);", le SELECT ne peut faire reference qu'a
  une seule colonne, pour pouvoir correspondre a la clause WHERE externe, et
  elles doivent etre du meme type (les deux etant soit entiers, soit chaines
  de caracteres, etc.).

  ----------------------------------------------------------------------------
  EXISTS et ALL

  EXISTS utilise une sous-requete comme condition, ou cette condition est Vraie
  si la sous-requete retourne au moins une ligne et Fausse si la sous-requete
  n'en retourne aucune; c'est une fonctionnalite qui n'est pas intuitive et
  n'est utilisee que dans peu de cas. Cependant, si un client eventuel voulait
  consulter la liste des proprietaires 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-requete renverra une ou plusieurs lignes, rendant la clause EXISTS
  vraie, ce qui amenera SQL a donner une liste des proprietaires dans
  ANTIQUEOWNERS. S'il n'y avait eu aucune Chaise, la requete externe n'aurait
  pas renvoye de ligne.

  ALL est une autre fonctionnalite peu commune, et en general, on peut realiser
  une requete avec ALL de manieres differentes et eventuellement plus simples;
  regardons cet exemple de requete :

  SELECT BUYERID, ITEM
  FROM ANTIQUES
  WHERE PRICE >= ALL

       (SELECT PRICE
       FROM ANTIQUES);

  Ceci va nous retourner l'article de prix le plus eleve (ou plus d'un article
  s'il y a des ex-aequo), et son acheteur. La sous-requete renvoie la liste de
  tous les Prix (PRICE) dans la table ANTIQUES, puis la requete externe examine
  chaque ligne de la table ANTIQUES et si son Prix est superieur ou egal a chacun
  (ou ALL, TOUS) des Prix de cette liste, il est affiche, donnant ainsi l'article
  de prix le plus eleve. La raison pour laquelle ">=" doit etre utilise est que
  l'article de prix le plus eleve sera egal au prix le plus eleve, puisque cet
  Article est dans la liste de Prix.

  ----------------------------------------------------------------------------
  UNION et Jointure Externe

  Il y a des occasions  ou vous pouvez desirer voir ensembles les resultats de
  requetes multiples, leurs sorties etant combinees; pour cela utilisez UNION.
  Pour fusionner la sortie des deux requetes suivantes, en affichant l'identificateur
  de tous les Acheteurs plus tous ceux qui ont passe une Commande :

  SELECT BUYERID
  FROM ANTIQUEOWNERS
  UNION
  SELECT OWNERID
  FROM ORDERS;

  Il faut noter que SQL necessite que les types de donnees des listes des clauses
  SELECT correspondent colonne par colonne. Dans cet exemple, les identificateurs
  BuyerID et OwnerID sont du meme type (entier). Notez egalement que SQL
  effectue automatiquement une elimination des doubles quand on utilise la clause
  UNION (comme si c'etaient deux "ensembles"); dans une requete simple, il faut
  utiliser la clause DISTINCT.

  La jointure externe est utilisee quand une requete de jointure est "unifiee",
  les lignes n'etant pas incluses dans la jointure. Ceci est particulierement
  utile si des "balises" de type constante texte sont inclus. D'abord,
  regardez la requete :

  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 premiere requete effectue une jointure pour lister tous les proprietaires
  qui sont dans les deux tables, et met une balise apres l'identificateur (ID)
  en inserant le texte correspondant a la balise. La clause UNION fusionne cette
  liste avec la liste suivante. La seconde liste est generee premierement en
  listant les identificateurs (ID) qui ne sont pas dans la table ORDERS, c'est a
  dire en generant une liste des ID exclus de la requete de jointure.. Puis,
  chaque ligne de la table ANTIQUES est analysee, et, si l'identifiant de
  l'acheteur (BuyerID) n'est pas dans cette liste d'exclusion, il est liste avec
  le texte correspondant a sa balise. Il y aurait peut-etre une meilleure
  maniere de creer cette liste, mais c'est difficile de generer des balises
  informationnelles.

  Ce concept est utile dans des situations ou une cle primaire est en relation
  avec une cle externe, et ou la valeur de la cle externe est NULLE (NULL) pour
  quelques cles primaires. Par exemple, dans une table, la cle primaire est
  vendeur, et dans une autre table client, avec le vendeur enregistre dans la
  meme ligne. Cependant, si un vendeur n'a pas de clients, le nom de cette
  personne n'apparaitra pas dans la table des clients. Une jointure externe sera
  utilisee pour imprimer une liste de tous les vendeurs, avec leurs clients, que
  le vendeur ait un client ou pas--c'est a dire qu'il n'y aura pas de client
  imprime (valeur logique NULL) si le vendeur n'a pas de client, mais existe dans
  la table des vendeurs. Autrement, le vendeur sera liste avec chaque client.

  ASSEZ DE REQUETES!!! Qu'est-ce que vous dites?...Eh bien, maintenant voyons
  quelque chose de completement different...

  ----------------------------------------------------------------------------
  SQL incorpore--un vilain exemple (n'ecrivez pas un programme comme cela... il
  est la UNIQUEMENT a titre d'exemple)

  /* -Voici un exemple de programme qui utilise le SQL incorpore (Embedded
      SQL). Le SQL incorpore permet aux programmeurs de se connecter a une
      base de donnees et d'inclure du code SQL en plein programme, et ainsi,
      leurs programmes peuvent utiliser, manipuler, et traiter les donnees
      d'une base de donnees.
     -Cet exemple de Programme C (qui utilise du SQL incorpore) doit imprimer
      un rapport.
     -Les instructions SQL devront etre pre-compilees avant d'effectuer la
      compilation normale.
     -Si vous utilisez un langage different les parties EXEC SQL seront les
      memes (standard), mais le code C qui les entourent devront etre
      modifiees, y compris les declarations de variables hotes.
     -Le SQL incorpore differe de systeme a systeme, aussi, encore une fois,
      verifiez la documentation locale, specialement les declarations de
      variables et les procedures de connexion pour lesquelles le reseau, le
      SGBD, et le systeme 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 declaration des variables hotes; ce seront les variables
  utilisees par votre programme, mais egalement celles utilisees 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,insere les variables SQLCA, de facon a pouvoir tester les erreurs. */
  EXEC SQL INCLUDE SQLCA;

  main() (

  /* Ceci est une possibilite pour se connecter a la base de donnees */
  EXEC SQL CONNECT UserID/Password;

  /* Cette partie de code soit vous indique que vous etes connecte  soit
  teste si un code erreur a ete genere, signifiant que la connexion etait
  incorrecte ou impossible. */
    if(sqlca.sqlcode) (
      printf(Printer, "Erreur de connexion au serveur de base de donnees.\n");
      exit();
    )
    printf("Connecte au serveur de base de donnees.\n");

  /* Ici, on declare un "Curseur". C'est utilise lorsqu'une requete retourne
     plus d'une ligne, et qu'on doit effectuer un traitement sur chaque ligne
     obtenue de la requete. Je vais utiliser pour le rapport, chaque ligne obtenue
     par cette requete. Ensuite, on utilisera "FETCH" (va chercher) pour recuperer
     les lignes, une par une, mais pour que la requete soit effectivement executee,
     il faut utiliser l'instruction "OPEN". La "Declaration" (Declare) sert
     uniquement a construire la requete. */
  EXEC SQL DECLARE ItemCursor CURSOR FOR
    SELECT ITEM, BUYERID
    FROM ANTIQUES
    ORDER BY ITEM;
  EXEC SQL OPEN ItemCursor;

  /*
   +-- Inserer ici un test d'erreur similaire au precedent si vous le desirez --+
  */

  /* L'instruction FETCH insere les valeurs de la ligne suivante respectivement
  dans chacune des variables hotes. Cependant un "priming fetch" (technique de
  programmation) doit etre execute en premier. Lorsque le curseur n'a plus de
  donnees un code (sqlcode) est genere nous permettant de sortir de la boucle.
  Notez que, pour des raisons de simplicite, on abandonne la boucle pour n'importe
  quel sqlcode, meme s'il correspond a un code erreur. Autrement, il faut
  effectuer un test d'erreur specifique. */
  EXEC SQL FETCH ItemCursor INTO :Item, :BuyerID;
    while(!sqlca.sqlcode) (

  /* Nous effectuerons egalement deux traitements pour chaque ligne. Premierement,
  augmenter le prix de 5 (retribution 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'ecran. La mise a
  jour suppose, cependant, qu'un acheteur donne n'a achete qu'un seul article,
  ou, sinon, le prix sera augmente de trop nombreuses fois. Sinon, il aurait
  fallu utiliser une logique "RowID" (consulter la documentation). De plus,
  notez la presence du signe : (deux points) qui doit etre place devant les
  noms de variables hotes quand elles sont utilisees 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 a 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 avances
  (Consulter les liens FAQ pour en avoir plusieurs autres)

    1. Pourquoi ne puis-je pas demander uniquement les trois premieres lignes
       d'une table? --Parce que, dans une base de donnees relationnelle, les
       lignes sont inserees sans aucun ordre particulier, c'est a dire que le
       systeme les inserent dans un ordre arbitraire; de ce fait, vous ne pouvez
       demander des lignes qu'en utilisant des fonctionnalites SQL valides,
       telles que ORDER BY, etc.
    2. Que sont ces DDL et DML dont j'entends parler ? --DDL (Data
       Definition Language - Langage de Definition de Donnees) fait reference a
       (en SQL) l'instruction de Creation de Table (Create Table)...DML (Data
       Manipulation Language - Langage de Manipulation de Donnees) fait reference
       aux instructions Select, Update, Insert, et Delete.
    3. Les tables des base de donnees ne sont elles pas simplement des fichiers?
       --Eh bien, les SGBD stockent les donnees dans des fichiers declares par
       le gestionnaire du systeme avant que de nouvelles tables ne soient creees
       (sur les grands systemes), mais le systeme stocke les donnees dans un
       format special, et peut repartir les donnees d'une table dans plusieurs
       fichiers. Dans le monde des bases de donnees, un ensemble de fichiers
       crees pour une base de donnees est appele un "espace de tables". En
       general, sur les petits systemes, tout ce qui concerne une base de donnees
       (definitions et toutes les tables de donnees) est stocke dans un seul
       fichier.
    4. (Question en relation avec la precedente) Les bases de donnees ne sont
       elles pas simplement que des tableurs? --Non, et ceci pour deux raisons.
       Premierement, les tableurs peuvent avoir des donnees 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 donnees (actuelles) ne permettent pas. Deuxiemement,
       les cellules dependent souvent des donnees presentes dans d'autres
       cellules. Dans les bases de donnees, les "cellules" sont independantes,
       sauf que les colonnes sont en relation logique (heureusement: ensembles,
       une ligne et une colonne decrivent une entite), et, en dehors des
       contraintes de cle primaire et de cle externe, chaque ligne d'une table
       est independante des autres.
    5. Comment puis-je importer un fichier texte de donnees dans une base de
       donnees? --Eh bien, vous ne pouvez pas le faire directement...il vous faut
       utiliser un programme utilitaire, tel que le SQL*Loader pour Oracle,
       ou ecrire un programme pour charger les donnees dans la base de donnees.
       Un programme pour realiser cela lit simplement chaque enregistrement du
       fichier texte, le separe en colonnes, et effectue une insertion (INSERT)
       dans la base de donnees.
    6. Qu'est-ce qu'un schema? --Un schema est un ensemble logique de tables, tel
       que la base de donnees ANTIQUES ci-dessus...habituellement, on s'y refere
       simplement en tant que "base de donnees", mais une base de donnees peut
       contenir plus d'un schema. Par exemple, un schema en etoile est un ensemble
       de tables ou une table centrale, de grande taille, contient toutes les
       informations importantes, et est liee, via des cles externes, a des tables
       de dimension qui contiennent l'information detaillee, et qui peuvent etre
       utilisees dans une jointure pour creer des rapports detailles.
    7. Quels conseils generaux pourriez vous donner pour rendre mes requetes SQL
       et mes bases de donnees meilleures et plus rapides (optimisees)?
          o Vous devriez essayer, si vous le pouvez, d'eviter, dans les clauses
            SELECT, des expressions telles que SELECT ColumnA + ColumnB, etc.
            L'optimiseur de requetes de la base de donnees, partie du SGBD qui
            determine la meilleure maniere d'extraire les donnees requises de la
            base de donnees elle-meme, traite les expressions d'une facon telle
            que cela demande en general plus de temps pour extraire les donnees
            que si les colonnes avaient ete selectionnees normalement, et que
            l'expression elle-meme calculee par programme.
          o Minimisez le nombre de colonnes incluses dans une clause Group By.
          o Si vous effectuez une jointure, tachez d'avoir les colonnes, de cette
            jointure, indexees (dans les deux tables).
          o Si vous avez un doute, creez un index.
          o A moins que vous ne fassiez de multiple comptages ou une requete
            complexe, utilisez COUNT(*) (le nombre de lignes sera genere par la
            requete) plutot que COUNT(Column_Name).
    8. Qu'est-ce que la Normalisation? --La Normalisation est une technique de
       conception de base de donnees qui suggere qu'un certain critere doit etre
       pris en compte quand on definit l'organisation des tables (prise de
       decision sur le nombre de colonnes de chaque table, et creation de la
       structure des cles), ou l'idee est d'eliminer la redondance a travers les
       tables des donnees qui ne sont pas des cles. On parle de la normalisation
       en s'y referant habituellement en termes de "formes", et j'introduirais ici
       uniquement les trois premieres, bien qu'il soit tout a fait courant d'en
       utiliser d'autres formes, plus avancees (quatrieme, cinquieme, Boyce-Codd;
       consultez la documentation).

       La Premiere Forme Normale consiste a placer les donnees dans des tables
       separees ou les donnees dans chaque tables sont de type similaire, et a
       donner a chaque table une cle primaire.

       Mettre les donnees en Seconde Forme Normale consiste a mettre les donnees
       dans les tables ou elle ne dependent uniquement que d'une partie de la cle.
       Par exemple, si j'avais laisse les noms des proprietaires d'objets anciens
       dans la table des articles, ce n'aurait pas ete une seconde forme normale
       puisque les donnees auraient ete redondantes; le nom aurait du etre
       repete pour chaque article possede, donc, les noms ont ete places dans
       leur propre table. Les noms en eux-memes n'ont rien a voir avec les
       articles, seules les identites des acheteurs et des vendeurs sont
       concernees.

       La Troisieme Forme Normale consiste a se debarrasser, dans une table, a
       tout ce qui ne depend pas uniquement de la cle primaire. On met uniquement
       l'information qui depend de la cle, et l'on deplace, dans d'autres tables,
       tout ce qui est independant de la cle primaire, et l'on cree des cles
       primaires pour les nouvelles tables.

       Il y a une certaine forme de redondance dans chaque forme, et si les
       donnees sont en 3NF (abrege pour 3ieme forme normale), elles sont deja en
       1NF et 2NF. En terme d'organisation des donnees, organisez vos donnees de
       facon que les colonnes qui ne sont pas des cles primaires dependent
       seulement de la cle primaire entiere. Si vous jetez un oeil sur la base de
       donnees en exemple, vous verrez que, lorsque vous naviguez a travers la
       base de donnees, c'est au travers de jointures qui utilisent les colonnes
       de cle commune.

       Deux autre points importants dans la conception de bases de donnees sont
       l'utilisation de noms significatifs, bien choisis, coherents et logiques
       pour les tables et les colonnes et l'utilisation de noms significatifs pour
       la base de donnees elle-meme. Sur le dernier point, ma base de donnees
       peche, puisque j'utilise des codes numeriques comme identificateurs. C'est
       en general bien meilleur d'utiliser, si possible, des cles qui ont, en
       elles-memes, un sens; par exemple, une meilleure cle pourrait consister
       des quatre premieres lettres du nom et de la premiere initiale du prenom,
       comme JONEB pour Bill Jones (ou pour eviter les doubles, ajoutez-y des
       nombres a la fin pour differencier deux ou plusieurs personnes ayant le
       meme nom, ainsi, on pourrait essayer JONEB1, JONEB2, etc.).
    9. Quelle est la difference entre une requete simple ligne et une requete
       multi-lignes et pourquoi est-ce important de connaitre cette
       difference? --Premierement, pour parler de ce qui est evident, une requete
       simple ligne est une requete qui retourne une ligne unique comme resultat,
       et le resultat d'une requete multi-lignes est constitue de plusieurs
       lignes. Qu'une requete retourne une ligne ou plusieurs depend completement
       de la conception (ou schema) des tables qui constituent la base de donnees.
       Assurez-vous d'inclure suffisamment de conditions, et structurez vos
       instructions SQL correctement, de facon a obtenir le resultat desire (soit
       une ligne, soit plusieurs). Par exemple, si vous vouliez etre sur qu'une
       requete sur la table AntiqueOwners ne retourne qu'une ligne, employez une
       condition d'egalite sur la cle primaire, OwnerID.

       Trois raisons, concernant l'importance de ce sujet, viennent immediatement
       a l'esprit.
       Premierement, l'obtention de plusieurs lignes alors que vous n'en attendez
       qu'une, ou vice-versa, peut signifier que la requete est erronee, que la
       base de donnees est incomplete, ou simplement que vous decouvrez quelque
       chose de nouveau concernant vos donnees.
       Deuxiemement, si vous utilisez une instruction de mise a jour (UPDATE) ou
       de suppression (DELETE), il vaudrait mieux vous assurer que l'instruction
       que vous ecrivez effectue bien l'operation sur la ligne desiree (ou les
       lignes)...ou sinon, vous pourriez supprimer ou mettre a jour plus de lignes
       que vous ne le desirez.
       Troisiemement, il faut soigneusement penser au nombre de lignes qui seront
       retournees pour toutes les requetes redigees  en SQL incorpore. Si vous
       ecrivez une requete simple ligne, une seule instruction SQL peut suffire
       pour satisfaire a la logique du programme. D'un autre cote, si votre
       requete retourne de multiples lignes, il vous faudra utiliser
       l'instruction FETCH, et tres certainement quelque chose comme une structure
       de boucle sera necessaire dans votre programme pour traiter chaque ligne
       retournee par la requete.
   10. Que sont les relations? --C'est une autre question de conception...le
       terme "relation" fait habituellement reference aux relations entre cles
       primaires et externes entre les tables. Ce concept est important parce que,
       quand les tables d'une base de donnees relationnelle sont concues, ces
       relations doivent etre definies parce que cela determine quelles colonnes
       sont ou ne sont pas des cles primaires ou externes. Vous avez peut-etre
       entendu parler des diagrammes Entites-Relations, qui sont une
       representation graphique des tables dans les schema de la base de donnees.
       Voyez l'exemple de diagramme a la fin de cette section ou consultez
       quelques sites indiques ci-dessous concernant ce sujet, car il y a de
       nombreuses manieres de dessiner les diagrammes E-R. Mais d'abord, jetons
       un oeil a chaque type de relation...

       Une relation 1-a-1 (ou 1:1, ou 1-1) signifie que vous avez une colonne cle
       primaire  et que chaque cle primaire est en relation avec une cle externe.
       Par exemple, dans le premier exemple, dans la table des adresses des
       employes TableAdresseEmploye nous avons une colonne numero d'identification
       de l'employe (EmployeeIDNo). Donc, la table TableAdresseEmploye est en
       relation avec la table EmployeeStatisticsTable (deuxieme exemple de table)
       par l'intermediaire du numero EmployeeIDNo. Plus precisement, chaque
       employe, de la table TableAdresseEmploye possede des statistiques (une
       ligne de donnees) dans la table EmployeeStatisticsTable. Meme si c'est un
       exemple invente, c'est une relation "1-1". Inscrivez en caracteres gras le
       "has" ("a" ou "possede")...quand on decrit une relation, il est important
       de decrire une relation en utilisant un verbe.

       Les deux autres types de relations peuvent ou pas utiliser une cle primaire
       logique et des contraintes par rapport aux cles externes...cela depend
       strictement des souhaits du concepteur. La premiere de ces relations est la
       relation un-a-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 cle peuvent etre ajoutees au modele, ou eventuellement une
       colonne d'identification peut etre utilisee pour etablir une relation. Un
       exemple serait que pour chaque OwnerID dans la table AntiqueOwners, il y
       ait un ou plusieurs (la valeur zero est egalement autorisee) articles
       (Items) achetes dans la table  ANTIQUES (verbe: acheter).

       Finalement, la relation plusieurs-a plusieurs ("M-M") n'utilise
       generalement pas de cles, 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 possibilite 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 donnees de fonctions, a avoir une
       table possedant une ligne pour chaque employe et sa fonction, et d'avoir
       une autre table contenant une ligne pour chaque fonction avec un des
       employes l'occupant. Dans ce cas, vous auriez plusieurs lignes pour chaque
       employe dans la premiere table, une pour chaque fonction, et plusieurs
       lignes pour chaque fonction dans le seconde table, une pour chaque employe
       ayant cette fonction.
       Ces tables sont en relation M-M: chaque employe, dans la premiere table a
       plusieurs fonctions dans la seconde table, et chaque fonction, dans la
       seconde table, a plusieurs attributaires dans la premiere table. Ceci est
       la partie emergee 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 simplifie de diagramme E-R.
       [Exemple Simplifie de Diagramme Entites-Relations]

   11. Quelles sont quelques unes des fonctionnalites importantes, non standard,
       de SQL (Question extremement courante)? --Eh bien, nous allons voir ca dans
       la section suivante...

  ----------------------------------------------------------------------------
  SQL Non-standard..."A verifier pour votre site"

     * INTERSECT et MINUS sont comme des instructions UNION , sauf que INTERSECT
       produits des lignes qui apparaissent dans les deux requetes, et que MINUS
       produit des lignes provenant de la premiere requete mais pas de la
       seconde.
     * Fonctionnalites de la Generation de Rapport: la clause COMPUTE est placee
       a la fin d'une requete pour placer le resultat d'une fonction agregee a
       la fin d'une liste, comme COMPUTE SUM (PRICE); Une autre solution est
       d'utiliser une logique d'interruption: definir une interruption pour
       diviser les resultats de la requete en groupes bases sur une colonne,
       comme BREAK ON BUYERID. Alors, pour sortir un resultat apres la liste d'un
       groupe, utilisez COMPUTE SUM OF PRICE ON BUYERID. Si, par exemple, vous
       avez utilise ces trois clauses ("BREAK" en premier, "COMPUTE on break" en
       second, "COMPUTE overall sum" en troisieme), vous obtiendrez un rapport qui
       regroupera les articles par acheteurs, listera la somme de Prix pour chaque
       groupe d'articles d'un acheteur, puis, apres que tous les groupes aient ete
       listes, listera la somme de tous les Prix, le tout, avec des en-tetes et
       des lignes generes par SQL.
     * En plus des fonctions agregees indiquees ci-dessus, quelques SGBD ont des
       fonctions supplementaires qui peuvent etre utilisees dans des listes de
       selection (SELECT), sauf que ces fonctions (quelques fonctions caracteres
       autorisent des resultats de plusieurs lignes) doivent etre utilisees avec
       une valeur individuelle (pas de groupes), pour des requetes simple ligne.
       De plus, les fonctions ne doivent etre utilisees qu' avec les types de
       donnees appropries. Voici quelques Fonctions Mathematiques:

        ABS(X)       Valeur A-convertit les nombres negatifs en nombres positifs
                     et laisse les positifs inchanges
        CEIL(X)      X est une valeur decimale qui sera arrondie a la valeur
                     superieure.
        FLOOR(X)     X est une valeur decimale qui sera arrondie a la valeur
                     inferieure.
        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 a la puissance Y.

        ROUND(X,Y)   Arrondit X a Y positions decimales. i Y n'est pas donne, X
                     est arrondi a 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 carree de  X.

                                 Fonctions Caracteres

        LEFT(<string>,X)
                             Retourne les X caracteres les plus a gauche de la
                             chaine de caracteres.

        RIGHT(<string>,X)
                             Retourne les X caracteres les plus a droite de la
                             chaine de caracteres.
        UPPER(<string>)
                             Convertit tous les caracteres de la chaine en
                             majuscules.
        LOWER(<string>)
                             Convertit tous les caracteres de la chaine en
                             minuscules.
        INITCAP(<string>)
                             Convertit les caracteres initiaux de la chaine en
                             Capitales.
        LENGTH(<string>)
                             Retourne le nombre de caracteres de la chaine.

        <string>||<string>
                             Combine les deux chaines en une seule chaine,
                             concatenee, ou la premiere chaine est immediatement
                             suivie par la seconde.

        LPAD(<string>,X,'*')
                             Insere des caracteres * (ou n'importe quel autre, mis
                             entre guillemets) a gauche de la chaine de
                             caracteres pour lui donner une longueur de X
                             caracteres.

        RPAD(<string>,X,'*')
                             Insere des caracteres * (ou n'importe quel autre, mis
                             entre guillemets) a droite de la chaine de
                             caracteres pour lui donner une longueur de X
                             caracteres.

        SUBSTR(<string>,X,Y)
                             Extrait Y lettres de la chaine a 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.

  ----------------------------------------------------------------------------
  Resume de la Syntaxe--Pour Utilisateurs Avances Seulement

  Voici la forme generale des instructions dont il a ete question dans ce
  didacticiel, avec, en plus, quelques autres, (des explications sont donnees).
  SOUVENEZ-VOUS que toutes ces instructions peuvent ne pas etre disponibles sur
  votre systeme, aussi verifiez leur disponibilite 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 specifications(donnees, types, etc.) d'une colonne
  existante;
  cette instruction est egalement utilisee pour changer les specifications
  physiques d'une table
  (comment la table est stockee, etc.), mais ces definitions sont specifiques au
  SGBD, aussi, lire la documentation. De meme, ces specifications physiques sont
  utilisees avec les instructions de creation de table, lorsqu'une table est creee
  pour la premiere fois. De plus, seulement une seule option peut etre executee
  par instruction de modification: (Alter Table)--soit add (ajout), drop
  (suppression), OU modify (modification) dans une simple instruction.

  COMMIT; --rend les modifications effectuees sur une bases de donnees 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 parentheses.

  CREATE TABLE <TABLE NAME>
  (<COLUMN NAME> <DATA TYPE> [(<SIZE>)] <COLUMN CONSTRAINT>,
  --ou SIZE est uniquement utilise avec certains types de donnees (voir
  ci-dessus), et les contraintes incluent les possibilites suivantes (impose
  automatiquement par le SGBD;
  (un non respect entraine la generation d'une erreur) :

    1. NULL ou NOT NULL (voir ci-dessus)
    2. UNIQUE impose que deux lignes ne peuvent avoir la meme valeur pour cette
  colonne
    3. PRIMARY KEY indique a la base de donnees que cette colonne est la colonne
  cle primaire (utilise uniquement si la cle est une colonne cle, autrement une
  instruction
       PRIMARY KEY (column, column, ...) apparait apres la derniere definition de
  colonne.
    4. CHECK permet de tester une condition quand on insere ou on met a jour une
  donnee dans cette colonne; par exemple, CHECK (PRICE > 0) amene le systeme a
  tester si la colonne Prix est superieure ou egale a zero avant d'accepter la
  valeur...quelquefois implante comme instruction CONSTRAINT.
    5. DEFAULT insere une valeur par defaut dans la base de donnees si l'on veut
  inserer une ligne qui ne contienne pas de valeur pour cette colonne; par
  exemple,
       BENEFITS INTEGER DEFAULT = 10000
    6. FOREIGN KEY fonctionne comme la Cle Primaire, mais est suivi par:
       REFERENCES <TABLE NAME> (<COLUMN NAME>), qui fait reference a la cle primaire
       de reference.

  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 effectuees dans la base de donnees,
  celles qui ont ete faites depuis la derniere 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]]; --ou 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 donnee, toutes les lignes
  seront mises a jour selon l'instruction SET

  ----------------------------------------------------------------------------

