Adaptive Server Anywhere Guide de programmation - Sybase
Adaptive Server Anywhere Guide de programmation - Sybase
Adaptive Server Anywhere Guide de programmation - Sybase
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Adaptive</strong> <strong>Server</strong> ®<br />
<strong>Anywhere</strong><br />
<strong>Gui<strong>de</strong></strong> <strong>de</strong> <strong>programmation</strong><br />
Dernière mise à jour : Octobre 2002<br />
Réf. du document : 03945-01-0802-01
Copyright © 1989–2002 <strong>Sybase</strong>, Inc. Copyright partiel © 2001-2002 i<strong>Anywhere</strong> Solutions, Inc. Tous droits réservés.<br />
Tout ou partie <strong>de</strong> cette publication ne peut être reproduit, transmis ou traduit, sous quelque forme ou par quelque moyen que ce soit (électronique,<br />
mécanique, manuel, optique ou autre) sans l'accord écrit préalable d'i<strong>Anywhere</strong> Solutions, Inc. i<strong>Anywhere</strong> Solutions, Inc. est une filiale <strong>de</strong> <strong>Sybase</strong>,<br />
Inc.<br />
<strong>Sybase</strong>, SYBASE (logo), AccelaTra<strong>de</strong>, ADA Workbench, Adaptable Windowing Environment, <strong>Adaptive</strong> Component Architecture, <strong>Adaptive</strong> <strong>Server</strong>,<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, <strong>Adaptive</strong> <strong>Server</strong> Enterprise, <strong>Adaptive</strong> <strong>Server</strong> Enterprise Monitor, <strong>Adaptive</strong> <strong>Server</strong> Enterprise Replication, <strong>Adaptive</strong><br />
<strong>Server</strong> Everywhere, <strong>Adaptive</strong> <strong>Server</strong> IQ, <strong>Adaptive</strong> Warehouse, AnswerBase, <strong>Anywhere</strong> Studio, Application Manager, AppMo<strong>de</strong>ler,<br />
APT Workbench, APT-Build, APT-Edit, APT-Execute, APT-FORMS, APT-Library, APT-Translator, ASEP, Backup <strong>Server</strong>, BayCam, Bit-Wise,<br />
BizTracker, Certified PowerBuil<strong>de</strong>r Developer, Certified SYBASE Professional, Certified SYBASE Professional (logo), ClearConnect, Client<br />
Services, Client-Library, Co<strong>de</strong>Bank, Column Design, ComponentPack, Connection Manager, Convoy/DM, Copernicus, CSP, Data Pipeline, Data<br />
Workbench, DataArchitect, Database Analyzer, DataExpress, Data<strong>Server</strong>, DataWindow, DB-Library, dbQueue, Developers Workbench, Direct<br />
Connect <strong>Anywhere</strong>, DirectConnect, Distribution Director, Dynamo, e-ADK, E-<strong>Anywhere</strong>, e-Biz Integrator, E-Whatever, EC-GATEWAY, ECMAP,<br />
ECRTP, eFulfillment Accelerator, Electronic Case Management, Embed<strong>de</strong>d SQL, EMS, Enterprise Application Studio, Enterprise Client/<strong>Server</strong>,<br />
Enterprise Connect, Enterprise Data Studio, Enterprise Manager, Enterprise SQL <strong>Server</strong> Manager, Enterprise Work Architecture, Enterprise Work<br />
Designer, Enterprise Work Mo<strong>de</strong>ler, eProcurement Accelerator, eremote, Everything Works Better When Everything Works Together, EWA,<br />
Financial Fusion, Financial Fusion <strong>Server</strong>, First Impression, Formula One, Gateway Manager, GeoPoint, i<strong>Anywhere</strong>, i<strong>Anywhere</strong> Solutions,<br />
ImpactNow, Industry Warehouse Studio, InfoMaker, Information <strong>Anywhere</strong>, Information Everywhere, InformationConnect, InstaHelp, Intelli<strong>de</strong>x,<br />
InternetBuil<strong>de</strong>r, iremote, iScript, Jaguar CTS, jConnect for JDBC, KnowledgeBase, Logical Memory Manager, MainframeConnect, Maintenance<br />
Express, MAP, MDI Access <strong>Server</strong>, MDI Database Gateway, media.splash, MetaWorks, MethodSet, ML Query, MobiCATS, MySupport,<br />
Net-Gateway, Net-Library, New Era of Networks, Next Generation Learning, Next Generation Learning Studio, O DEVICE, OASiS, OASiS (logo),<br />
ObjectConnect, ObjectCycle, OmniConnect, OmniSQL Access Module, OmniSQL Toolkit, Open Biz, Open Business Interchange, Open Client,<br />
Open Client/<strong>Server</strong>, Open Client/<strong>Server</strong> Interfaces, Open ClientConnect, Open Gateway, Open <strong>Server</strong>, Open <strong>Server</strong>Connect, Open Solutions,<br />
Optima++, Partnerships that Work, PB-Gen, PC APT Execute, PC DB-Net, PC Net Library, PhysicalArchitect, Pocket PowerBuil<strong>de</strong>r,<br />
PocketBuil<strong>de</strong>r, Power Through Knowledge, Power++, power.stop, PowerAMC, PowerBuil<strong>de</strong>r, PowerBuil<strong>de</strong>r Foundation Class Library,<br />
PowerDesigner, PowerDimensions, PowerDynamo, Powering the New Economy, PowerJ, PowerScript, PowerSite, PowerSocket, Powersoft,<br />
Powersoft Portfolio, Powersoft Professional, PowerStage, PowerStudio, PowerTips, PowerWare Desktop, PowerWare Enterprise, ProcessAnalyst,<br />
Rapport, Relational Beans, Replication Agent, Replication Driver, Replication <strong>Server</strong>, Replication <strong>Server</strong> Manager, Replication Toolkit, Report<br />
Workbench, Report-Execute, Resource Manager, RW-DisplayLib, RW-Library, S Designor, S-Designor, S.W.I.F.T. Message Format Libraries,<br />
SAFE, SAFE/PRO, SDF, Secure SQL <strong>Server</strong>, Secure SQL Toolset, Security Guardian, SKILS, smart.partners, smart.parts, smart.script,<br />
SQL Advantage, SQL <strong>Anywhere</strong>, SQL <strong>Anywhere</strong> Studio, SQL Co<strong>de</strong> Checker, SQL Debug, SQL Edit, SQL Edit/TPU, SQL Everywhere,<br />
SQL Mo<strong>de</strong>ler, SQL Remote, SQL <strong>Server</strong>, SQL <strong>Server</strong> Manager, SQL <strong>Server</strong> SNMP SubAgent, SQL <strong>Server</strong>/CFT, SQL <strong>Server</strong>/DBM, SQL SMART,<br />
SQL Station, SQL Toolset, SQLJ, Stage III Engineering, Startup.Com, STEP, SupportNow, <strong>Sybase</strong> Central, <strong>Sybase</strong> Client/<strong>Server</strong> Interfaces, <strong>Sybase</strong><br />
Development Framework, <strong>Sybase</strong> Financial <strong>Server</strong>, <strong>Sybase</strong> Gateways, <strong>Sybase</strong> Learning Connection, <strong>Sybase</strong> MPP, <strong>Sybase</strong> SQL Desktop, <strong>Sybase</strong><br />
SQL Lifecycle, <strong>Sybase</strong> SQL Workgroup, <strong>Sybase</strong> Synergy Program, <strong>Sybase</strong> User Workbench, <strong>Sybase</strong> Virtual <strong>Server</strong> Architecture, <strong>Sybase</strong>Ware,<br />
Syber Financial, SyberAssist, SybMD, SyBooks, System 10, System 11, System XI (logo), SystemTools, Tabular Data Stream, The Enterprise<br />
Client/<strong>Server</strong> Company, The Extensible Software Platform, The Future Is Wi<strong>de</strong> Open, The Learning Connection, The Mo<strong>de</strong>l For Client/<strong>Server</strong><br />
Solutions, The Online Information Center, The Power of One, Tra<strong>de</strong>Force, Transact-SQL, Translation Toolkit, Turning Imagination Into Reality,<br />
UltraLite, UNIBOM, Unilib, Uninull, Unisep, Unistring, URK Runtime Kit for UniCo<strong>de</strong>, Viewer, Visual Components, VisualSpeller, VisualWriter,<br />
VQL, Warehouse Control Center, Warehouse Studio, Warehouse WORKS, WarehouseArchitect, Watcom, Watcom SQL, Watcom SQL <strong>Server</strong>,<br />
Web Deployment Kit, Web.PB, Web.SQL, WebSights, WebViewer, WorkGroup SQL <strong>Server</strong>, XA-Library, XA-<strong>Server</strong> et XP <strong>Server</strong> sont <strong>de</strong>s<br />
marques <strong>de</strong> <strong>Sybase</strong>, Inc. ou <strong>de</strong> ses filiales.<br />
Tous les autres noms <strong>de</strong> produit, société ou marque appartiennent à leurs propriétaires respectifs.<br />
Dernière mise à jour : Octobre 2002. Réf. du document : 03945-01-0802-01.
Table <strong>de</strong>s matières<br />
Préface ............................................................................. vii<br />
Documentation SQL <strong>Anywhere</strong> Studio ...................................viii<br />
Conventions ............................................................................. xi<br />
La base <strong>de</strong> données exemple <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> ................................................................................xiv<br />
Source d'informations complémentaires................................. xv<br />
1 Présentation <strong>de</strong> l'interface <strong>de</strong> <strong>programmation</strong> ................ 1<br />
Interface <strong>de</strong> <strong>programmation</strong> ODBC ..........................................2<br />
Interface <strong>de</strong> <strong>programmation</strong> OLE DB........................................3<br />
Interface <strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL ...........................4<br />
Interface <strong>de</strong> <strong>programmation</strong> JDBC ...........................................5<br />
Interface <strong>de</strong> <strong>programmation</strong> Open Client..................................6<br />
2 Utilisation <strong>de</strong> SQL dans les applications ......................... 9<br />
Exécution d'instructions SQL dans les<br />
applications .............................................................................10<br />
Préparation <strong>de</strong>s instructions ...................................................12<br />
Présentation <strong>de</strong>s curseurs ......................................................15<br />
Utilisation <strong>de</strong>s curseurs...........................................................20<br />
Choix d'un type <strong>de</strong> curseur .....................................................25<br />
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>......................................29<br />
Description <strong>de</strong>s jeux <strong>de</strong> résultats ............................................45<br />
Contrôle <strong>de</strong>s transactions dans les applications.....................47<br />
3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données ............ 51<br />
Introduction .............................................................................52<br />
FAQ concernant Java dans la base <strong>de</strong> données....................55<br />
Séminaire Java .......................................................................62<br />
Environnement d'exécution pour Java dans la<br />
base <strong>de</strong> données.....................................................................73<br />
Didacticiel : Java dans la base <strong>de</strong> données -<br />
Exercice pratique ....................................................................82<br />
iii
4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données ................ 91<br />
Introduction ............................................................................. 92<br />
Configuration <strong>de</strong> la base <strong>de</strong> données pour Java .................... 95<br />
Installation <strong>de</strong> classes Java dans une base <strong>de</strong><br />
données ................................................................................ 101<br />
Création <strong>de</strong> colonnes d'objets Java...................................... 106<br />
Insertion, mise à jour et suppression d'objets<br />
Java....................................................................................... 108<br />
Recherche d'objets Java....................................................... 114<br />
Comparaison <strong>de</strong>s champs et <strong>de</strong>s objets Java...................... 116<br />
Fonctionnalités spéciales <strong>de</strong>s classes Java dans<br />
la base <strong>de</strong> données............................................................... 120<br />
Stockage <strong>de</strong>s objets Java..................................................... 127<br />
Conception d'une base <strong>de</strong> données Java............................. 130<br />
Utilisation <strong>de</strong> colonnes calculées avec les classes<br />
Java....................................................................................... 134<br />
Configuration <strong>de</strong> la mémoire pour Java................................ 137<br />
5 Accès aux données via JDBC....................................... 139<br />
Présentation <strong>de</strong> JBDC .......................................................... 140<br />
Utilisation du gestionnaire JDBC jConnect ........................... 147<br />
Utilisation <strong>de</strong> la passerelle JDBC-ODBC .............................. 152<br />
Etablissement <strong>de</strong> connexions JDBC..................................... 154<br />
Utilisation <strong>de</strong> JDBC pour accé<strong>de</strong>r aux données ................... 162<br />
Création d'applications distribuées ....................................... 171<br />
6 Programmation avec Embed<strong>de</strong>d SQL.......................... 177<br />
Introduction ........................................................................... 178<br />
Exemples <strong>de</strong> programmes Embed<strong>de</strong>d SQL ......................... 186<br />
Types <strong>de</strong> données Embed<strong>de</strong>d SQL...................................... 192<br />
Utilisation <strong>de</strong>s variables hôte ................................................ 196<br />
Zone <strong>de</strong> communication SQL (SQLCA)................................ 205<br />
Lecture <strong>de</strong> données .............................................................. 211<br />
SQL statique et SQL dynamique .......................................... 221<br />
Zone <strong>de</strong>scripteur SQL (SQLDA) ........................................... 226<br />
Envoi et extraction <strong>de</strong> valeurs longues ................................. 235<br />
Utilisation <strong>de</strong> procédures stockées ....................................... 241<br />
Techniques <strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL .................. 245<br />
Préprocesseur SQL .............................................................. 247<br />
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque............................ 251<br />
Récapitulatif <strong>de</strong>s comman<strong>de</strong>s Embed<strong>de</strong>d SQL.................... 270<br />
iv
7 Programmation avec ODBC.......................................... 275<br />
Présentation d'ODBC............................................................276<br />
Création d'applications ODBC ..............................................278<br />
Exemples ODBC...................................................................283<br />
Descripteurs ODBC...............................................................285<br />
Connexion à une source <strong>de</strong> données ...................................288<br />
Exécution d'instructions SQL ................................................292<br />
Jeux <strong>de</strong> résultats ...................................................................297<br />
Appel <strong>de</strong> procédures stockées..............................................302<br />
Gestion <strong>de</strong>s erreurs...............................................................304<br />
8 Interface Outils <strong>de</strong> base <strong>de</strong> données............................ 309<br />
Introduction à l'interface Outils <strong>de</strong> base <strong>de</strong><br />
données ................................................................................310<br />
Utilisation <strong>de</strong> l'interface Outils <strong>de</strong> base <strong>de</strong><br />
données ................................................................................311<br />
Fonctions DBTools................................................................320<br />
Structures DBTools...............................................................332<br />
Types d'énumération DBTools..............................................364<br />
9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et<br />
ADO ................................................................................ 367<br />
Introduction à OLE DB ..........................................................368<br />
Programmation ADO avec <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> ..............................................................................370<br />
Interfaces OLE DB supportées .............................................378<br />
10 Interface Open Client..................................................... 385<br />
Préalables à la création d'applications<br />
Open Client ...........................................................................386<br />
Correspondances entre les types <strong>de</strong> données .....................387<br />
SQL dans les applications Open Client ................................389<br />
Limites d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> avec Open<br />
Client .....................................................................................392<br />
11 Transactions distribuées et architecture à trois<br />
niveaux ........................................................................... 393<br />
Introduction ...........................................................................394<br />
Architecture informatique à trois niveaux..............................395<br />
Utilisation <strong>de</strong>s transactions distribuées.................................399<br />
Utilisation d'EA<strong>Server</strong> avec <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> ..............................................................................401<br />
v
12 Déploiement <strong>de</strong> bases <strong>de</strong> données et<br />
d'applications ................................................................ 405<br />
Présentation du déploiement ................................................ 406<br />
Répertoires d'installation et noms <strong>de</strong> fichiers ....................... 409<br />
Utilisation <strong>de</strong>s objets et modèles InstallShield<br />
pour le déploiement .............................................................. 414<br />
Déploiement avec une installation silencieuse ..................... 416<br />
Déploiement <strong>de</strong>s applications clientes.................................. 420<br />
Déploiement <strong>de</strong>s outils d'administration ............................... 431<br />
Déploiement <strong>de</strong>s serveurs <strong>de</strong> base <strong>de</strong> données .................. 432<br />
Déploiement d'applications <strong>de</strong> base <strong>de</strong> données<br />
embarquées .......................................................................... 435<br />
13 Messages d’erreur du préprocesseur SQL.................. 439<br />
Messages d'erreur du préprocesseur SQL<br />
in<strong>de</strong>xés par valeur <strong>de</strong> message d'erreur............................... 440<br />
Erreurs SQLPP ..................................................................... 444<br />
vi<br />
In<strong>de</strong>x............................................................................... 461
Préface<br />
Présentation<br />
A qui s'adresse ce<br />
manuel ?<br />
Ce manuel explique comment construire et déployer les applications <strong>de</strong> base<br />
<strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong>s langages <strong>de</strong> <strong>programmation</strong> C, C++ et Java. Les<br />
utilisateurs <strong>de</strong> Visual Basic et PowerBuil<strong>de</strong>r peuvent recourir aux interfaces<br />
<strong>de</strong> <strong>programmation</strong> fournies par ces outils.<br />
Ce manuel s'adresse aux développeurs d'application qui écrivent <strong>de</strong>s<br />
programmes fonctionnant directement avec l'une <strong>de</strong>s interfaces d'<strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>.<br />
Si vous utilisez un outil <strong>de</strong> développement tel que PowerBuil<strong>de</strong>r ou Visual<br />
Basic, lesquels disposent <strong>de</strong> leur propre interface <strong>de</strong> base <strong>de</strong> données au<strong>de</strong>ssus<br />
d'ODBC, vous n'êtes pas concerné par ce manuel.<br />
vii
Documentation SQL <strong>Anywhere</strong> Studio<br />
viii<br />
Ce manuel fait partie <strong>de</strong> la documentation SQL <strong>Anywhere</strong> Studio. Cette<br />
section décrit les différents manuels <strong>de</strong> la documentation et explique<br />
comment les utiliser.<br />
La documentation <strong>de</strong> SQL <strong>Anywhere</strong> Studio<br />
La documentation <strong>de</strong> SQL <strong>Anywhere</strong> Studio comprend les manuels<br />
suivants :<br />
♦ Présentation <strong>de</strong> SQL <strong>Anywhere</strong> Studio Ce manuel présente les<br />
technologies <strong>de</strong> gestion <strong>de</strong> base <strong>de</strong> données et <strong>de</strong> synchronisation<br />
offertes par SQL <strong>Anywhere</strong> Studio. Il inclut <strong>de</strong>s didacticiels <strong>de</strong>stinés à<br />
vous initier aux différentes parties qui composent SQL <strong>Anywhere</strong><br />
Studio.<br />
♦ Nouvelles fonctionnalités <strong>de</strong> SQL <strong>Anywhere</strong> Studio Ce manuel<br />
s'adresse aux utilisateurs <strong>de</strong>s versions antérieures du logiciel. Il<br />
répertorie les nouvelles fonctionnalités <strong>de</strong> la version actuelle et <strong>de</strong>s<br />
versions précé<strong>de</strong>ntes du produit et décrit les procédures <strong>de</strong> mise à<br />
niveau.<br />
♦ ASA - Mise en route Ce manuel s'adresse aux utilisateurs qui<br />
découvrent les bases <strong>de</strong> données relationnelles et <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>. Il permet <strong>de</strong> maîtriser rapi<strong>de</strong>ment le système <strong>de</strong> gestion <strong>de</strong><br />
base <strong>de</strong> données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> et inclut <strong>de</strong>s présentations<br />
sur la conception, la construction et l'exploitation <strong>de</strong>s bases <strong>de</strong> données.<br />
♦ ASA - <strong>Gui<strong>de</strong></strong> d’administration Ce manuel traite du lancement, <strong>de</strong> la<br />
gestion et <strong>de</strong> la configuration <strong>de</strong>s bases <strong>de</strong> données.<br />
♦ ASA - <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL Ce manuel explique comment<br />
concevoir et créer <strong>de</strong>s bases <strong>de</strong> données, comment importer, exporter et<br />
modifier <strong>de</strong>s données, comment récupérer <strong>de</strong>s données et construire <strong>de</strong>s<br />
procédures stockées et <strong>de</strong>s triggers.<br />
♦ ASA - Manuel <strong>de</strong> référence SQL Ce manuel <strong>de</strong> référence fournit une<br />
<strong>de</strong>scription complète du langage SQL utilisé par <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>. Il présente également les tables et procédures système<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
♦ ASA - <strong>Gui<strong>de</strong></strong> <strong>de</strong> <strong>programmation</strong> Ce manuel explique comment<br />
construire et déployer les applications <strong>de</strong> base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong>s<br />
langages <strong>de</strong> <strong>programmation</strong> C, C++ et Java. Les utilisateurs <strong>de</strong> Visual<br />
Basic et PowerBuil<strong>de</strong>r peuvent recourir aux interfaces <strong>de</strong><br />
<strong>programmation</strong> fournies par ces outils.
Formats <strong>de</strong> la documentation<br />
♦ ASA - Messages d’erreur Ce manuel fournit la liste complète <strong>de</strong>s<br />
messages d'erreur d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, ainsi que <strong>de</strong>s<br />
informations <strong>de</strong> diagnostic.<br />
♦ ASA - Système <strong>de</strong> sécurité C2 Dans le cadre <strong>de</strong>s critères d'évaluation<br />
<strong>de</strong> la sécurité <strong>de</strong>s systèmes informatiques (TCSEC, Trusted Computer<br />
System Evaluation Criteria), le gouvernement américain a décerné la<br />
classe C2 à <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> 7.0. Ce manuel s'adresse plus<br />
particulièrement à ceux qui souhaitent utiliser la version actuelle<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> conformément aux exigences <strong>de</strong><br />
l'environnement certifié C2. Ce manuel n’inclut pas les fonctionnalités<br />
<strong>de</strong> sécurité ajoutées au produit <strong>de</strong>puis la certification.<br />
♦ Synchronisation MobiLink - <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur Ce manuel décrit<br />
tous les aspects du système <strong>de</strong> synchronisation <strong>de</strong>s données MobiLink<br />
pour l'informatique mobile, qui permet le partage <strong>de</strong>s données entre une<br />
base Oracle, <strong>Sybase</strong>, Microsoft ou IBM unique et plusieurs bases <strong>de</strong><br />
données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> ou UltraLite.<br />
♦ SQL Remote - <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur Ce manuel décrit tous les aspects<br />
du système <strong>de</strong> réplication <strong>de</strong>s données SQL Remote pour l'informatique<br />
mobile. Ce système permet le partage <strong>de</strong>s données entre une seule base<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> ou <strong>Adaptive</strong> <strong>Server</strong> Enterprise et plusieurs<br />
bases <strong>de</strong> données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> via un lien indirect tel que<br />
la messagerie électronique ou le transfert <strong>de</strong> fichiers.<br />
♦ UltraLite - <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur Ce manuel décrit comment construire<br />
<strong>de</strong>s applications <strong>de</strong> base <strong>de</strong> données pour <strong>de</strong> petits périphériques tels que<br />
les organiseurs <strong>de</strong> poche, à l'ai<strong>de</strong> <strong>de</strong> la technologie <strong>de</strong> déploiement<br />
UltraLite pour les bases <strong>de</strong> données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
♦ UltraLite User’s <strong>Gui<strong>de</strong></strong> to PenRight! MobileBuil<strong>de</strong>r (disponible en<br />
version anglaise seulement) Ce manuel s'adresse aux utilisateurs <strong>de</strong><br />
l'outil <strong>de</strong> développement PenRight! MobileBuil<strong>de</strong>r. Il décrit comment<br />
utiliser la technologie UltraLite dans l'environnement <strong>de</strong> <strong>programmation</strong><br />
MobileBuil<strong>de</strong>r.<br />
♦ SQL <strong>Anywhere</strong> Studio - Ai<strong>de</strong> Ce manuel est exclusivement disponible<br />
en ligne. Il inclut l'ai<strong>de</strong> contextuelle <strong>de</strong> <strong>Sybase</strong> Central,<br />
d'Interactive SQL et d'autres outils graphiques.<br />
PowerAMC et InfoMaker disposent également <strong>de</strong> leur propre documentation<br />
en ligne.<br />
La documentation <strong>de</strong> SQL <strong>Anywhere</strong> Studio se présente sous les formats<br />
suivants :<br />
ix
x<br />
♦ Documentation en ligne Elle inclut toute la documentation <strong>de</strong><br />
SQL <strong>Anywhere</strong> Studio, y compris les livres imprimés et l'ai<strong>de</strong><br />
contextuelle <strong>de</strong>s outils SQL <strong>Anywhere</strong>. Elle est mise à jour à chaque<br />
version <strong>de</strong> maintenance du produit et constitue la source <strong>de</strong><br />
documentation la plus complète et la plus récente.<br />
Pour accé<strong>de</strong>r à la documentation en ligne sous les systèmes<br />
d'exploitation Windows, choisissez Démarrer➤Programmes➤<strong>Sybase</strong><br />
SQL <strong>Anywhere</strong> 8➤Documentation en ligne. Vous pouvez explorer cette<br />
documentation à partir du sommaire, <strong>de</strong> l'in<strong>de</strong>x et à l'ai<strong>de</strong> <strong>de</strong> la fonction<br />
<strong>de</strong> recherche <strong>de</strong> l'Ai<strong>de</strong> HTML dans le volet gauche ou en utilisant les<br />
liens et les menus dans le volet droit.<br />
Pour accé<strong>de</strong>r à la documentation en ligne sous les systèmes<br />
d'exploitation UNIX, exécutez la comman<strong>de</strong> suivante à l'invite <strong>de</strong><br />
comman<strong>de</strong>s :<br />
dbbooks<br />
♦ Manuels imprimables Les manuels SQL <strong>Anywhere</strong> sont fournis sous<br />
format PDF et se lisent avec Adobe Acrobat Rea<strong>de</strong>r.<br />
Les fichiers PDF sont disponibles sur le CD-ROM dans le répertoire<br />
pdf_docs. Vous pouvez déci<strong>de</strong>r <strong>de</strong> les installer lors <strong>de</strong> l'exécution du<br />
programme d'installation.<br />
♦ Manuels imprimés Le coffret SQL <strong>Anywhere</strong> Studio comprend les<br />
manuels suivants :<br />
♦ Présentation <strong>de</strong> SQL <strong>Anywhere</strong> Studio<br />
♦ ASA - Mise en route<br />
♦ SQL <strong>Anywhere</strong> Studio <strong>Gui<strong>de</strong></strong> <strong>de</strong> référence rapi<strong>de</strong>. Ce manuel est<br />
exclusivement disponible sous forme imprimée.<br />
La totalité <strong>de</strong>s manuels est disponible sous le nom <strong>de</strong> Documentation<br />
SQL <strong>Anywhere</strong> auprès <strong>de</strong> <strong>Sybase</strong> ou à la boutique en ligne <strong>de</strong> <strong>Sybase</strong>,<br />
l'e-Shop, à l'adresse suivante : http://e-shop.sybase.com/cgibin/eshop.storefront/.
Conventions<br />
Conventions syntaxiques<br />
Cette section décrit les conventions syntaxiques, typographiques et<br />
graphiques employées dans ce manuel.<br />
Les exemples <strong>de</strong> syntaxe SQL s'appuient sur les conventions suivantes :<br />
♦ Mots-clés Tous les mots-clés SQL sont indiqués en majuscules. Par<br />
exemple :<br />
ALTER TABLE [ propriétaire.]nom_table<br />
♦ Marques <strong>de</strong> réservation Les éléments à remplacer par <strong>de</strong>s expressions<br />
ou <strong>de</strong>s i<strong>de</strong>ntificateurs appropriés apparaissent en italique. Par exemple :<br />
ALTER TABLE [ propriétaire.]nom_table<br />
♦ Eléments répétitifs Dans une liste contenant <strong>de</strong>s éléments qui se<br />
répètent, le nom d'un élément <strong>de</strong> la liste est suivi <strong>de</strong> points <strong>de</strong> suspension<br />
(...). Par exemple :<br />
ADD définition_colonne [ contrainte_colonne, … ]<br />
Une liste peut comprendre un ou plusieurs éléments. Dans ce <strong>de</strong>rnier<br />
cas, les éléments sont séparés par une virgule.<br />
♦ Eléments facultatifs Les éléments facultatifs d'une instruction sont<br />
placés entre crochets.<br />
RELEASE SAVEPOINT [nom_point<strong>de</strong>sauvegar<strong>de</strong>]<br />
Les crochets indiquent que le paramètre nom_point<strong>de</strong>sauvegar<strong>de</strong> est<br />
facultatif. Les crochets ne doivent pas être saisis.<br />
♦ Options Lorsqu'un seul élément <strong>de</strong> la liste (ou aucun) doit être déclaré,<br />
les éléments sont séparés par <strong>de</strong>s barres verticales et la liste est placée<br />
entre crochets.<br />
[ ASC | DESC ]<br />
Par exemple, vous pouvez choisir le paramètre ASC ou DESC, ou aucun<br />
<strong>de</strong>s <strong>de</strong>ux. Les crochets ne doivent pas être saisis.<br />
♦ Options obligatoires Lorsque vous <strong>de</strong>vez obligatoirement spécifier une<br />
valeur, les choix possibles sont placés entre accola<strong>de</strong>s.<br />
[ QUOTES { ON | OFF } ]<br />
Si l'option QUOTES est sélectionnée, ON ou OFF doit également être<br />
spécifié. Les crochets et les accola<strong>de</strong>s ne doivent pas être saisis.<br />
xi
Icônes<br />
xii<br />
♦ Options multiples Si vous choisissez plusieurs options, séparez vos<br />
choix par <strong>de</strong>s virgules.<br />
{ CONNECT, DBA, RESOURCE }<br />
Les icônes suivantes sont utilisées dans cette documentation :
Icône Signification<br />
API<br />
Application cliente<br />
Serveur <strong>de</strong> base <strong>de</strong> données (par exemple, <strong>Sybase</strong><br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> ou <strong>Adaptive</strong> <strong>Server</strong><br />
Enterprise).<br />
Application et serveur <strong>de</strong> base <strong>de</strong> données UltraLite.<br />
Dans UltraLite, le serveur <strong>de</strong> base <strong>de</strong> données et<br />
l'application font partie du même processus.<br />
Base <strong>de</strong> données. Dans certains diagrammes élaborés,<br />
l'icône peut servir à représenter à la fois la base <strong>de</strong><br />
données et le serveur qui la gère.<br />
Middleware <strong>de</strong> réplication ou <strong>de</strong> synchronisation. Ils<br />
participent au partage <strong>de</strong>s données entre les bases.<br />
Exemples : serveur <strong>de</strong> synchronisation MobiLink,<br />
agent <strong>de</strong> message SQL Remote et agent <strong>de</strong> réplication<br />
LTM qui sont utilisés avec le Replication <strong>Server</strong>.<br />
<strong>Sybase</strong> Replication <strong>Server</strong><br />
Interface <strong>de</strong> <strong>programmation</strong><br />
xiii
La base <strong>de</strong> données exemple <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong><br />
xiv<br />
De nombreux exemples <strong>de</strong> la documentation font appel à la base <strong>de</strong> données<br />
exemple <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
La base <strong>de</strong> données exemple est stockée dans un fichier appelé asa<strong>de</strong>mo.db<br />
et situé dans votre répertoire SQL <strong>Anywhere</strong>.<br />
Cette base <strong>de</strong> données représente une petite société. Elle contient <strong>de</strong>s<br />
informations concernant la société (employés, services et finances), les<br />
produits et les ventes (comman<strong>de</strong>s, clients et contacts). Toutes les<br />
informations contenues dans la base <strong>de</strong> données relèvent <strong>de</strong> la pure fiction.<br />
La figure suivante montre les tables <strong>de</strong> la base <strong>de</strong> données exemple et leurs<br />
relations.<br />
product<br />
id integer<br />
name char(15)<br />
<strong>de</strong>scription char(30)<br />
size char(18)<br />
color char(6)<br />
quantity integer<br />
unit_price numeric(15,2)<br />
customer<br />
id integer<br />
fname char(15)<br />
lname char(20)<br />
address char(35)<br />
city char(20)<br />
state char(2)<br />
zip char(10)<br />
phone char(12)<br />
company_name char(35)<br />
contact<br />
id integer<br />
last_name char(15)<br />
first_name char(15)<br />
title char(2)<br />
street char(30)<br />
city char(20)<br />
state char(2)<br />
zip char(5)<br />
phone char(10)<br />
fax char(10)<br />
id = prod_id<br />
id = cust_id<br />
asa<strong>de</strong>mo.db<br />
sales_or<strong>de</strong>r_items<br />
id integer<br />
line_id smallint<br />
prod_id integer<br />
quantity integer<br />
ship_date date<br />
id = id<br />
sales_or<strong>de</strong>r<br />
id integer<br />
cust_id integer<br />
or<strong>de</strong>r_date date<br />
fin_co<strong>de</strong>_id char(2)<br />
region char(7)<br />
sales_rep integer<br />
co<strong>de</strong> = fin_co<strong>de</strong>_id<br />
emp_id = sales_rep<br />
fin_co<strong>de</strong><br />
co<strong>de</strong> char(2)<br />
type char(10)<br />
<strong>de</strong>scription char(50)<br />
co<strong>de</strong> = co<strong>de</strong><br />
fin_data<br />
year char(4)<br />
quarter char(2)<br />
co<strong>de</strong> char(2)<br />
amount numeric(9)<br />
employee<br />
emp_id integer<br />
manager_id integer<br />
emp_fname char(20)<br />
emp_lname char(20)<br />
<strong>de</strong>pt_id integer<br />
street char(40)<br />
city char(20)<br />
state char(4)<br />
zip_co<strong>de</strong> char(9)<br />
phone char(10)<br />
status char(1)<br />
ss_number char(11)<br />
salary numeric(20,3)<br />
start_date date<br />
termination_date date<br />
birth_date date<br />
bene_health_ins char(1)<br />
bene_life_ins char(1)<br />
bene_day_care char(1)<br />
sex char(1)<br />
<strong>de</strong>pt_id = <strong>de</strong>pt_id<br />
emp_id = <strong>de</strong>pt_head_id<br />
<strong>de</strong>partment<br />
<strong>de</strong>pt_id integer<br />
<strong>de</strong>pt_name char(40)<br />
<strong>de</strong>pt_head_id integer
Source d'informations complémentaires<br />
Si vous avez <strong>de</strong>s observations sur le contenu <strong>de</strong> cette documentation et sur le<br />
logiciel, nous vous serions reconnaissants <strong>de</strong> nous en faire part.<br />
Vous pouvez nous les adresser par l'intermédiaire <strong>de</strong>s forums (newsgroups)<br />
mis en place pour discuter <strong>de</strong>s technologies <strong>de</strong> SQL <strong>Anywhere</strong>. Ces forums<br />
sont accessibles sur le serveur forums.sybase.com.<br />
Les forums se déclinent comme suit :<br />
♦ sybase.public.sqlanywhere.general.<br />
♦ sybase.public.sqlanywhere.linux.<br />
♦ sybase.public.sqlanywhere.mobilink.<br />
♦ sybase.public.sqlanywhere.product_futures_discussion.<br />
♦ sybase.public.sqlanywhere.replication.<br />
♦ sybase.public.sqlanywhere.ultralite.<br />
Dédit <strong>de</strong> responsabilité pour les forums<br />
La société i<strong>Anywhere</strong> Solutions n'est nullement tenue <strong>de</strong> fournir <strong>de</strong>s<br />
solutions, <strong>de</strong>s informations ou <strong>de</strong>s avis concernant ses forums. Elle n'est<br />
pas dans l'obligation <strong>de</strong> fournir un service supplémentaire autre que celui<br />
<strong>de</strong> l'opérateur système prévu pour contrôler le service et garantir son<br />
fonctionnement ainsi que sa disponibilité.<br />
Les conseillers techniques d'i<strong>Anywhere</strong> Solutions ainsi que d'autres<br />
catégories <strong>de</strong> personnel participent à l'exploitation du forum lorsque leurs<br />
disponibilités le leur permettent. Ils apportent leur ai<strong>de</strong> <strong>de</strong> manière<br />
bénévole et ne peuvent pas être disponibles régulièrement pour fournir <strong>de</strong>s<br />
solutions ou <strong>de</strong>s informations. Leur aptitu<strong>de</strong> à fournir une ai<strong>de</strong> dépend <strong>de</strong><br />
leur charge <strong>de</strong> travail.<br />
xv
xvi
CHAPITRE 1<br />
Présentation <strong>de</strong> l'interface <strong>de</strong><br />
<strong>programmation</strong><br />
Présentation<br />
Sommaire<br />
Ce chapitre présente les interfaces <strong>de</strong> <strong>programmation</strong><br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Toute application cliente utilise une <strong>de</strong> ces<br />
interfaces pour communiquer avec la base <strong>de</strong> données.<br />
Sujet Page<br />
Interface <strong>de</strong> <strong>programmation</strong> ODBC 2<br />
Interface <strong>de</strong> <strong>programmation</strong> OLE DB 3<br />
Interface <strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL 4<br />
Interface <strong>de</strong> <strong>programmation</strong> JDBC 5<br />
Interface <strong>de</strong> <strong>programmation</strong> Open Client 6<br />
1
Interface <strong>de</strong> <strong>programmation</strong> ODBC<br />
Interface <strong>de</strong> <strong>programmation</strong> ODBC<br />
2<br />
ODBC (Open Database Connectivity) est une interface CLI (call level<br />
interface) standard développée par Microsoft. Elle est fondée sur la<br />
spécification CLI SQL Access Group. Les applications ODBC sont<br />
exécutables sur n'importe quelle source <strong>de</strong> données dotée d'un pilote ODBC.<br />
Vous <strong>de</strong>vez utiliser ODBC si vous voulez que votre application soit<br />
transférable vers d'autres sources <strong>de</strong> données disposant <strong>de</strong> pilotes ODBC. En<br />
outre, si vous préférez utiliser une API, utilisez ODBC.<br />
ODBC est une interface <strong>de</strong> bas niveau, semblable à Embed<strong>de</strong>d SQL. Elle<br />
permet d'accé<strong>de</strong>r à la plupart <strong>de</strong>s fonctionnalités<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. ODBC est disponible sous la forme d'une DLL<br />
dans tous les systèmes d'exploitation Windows à l'exception <strong>de</strong><br />
Windows CE. Pour UNIX, elle est fournie sous forme <strong>de</strong> bibliothèque.<br />
Microsoft ODBC Software Development Kit constitue la documentation<br />
principale d'ODBC. Ce manuel contient <strong>de</strong>s notes complémentaires,<br />
spécifiquement fournies à l'intention <strong>de</strong>s développeurs<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> pour ODBC.<br />
$ ODBC est décrit dans "Programmation avec ODBC", page 275.
Chapitre 1 Présentation <strong>de</strong> l'interface <strong>de</strong> <strong>programmation</strong><br />
Interface <strong>de</strong> <strong>programmation</strong> OLE DB<br />
OLE DB est un ensemble d’interfaces COM (Component Object Mo<strong>de</strong>l)<br />
développées par Microsoft, qui fournissent aux applications un accès<br />
uniformisé aux données stockées dans diverses sources d'information et<br />
permettent <strong>de</strong> mettre en oeuvre <strong>de</strong>s services <strong>de</strong> base <strong>de</strong> données<br />
supplémentaires. Ces interfaces supportent les nombreuses<br />
fonctionnalités SGBD appropriées à l'environnement <strong>de</strong> stockage, lui<br />
permettant ainsi <strong>de</strong> partager ses données.<br />
ADO est un modèle d'objet qui permet d'atteindre, <strong>de</strong> modifier et <strong>de</strong> mettre à<br />
jour par <strong>programmation</strong> un grand nombre <strong>de</strong> sources <strong>de</strong> données par<br />
l'intermédiaire <strong>de</strong>s interfaces du système OLE DB. ADO est également<br />
développé par Microsoft. La plupart <strong>de</strong>s développeurs utilisent l'interface <strong>de</strong><br />
<strong>programmation</strong> OLE DB en écrivant dans l'API ADO, et non en accédant<br />
directement à l'API OLE DB.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> inclut un fournisseur OLE DB pour les<br />
programmeurs OLE DB et ADO.<br />
La documentation principale relative à la <strong>programmation</strong> OLE DB et ADO<br />
provient du Microsoft Developer Network. Ce manuel contient <strong>de</strong>s notes<br />
complémentaires, spécifiquement fournies à l'intention <strong>de</strong>s développeurs<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> pour ADO et OLE DB.<br />
$ Pour plus d'informations, reportez-vous au chapitre "Les interfaces <strong>de</strong><br />
<strong>programmation</strong> OLE DB et ADO", page 367.<br />
3
Interface <strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL<br />
Interface <strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL<br />
4<br />
Embed<strong>de</strong>d SQL est un système dans lequel les comman<strong>de</strong>s SQL sont<br />
imbriquées directement dans un fichier source C ou C++. Un préprocesseur<br />
convertit ces instructions en appels à une bibliothèque d'exécution.<br />
Embed<strong>de</strong>d SQL est une norme ISO/ANSI et IBM.<br />
Embed<strong>de</strong>d SQL peut être porté sur d'autres bases <strong>de</strong> données et<br />
environnements, et offre <strong>de</strong>s fonctions équivalentes dans tous les<br />
environnements d'exploitation. Il fournit toutes les fonctionnalités<br />
disponibles dans le produit. Même si l'idée d'imbriquer <strong>de</strong>s instructions SQL<br />
(plutôt que <strong>de</strong>s appels <strong>de</strong> fonction) dans du co<strong>de</strong> C peut paraître déroutante<br />
au début, Embed<strong>de</strong>d SQL reste d'un maniement aisé.<br />
$ Embed<strong>de</strong>d SQL est présenté dans le chapitre "Programmation avec<br />
Embed<strong>de</strong>d SQL", page 177.
Chapitre 1 Présentation <strong>de</strong> l'interface <strong>de</strong> <strong>programmation</strong><br />
Interface <strong>de</strong> <strong>programmation</strong> JDBC<br />
JDBC est une interface call level pour les applications Java. Développée par<br />
Sun Microsystems, JDBC fournit aux programmeurs Java une interface<br />
uniforme pour différentes bases <strong>de</strong> données relationnelles et constitue une<br />
base commune pour les conceptions d'outils et d'interfaces <strong>de</strong> niveau<br />
supérieur. JDBC, désormais un composant standard <strong>de</strong> Java, est incluse dans<br />
le JDK.<br />
SQL <strong>Anywhere</strong> Studio fournit un pilote Java JDBC pur, nommé <strong>Sybase</strong><br />
jConnect. Il comprend également une passerelle JDBC-ODBC. Tous <strong>de</strong>ux<br />
font l'objet d'une <strong>de</strong>scription dans la rubrique "Accès aux données via<br />
JDBC", page 139. Pour obtenir <strong>de</strong>s informations sur le choix d'un pilote,<br />
reportez-vous à "Choix d'un pilote JDBC", page 141.<br />
JDBC constitue, côté client, une interface <strong>de</strong> <strong>programmation</strong> mais également,<br />
côté serveur, une métho<strong>de</strong> d'accès aux données Java <strong>de</strong> la base. C'est pour<br />
cela que JDBC est documentée en tant que composant <strong>de</strong> Java dans la base<br />
<strong>de</strong> données.<br />
$ L'interface JDBC n'est pas décrite dans le présent manuel. Pour obtenir<br />
une <strong>de</strong>scription <strong>de</strong> JDBC, reportez-vous au chapitre "Accès aux données via<br />
JDBC", page 139.<br />
5
Interface <strong>de</strong> <strong>programmation</strong> Open Client<br />
Interface <strong>de</strong> <strong>programmation</strong> Open Client<br />
Contexte<br />
d’utilisation d’Open<br />
Client<br />
Architecture d’Open Client<br />
Client-Library et<br />
DB-Library<br />
Services <strong>de</strong> réseau<br />
6<br />
<strong>Sybase</strong> Open Client fournit <strong>de</strong>s applications clientes, <strong>de</strong>s produits tiers et<br />
d’autres produits <strong>Sybase</strong> avec les interfaces requises pour communiquer avec<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> et d’autres Open <strong>Server</strong>s.<br />
Envisagez d’utiliser l’interface Open Client si la compatibilité avec<br />
<strong>Adaptive</strong> <strong>Server</strong> Enterprise vous préoccupe ou si vous utilisez d'autres<br />
produits <strong>Sybase</strong> qui supportent l'interface Open Client, notamment<br />
Replication <strong>Server</strong>.<br />
$ L'interface Open Client est décrite dans le chapitre "Interface Open<br />
Client", page 385.<br />
$ Pour plus d'informations sur l'interface Open Client, reportez-vous au<br />
chapitre "<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> exploité comme un Open <strong>Server</strong>",<br />
page 111 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
On peut considérer qu'Open Client est constitué <strong>de</strong> <strong>de</strong>ux composants : les<br />
interfaces <strong>de</strong> <strong>programmation</strong> et les services <strong>de</strong> réseau.<br />
Open Client offre <strong>de</strong>ux interfaces <strong>de</strong> <strong>programmation</strong> principales pour écrire<br />
les applications clients : DB-Library et Client-Library.<br />
Open Client DB-Library supporte les anciennes applications Open Client ;<br />
cette interface <strong>de</strong> <strong>programmation</strong> est complètement distincte <strong>de</strong> Client-<br />
Library. DB-Library est documentée dans Open Client DB-Library/C<br />
Reference Manual, fourni avec le produit <strong>Sybase</strong> Open Client.<br />
Les programmes Client-Library sont aussi dépendants <strong>de</strong> CS-Library, qui<br />
fournit <strong>de</strong>s routines utilisées à la fois dans les applications Client-Library et<br />
<strong>Server</strong>-Library. Les applications Client-Library peuvent également utiliser<br />
<strong>de</strong>s routines Bulk-Library pour faciliter les transferts <strong>de</strong> données à haut débit.<br />
CS-Library et Bulk-Library sont incluses dans <strong>Sybase</strong> Open Client,<br />
disponible séparément.<br />
Les services <strong>de</strong> réseau Open Client comprennent <strong>Sybase</strong> Net-Library, qui<br />
assure le support <strong>de</strong>s protocoles <strong>de</strong> réseau spécifiques, tels que TCP/IP et<br />
DECnet. L'interface Net-Library est invisible pour les programmeurs<br />
d'applications. Toutefois, sur certaines plates-formes, une application peut<br />
nécessiter un pilote Net-Library spécifique selon la configuration réseau.<br />
Selon la plate-forme hôte, le pilote Net-Library est spécifié par la<br />
configuration <strong>Sybase</strong> du système ou au moment <strong>de</strong> la compilation et <strong>de</strong> la<br />
liaison <strong>de</strong> vos programmes.
Chapitre 1 Présentation <strong>de</strong> l'interface <strong>de</strong> <strong>programmation</strong><br />
$ Des instructions <strong>de</strong> configuration du pilote sont fournies dans Open<br />
Client/<strong>Server</strong> - Manuel <strong>de</strong> configuration.<br />
$ Des instructions relatives à l'élaboration <strong>de</strong> programmes Client-Library<br />
sont fournies dans Open Client/<strong>Server</strong> Programmer’s Supplement.<br />
7
Interface <strong>de</strong> <strong>programmation</strong> Open Client<br />
8
CHAPITRE 2<br />
Utilisation <strong>de</strong> SQL dans les applications<br />
Présentation<br />
Sommaire<br />
Bien que <strong>de</strong> nombreux aspects du développement d'applications <strong>de</strong> base <strong>de</strong><br />
données dépen<strong>de</strong>nt <strong>de</strong> votre outil <strong>de</strong> développement d'applications, <strong>de</strong><br />
l'interface <strong>de</strong> base <strong>de</strong> données et du langage <strong>de</strong> <strong>programmation</strong>, un certain<br />
nombre <strong>de</strong> problèmes et <strong>de</strong> principes sont communs.<br />
Ce chapitre présente quelques techniques et principes communs à quasiment<br />
toutes les interfaces et donne <strong>de</strong>s indications pour trouver <strong>de</strong>s informations<br />
complémentaires. Il ne prétend pas être un gui<strong>de</strong> détaillé <strong>de</strong> <strong>programmation</strong>.<br />
Sujet Page<br />
Exécution d'instructions SQL dans les applications 10<br />
Préparation <strong>de</strong>s instructions 12<br />
Présentation <strong>de</strong>s curseurs 15<br />
Utilisation <strong>de</strong>s curseurs 20<br />
Choix d'un type <strong>de</strong> curseur 25<br />
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> 29<br />
Description <strong>de</strong>s jeux <strong>de</strong> résultats 45<br />
Contrôle <strong>de</strong>s transactions dans les applications 47<br />
9
Exécution d'instructions SQL dans les applications<br />
Exécution d'instructions SQL dans les<br />
applications<br />
10<br />
Le mo<strong>de</strong> d'intégration d'instructions SQL dans une application dépend <strong>de</strong><br />
l'outil <strong>de</strong> développement <strong>de</strong>s applications et <strong>de</strong> l'interface <strong>de</strong> <strong>programmation</strong><br />
utilisés.<br />
♦ ODBC Si vous écrivez directement dans l'interface <strong>de</strong> <strong>programmation</strong><br />
ODBC, les instructions SQL apparaissent dans les appels <strong>de</strong> fonction.<br />
Par exemple, l'appel <strong>de</strong> fonction C suivant exécute une instruction<br />
DELETE :<br />
SQLExecDirect( stmt,<br />
"DELETE FROM employee<br />
WHERE emp_id = 105",<br />
SQL_NTS );<br />
♦ JDBC Si vous travaillez sous l'interface <strong>de</strong> <strong>programmation</strong> JDBC, vous<br />
pouvez exécuter les instructions SQL en invoquant les métho<strong>de</strong>s <strong>de</strong><br />
l'objet statement. Par exemple :<br />
stmt.executeUpdate(<br />
"DELETE FROM employee<br />
WHERE emp_id = 105" );<br />
♦ Embed<strong>de</strong>d SQL Si vous utilisez Embed<strong>de</strong>d SQL, mettez le mot-clé<br />
EXEC SQL en préfixe à vos instructions SQL en langage C. Le co<strong>de</strong> est<br />
ensuite traité par un préprocesseur avant d'être compilé. Par exemple :<br />
EXEC SQL EXECUTE IMMEDIATE<br />
’DELETE FROM employee<br />
WHERE emp_id = 105’;<br />
♦ <strong>Sybase</strong> Open Client Si vous travaillez sous l'interface <strong>Sybase</strong> Open<br />
Client, vos instructions SQL apparaissent dans <strong>de</strong>s appels <strong>de</strong> fonction.<br />
Par exemple, les <strong>de</strong>ux appels suivants exécutent une instruction<br />
DELETE :<br />
ret = ct_command(cmd, CS_LANG_CMD,<br />
"DELETE FROM employee<br />
WHERE emp_id=105"<br />
CS_NULLTERM,<br />
CS_UNUSED);<br />
ret = ct_send(cmd);<br />
♦ Outils <strong>de</strong> développement d'applications Les outils <strong>de</strong> développement<br />
d'applications tels que ceux <strong>de</strong> la famille <strong>Sybase</strong> Enterprise Application<br />
Studio fournissent leurs propres objets SQL, qui utilisent soit ODBC<br />
(PowerBuil<strong>de</strong>r), soit JDBC (Power J).
Applications dans<br />
le serveur<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
$ Pour plus <strong>de</strong> détails sur l'intégration <strong>de</strong> SQL dans votre application,<br />
reportez-vous à la documentation <strong>de</strong> votre outil <strong>de</strong> développement. Si vous<br />
exploitez ODBC ou JDBC, consultez le kit <strong>de</strong> développement logiciel pour<br />
ces interfaces.<br />
$ Pour plus d'informations sur la <strong>programmation</strong> avec Embed<strong>de</strong>d SQL,<br />
reportez-vous au chapitre "Programmation avec Embed<strong>de</strong>d SQL", page 177.<br />
A <strong>de</strong> nombreux égards, les procédures stockées et les triggers agissent<br />
comme <strong>de</strong>s applications ou <strong>de</strong>s parties d'application exécutées à l'intérieur du<br />
serveur. Vous pouvez utiliser pour <strong>de</strong>s procédures stockées la plupart <strong>de</strong>s<br />
techniques décrites ici. Les procédures stockées utilisent <strong>de</strong>s instructions très<br />
similaires aux instructions Embed<strong>de</strong>d SQL.<br />
$ Pour plus d'informations sur les procédures stockées et les triggers,<br />
reportez-vous au chapitre "Utilisation <strong>de</strong>s procédures, <strong>de</strong>s triggers et <strong>de</strong>s<br />
batchs", page 541 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL.<br />
Les classes Java présentes dans la base <strong>de</strong> données peuvent utiliser l'interface<br />
JDBC exactement comme les applications Java en <strong>de</strong>hors du serveur. Ce<br />
chapitre traite <strong>de</strong> quelques aspects <strong>de</strong> JDBC. Pour plus d'informations sur<br />
JDBC, reportez-vous au chapitre "Accès aux données via JDBC", page 139.<br />
11
Préparation <strong>de</strong>s instructions<br />
Préparation <strong>de</strong>s instructions<br />
Instructions<br />
préparées et<br />
amélioration <strong>de</strong>s<br />
performances<br />
Ne préparez pas<br />
les instructions qui<br />
ne seront<br />
exécutées qu'une<br />
fois<br />
12<br />
Chaque fois qu'une instruction est envoyée à une base <strong>de</strong> données, le serveur<br />
doit d'abord la préparer. La préparation <strong>de</strong> l'instruction englobe plusieurs<br />
tâches :<br />
♦ Analyse <strong>de</strong> l'instruction et conversion en un format interne.<br />
♦ Vérification <strong>de</strong> toutes les références aux objets <strong>de</strong> base <strong>de</strong> données, en<br />
contrôlant, par exemple, l'existence <strong>de</strong>s colonnes nommées dans la liste<br />
d'une requête.<br />
♦ Si l'instruction implique <strong>de</strong>s jointures ou <strong>de</strong>s sous-requêtes, génération<br />
d'un plan d'accès par l'optimiseur <strong>de</strong> requêtes.<br />
♦ Exécution <strong>de</strong> l'instruction une fois toutes ces opérations accomplies.<br />
Si vous utilisez une même instruction <strong>de</strong> façon répétitive, par exemple pour<br />
insérer <strong>de</strong>s lignes dans une table, le fait <strong>de</strong> répéter la préparation <strong>de</strong><br />
l'instruction entraîne une surcharge importante et inutile. Pour éliminer cette<br />
surcharge, certaines interfaces <strong>de</strong> <strong>programmation</strong> <strong>de</strong> bases <strong>de</strong> données<br />
autorisent le recours à <strong>de</strong>s instructions préparées. Une instruction préparée<br />
est une instruction contenant une série <strong>de</strong> marques <strong>de</strong> réservation. Au<br />
moment <strong>de</strong> l'exécuter, il vous suffit d'attribuer <strong>de</strong>s valeurs aux marques <strong>de</strong><br />
réservation au lieu <strong>de</strong> recommencer entièrement la préparation <strong>de</strong><br />
l'instruction.<br />
Le recours aux instructions préparées est particulièrement utile pour effectuer<br />
plusieurs actions i<strong>de</strong>ntiques, par exemple pour insérer plusieurs lignes.<br />
L'utilisation d'instructions préparées implique généralement les étapes<br />
suivantes :<br />
1 Préparation <strong>de</strong> l'instruction Cette étape consiste généralement à fournir<br />
l'instruction avec <strong>de</strong>s marques <strong>de</strong> réservation et non <strong>de</strong>s valeurs.<br />
2 Exécution à plusieurs reprises <strong>de</strong> l'instruction préparée Dans cette<br />
étape, vous fournissez les valeurs à utiliser chaque fois que l'instruction<br />
est exécutée. Il est inutile <strong>de</strong> préparer chaque fois l'instruction.<br />
3 Suppression <strong>de</strong> l’instruction Dans cette étape, vous libérez les<br />
ressources associées à l'instruction préparée. Certaines interfaces <strong>de</strong><br />
<strong>programmation</strong> gèrent automatiquement cette étape.<br />
En général, il est superflu <strong>de</strong> préparer <strong>de</strong>s instructions si elles ne doivent être<br />
exécutées qu'une seule fois. La préparation et l'exécution d'une instruction<br />
ponctuelle pénalisent légèrement les performances et compliquent<br />
inutilement votre application.
Instructions préparées<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Dans certaines interfaces, toutefois, vous n'avez pas besoin <strong>de</strong> préparer une<br />
instruction pour l'associer à un curseur.<br />
$ Pour plus d'informations sur les curseurs, reportez-vous à la section<br />
"Présentation <strong>de</strong>s curseurs", page 15.<br />
Les appels requis pour préparer et exécuter les instructions ne font pas partie<br />
du SQL et ils diffèrent en fonction <strong>de</strong>s interfaces. Chacune <strong>de</strong>s interfaces <strong>de</strong><br />
<strong>programmation</strong> d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> offre une métho<strong>de</strong> permettant<br />
d'exploiter <strong>de</strong>s instructions préparées.<br />
Cette section donne un bref aperçu <strong>de</strong> l'utilisation <strong>de</strong>s instructions préparées.<br />
La procédure générale est i<strong>de</strong>ntique, mais les détails varient d'une interface à<br />
l'autre. Pour illustrer cela, nous allons comparer le mo<strong>de</strong> d'utilisation<br />
d'instructions préparées dans différentes interfaces.<br />
v Pour utiliser une instruction préparée (générique) :<br />
1 Préparez l'instruction.<br />
2 Définissez les paramètres <strong>de</strong> liaison, qui contiennent les valeurs dans<br />
l’instruction.<br />
3 Affectez <strong>de</strong>s valeurs aux paramètres <strong>de</strong> liaison.<br />
4 Exécutez l'instruction.<br />
5 Répétez les étapes 3 et 4 autant <strong>de</strong> fois que nécessaire.<br />
6 L'opération terminée, supprimez l'instruction. Cette étape est inutile dans<br />
JDBC, dans la mesure où les mécanismes <strong>de</strong> défragmentation <strong>de</strong> la<br />
mémoire <strong>de</strong> Java le font à votre place.<br />
v Pour utiliser une instruction préparée (Embed<strong>de</strong>d SQL) :<br />
1 Préparez l'instruction avec la comman<strong>de</strong> EXEC SQL PREPARE.<br />
2 Affectez <strong>de</strong>s valeurs aux paramètres dans l'instruction.<br />
3 Exécutez l'instruction avec la comman<strong>de</strong> EXE SQL EXECUTE.<br />
4 Libérez les ressources associées à l'instruction, en utilisant la comman<strong>de</strong><br />
EXEC SQL DROP.<br />
v Pour utiliser une instruction préparée (ODBC) :<br />
1 Préparez l'instruction via SQLPrepare.<br />
13
Préparation <strong>de</strong>s instructions<br />
14<br />
2 Effectuez la liaison <strong>de</strong>s paramètres <strong>de</strong> l'instruction avec<br />
SQLBindParameter.<br />
3 Exécutez l'instruction avec SQLExecute.<br />
4 Supprimez l'instruction avec SQLFreeStmt.<br />
$ Pour plus d'informations, reportez-vous à la section "Exécution <strong>de</strong>s<br />
instructions préparées", page 295 et à la documentation SDK ODBC.<br />
v Pour utiliser une instruction préparée (JDBC) :<br />
1 Préparez l'instruction avec la métho<strong>de</strong> prepareStatement <strong>de</strong> l'objet <strong>de</strong><br />
connexion. Vous obtenez un objet instruction préparée.<br />
2 Définissez les paramètres <strong>de</strong> l'instruction avec les métho<strong>de</strong>s setType<br />
adaptées <strong>de</strong> l'objet instruction préparée. Type est ici le type <strong>de</strong> données<br />
affecté.<br />
3 Définissez les paramètres <strong>de</strong> l'instruction avec la métho<strong>de</strong> appropriée <strong>de</strong><br />
l'objet instruction préparée. Pour les insertions, mises à jour et<br />
suppressions, il s'agit <strong>de</strong> la métho<strong>de</strong> executeUpdate.<br />
$ Pour plus d'informations sur les instructions préparées dans JDBC,<br />
reportez-vous à la section "Utilisation d'instructions préparées pour un<br />
accès optimisé", page 167.<br />
v Pour utiliser une instruction préparée (Open Client) :<br />
1 Préparez l'instruction via la fonction ct_dynamic, avec un paramètre <strong>de</strong><br />
type CS_PREPARE.<br />
2 Définissez les paramètres <strong>de</strong> l'instruction avec ct_param.<br />
3 Exécutez l'instruction via ct_dynamic avec un paramètre <strong>de</strong> type<br />
CS_EXECUTE.<br />
4 Libérez les ressources associées à l'instruction via ct_dynamic avec un<br />
paramètre <strong>de</strong> type CS_DEALLOC.<br />
$ Pour plus d'informations sur l'utilisation d'instructions préparées<br />
dans Open Client, reportez-vous à la section "SQL dans les applications<br />
Open Client", page 389.
Présentation <strong>de</strong>s curseurs<br />
Qu’est-ce qu’un curseur ?<br />
Positions du<br />
curseur<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Lorsque vous exécutez une requête dans une application, le jeu <strong>de</strong> résultats<br />
est constitué d'un certain nombre <strong>de</strong> lignes. En général, vous ne connaissez<br />
pas le nombre <strong>de</strong> lignes que l'application recevra avant d'exécuter la requête.<br />
Les curseurs constituent un moyen <strong>de</strong> gérer les jeux <strong>de</strong> résultats d'une<br />
requête dans les applications.<br />
Le mo<strong>de</strong> d'utilisation effective <strong>de</strong>s curseurs, <strong>de</strong> même que les types <strong>de</strong><br />
curseurs disponibles, dépen<strong>de</strong>nt <strong>de</strong> l'interface <strong>de</strong> <strong>programmation</strong>. JDBC 1.0<br />
n'offre qu'une gestion rudimentaire <strong>de</strong>s jeux <strong>de</strong> résultats, tandis qu'ODBC et<br />
Embed<strong>de</strong>d SQL proposent plusieurs types <strong>de</strong> curseur. Les curseurs Open<br />
Client se limitent au simple déplacement vers l'avant dans un jeu <strong>de</strong> résultats.<br />
Les curseurs vous permettent d'exécuter les tâches suivantes au sein <strong>de</strong><br />
n'importe quelle interface <strong>de</strong> <strong>programmation</strong> :<br />
♦ Naviguer dans les résultats d'une requête.<br />
♦ Effectuer <strong>de</strong>s insertions, <strong>de</strong>s mises à jour et <strong>de</strong>s suppressions <strong>de</strong> données<br />
sous-jacentes en tout point d'un jeu <strong>de</strong> résultats.<br />
D'autre part, certaines interfaces <strong>de</strong> <strong>programmation</strong> proposent <strong>de</strong>s fonctions<br />
spécifiques pour optimiser le renvoi <strong>de</strong>s jeux <strong>de</strong> résultats à l'application, <strong>de</strong><br />
sorte que vous pouvez améliorer sensiblement ses performances.<br />
$ Pour plus d'informations sur les types <strong>de</strong> curseurs disponibles dans les<br />
différentes interfaces <strong>de</strong> <strong>programmation</strong>, reportez-vous à la section<br />
"Disponibilité <strong>de</strong>s curseurs", page 25.<br />
Un curseur est un nom associé à un jeu <strong>de</strong> résultats issu d'une instruction<br />
SELECT ou d'un appel <strong>de</strong> procédure stockée.<br />
Le curseur est un <strong>de</strong>scripteur du jeu <strong>de</strong> résultats. Il détient à tout moment une<br />
position bien définie au sein du jeu <strong>de</strong> résultats. Un curseur permet<br />
d'examiner, voire <strong>de</strong> manipuler, les données ligne par ligne. Dans <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>, les curseurs permettent les déplacements vers l'avant et<br />
vers l'arrière dans les résultats d'une requête.<br />
Vous pouvez positionner les curseurs aux endroits suivants :<br />
♦ avant la première ligne du jeu <strong>de</strong> résultats ;<br />
♦ sur une ligne du jeu <strong>de</strong> résultats ;<br />
♦ après la <strong>de</strong>rnière ligne du jeu <strong>de</strong> résultats.<br />
15
Présentation <strong>de</strong>s curseurs<br />
16<br />
La position du curseur et le jeu <strong>de</strong> résultats sont tenus à jour sur le serveur <strong>de</strong><br />
base <strong>de</strong> données. Des lignes sont extraites par le client à <strong>de</strong>s fins d'affichage<br />
et <strong>de</strong> traitement, une par une ou plusieurs à la fois. Il est en effet inutile <strong>de</strong><br />
transmettre entièrement le jeu <strong>de</strong> résultats au client.<br />
Avantages liés à l'utilisation <strong>de</strong> curseurs<br />
Si l'utilisation <strong>de</strong> curseurs dans les applications <strong>de</strong> base <strong>de</strong> données est<br />
facultative, elle présente toutefois un certain nombre d'avantages. Ces<br />
avantages sont liés au fait que si vous n'utilisez pas <strong>de</strong> curseur, l'intégralité<br />
du jeu <strong>de</strong> résultats doit être transférée au client à <strong>de</strong>s fins <strong>de</strong> traitement et<br />
d'affichage.
Etapes d’utilisation d’un curseur<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
♦ Mémoire côté client Pour les résultats volumineux, le stockage d'un jeu<br />
<strong>de</strong> résultats complet sur le client peut se traduire par une augmentation<br />
<strong>de</strong>s besoins en mémoire.<br />
♦ Temps <strong>de</strong> réponse Les curseurs peuvent fournir les premières lignes<br />
avant la création complète du jeu <strong>de</strong> résultats. Si vous n'utilisez pas <strong>de</strong><br />
curseur, le jeu <strong>de</strong> résultats doit être entièrement transféré pour que<br />
l'application puisse en afficher les lignes.<br />
♦ Contrôle <strong>de</strong> la concurrence d'accès Si vous mettez <strong>de</strong>s données à jour<br />
sans utiliser <strong>de</strong> curseur dans votre application, vous <strong>de</strong>vez envoyer <strong>de</strong>s<br />
instructions SQL distinctes au serveur <strong>de</strong> base <strong>de</strong> données pour<br />
appliquer les modifications. Ceci peut donner lieu à <strong>de</strong>s problèmes <strong>de</strong><br />
concurrence d'accès si le jeu <strong>de</strong> résultats a changé <strong>de</strong>puis la requête du<br />
client. Ces problèmes peuvent à leur tour entraîner <strong>de</strong>s pertes <strong>de</strong> mise à<br />
jour.<br />
Les curseurs agissent comme <strong>de</strong>s pointeurs sur les données sous-jacentes<br />
et soumettent donc les modifications apportées à <strong>de</strong>s contraintes <strong>de</strong><br />
concurrence d'accès.<br />
Les étapes d'utilisation d'un curseur ne sont pas les mêmes selon que vous<br />
utilisez Embed<strong>de</strong>d SQL ou d'autres interfaces.<br />
v Pour utiliser un curseur (Embed<strong>de</strong>d SQL) :<br />
1 Préparez une instruction.<br />
En général, les curseurs utilisent un <strong>de</strong>scripteur d'instruction plutôt<br />
qu'une chaîne. Vous <strong>de</strong>vez préparer une instruction pour disposer d'un<br />
pointeur.<br />
$ Pour plus d'informations sur la préparation d'une instruction,<br />
reportez-vous à la section "Préparation <strong>de</strong>s instructions", page 12.<br />
2 Déclarez le curseur.<br />
Chaque curseur référence une instruction SELECT ou CALL donnée.<br />
Lorsque vous déclarez un curseur, vous définissez son nom et l'interface<br />
à laquelle il fait référence.<br />
$ Pour plus d'informations, reportez-vous à la section "Instruction<br />
DECLARE CURSOR [ESQL] [SP]", page 401 du document ASA<br />
Manuel <strong>de</strong> référence SQL.<br />
3 Ouvrez le curseur.<br />
17
Présentation <strong>de</strong>s curseurs<br />
18<br />
$ Pour plus d'informations, reportez-vous à la section "Instruction<br />
OPEN [ESQL] [SP]", page 508 du document ASA Manuel <strong>de</strong> référence<br />
SQL.<br />
Dans le cas d'une instruction CALL, l'ouverture du curseur entraîne<br />
l'exécution <strong>de</strong> la requête jusqu'au point où la première ligne est en passe<br />
d'être obtenue.<br />
4 Lisez les résultats.<br />
Une simple opération d'extraction déplace le curseur sur la ligne<br />
suivante du jeu <strong>de</strong> résultats ; toutefois, les fonctions d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> permettent <strong>de</strong>s mouvements plus complexes. Les fonctions <strong>de</strong><br />
lecture disponibles dépen<strong>de</strong>nt <strong>de</strong> la manière dont vous déclarez le<br />
curseur.<br />
$ Pour plus d'informations, reportez-vous aux sections "Instruction<br />
FETCH [ESQL] [SP]", page 446 du document ASA Manuel <strong>de</strong> référence<br />
SQL et "Lecture <strong>de</strong> données", page 211.<br />
5 Fermez le curseur.<br />
Lorsque vous ne l'utilisez plus, fermez le curseur. Cette opération lève<br />
les verrous posés sur les données sous-jacentes.<br />
$ Pour plus d'informations, reportez-vous à la section "Instruction<br />
CLOSE [ESQL] [SP]", page 276 du document ASA Manuel <strong>de</strong> référence<br />
SQL.<br />
6 Supprimez l’instruction.<br />
Pour libérer la mémoire associée au curseur et à l'instruction<br />
correspondante, vous <strong>de</strong>vez libérer l'instruction.<br />
$ Pour plus d'informations, reportez-vous à la section "Instruction<br />
DROP STATEMENT [ESQL]", page 427 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
v Pour utiliser un curseur (ODBC, JDBC ou Open Client) :<br />
1 Préparez et exécutez une instruction.<br />
Exécutez l'instruction comme vous le faites habituellement sous cette<br />
interface. Vous pouvez préparer l'instruction avant <strong>de</strong> l'exécuter ou<br />
l'exécuter directement.<br />
2 Vérifiez si l'instruction renvoie un jeu <strong>de</strong> résultats.<br />
Un curseur est ouvert par défaut lors <strong>de</strong> l'exécution d'une instruction qui<br />
crée un jeu <strong>de</strong> résultats. Lors <strong>de</strong> son ouverture, le curseur est positionné<br />
avant la première ligne du jeu <strong>de</strong> résultats.
Prélecture <strong>de</strong><br />
lignes<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
3 Lisez les résultats.<br />
Une simple opération <strong>de</strong> lecture déplace le curseur sur la ligne suivante<br />
du jeu <strong>de</strong> résultats ; toutefois, les fonctions <strong>de</strong> lecture d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> permettent <strong>de</strong>s mouvements plus complexes.<br />
4 Fermez le curseur.<br />
Lorsque vous ne l'utilisez plus, fermez le curseur afin <strong>de</strong> libérer les<br />
ressources associées.<br />
5 Libérez l'instruction.<br />
Si vous avez utilisé une instruction préparée, libérez-la pour récupérer<br />
<strong>de</strong> la mémoire.<br />
Parfois, la bibliothèque d'interface procè<strong>de</strong> à une optimisation <strong>de</strong>s<br />
performances (prélecture <strong>de</strong>s résultats, par exemple) <strong>de</strong> manière transparente.<br />
Il est donc possible que les étapes dans l'application cliente ne correspon<strong>de</strong>nt<br />
pas exactement aux opérations logicielles.<br />
19
Utilisation <strong>de</strong>s curseurs<br />
Utilisation <strong>de</strong>s curseurs<br />
Positionnement du curseur<br />
20<br />
Cette section traite <strong>de</strong> l'exécution <strong>de</strong> différentes opérations utilisant <strong>de</strong>s<br />
curseurs.<br />
Lors <strong>de</strong> son ouverture, un curseur est placé avant la première ligne. Vous<br />
pouvez lui donner une position absolue par rapport au début ou à la fin <strong>de</strong>s<br />
résultats <strong>de</strong> la requête, ou une position relative à sa position courante. La<br />
façon dont vous pouvez modifier la position du curseur et les opérations<br />
possibles dépen<strong>de</strong>nt <strong>de</strong> l'interface <strong>de</strong> <strong>programmation</strong>.<br />
Le nombre <strong>de</strong> positions <strong>de</strong> ligne que vous pouvez extraire dans un curseur est<br />
fonction <strong>de</strong> la taille d'un entier. Vous pouvez extraire <strong>de</strong>s lignes numérotées<br />
jusqu'à 2 147 483 646, ce qui correspond à la valeur que peut contenir un<br />
entier, moins un. Lorsque vous utilisez <strong>de</strong>s nombres négatifs (comptage <strong>de</strong>s<br />
lignes à partir <strong>de</strong> la fin), vous pouvez extraire un nombre <strong>de</strong> lignes égal à la<br />
plus gran<strong>de</strong> valeur négative que peut contenir un entier, plus un.<br />
Vous pouvez utiliser <strong>de</strong>s opérations spécifiques <strong>de</strong> mise à jour (UPDATE) et<br />
<strong>de</strong> suppression (DELETE) positionnées pour mettre à jour ou supprimer une<br />
ligne à la position courante du curseur. Si le curseur est positionné avant la<br />
première ligne ou après la <strong>de</strong>rnière ligne, une erreur Aucune ligne <strong>de</strong> curseur<br />
n'est actuellement sélectionnée est renvoyé.
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Problèmes liés au positionnement du curseur<br />
Les insertions et certaines mises à jour apportées aux curseurs à sensibilité<br />
indéfinie peuvent engendrer <strong>de</strong>s problèmes <strong>de</strong> positionnement. <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong> ne place les lignes insérées à une position prévisible<br />
d'un curseur que si l'instruction SELECT comporte une clause<br />
ORDER BY. Dans certains cas, la ligne insérée n'apparaît pas avant que le<br />
curseur soit fermé puis rouvert.<br />
Dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, ce problème survient lorsqu'une table<br />
<strong>de</strong> travail a dû être créée pour ouvrir le curseur (pour une <strong>de</strong>scription<br />
détaillée, reportez-vous à la section "Utilisation <strong>de</strong> tables <strong>de</strong> travail dans le<br />
traitement <strong>de</strong>s requêtes", page 170 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong><br />
l’utilisateur SQL).<br />
L'instruction UPDATE peut provoquer le déplacement d'une ligne dans le<br />
curseur. Cela se produit si le curseur inclut une clause ORDER BY qui<br />
utilise un in<strong>de</strong>x existant (aucune table <strong>de</strong> travail n'est créée). Les curseurs<br />
STATIC SCROLL réduisent ces problèmes, mais consomment plus <strong>de</strong><br />
mémoire et <strong>de</strong> traitement.<br />
Configuration <strong>de</strong>s curseurs à l'ouverture<br />
A l'ouverture d'un curseur, vous pouvez configurer les éléments suivants :<br />
♦ Niveau d’isolement Vous pouvez définir explicitement le niveau<br />
d'isolement <strong>de</strong>s opérations sur un curseur, <strong>de</strong> sorte qu'il soit différent du<br />
niveau d'isolement défini pour la transaction. Pour ce faire, définissez<br />
l'option ISOLATION_LEVEL.<br />
$ Pour plus d'informations, reportez-vous à la section "Option<br />
ISOLATION_LEVEL", page 623 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
♦ Maintien Par défaut, les curseurs dans Embed<strong>de</strong>d SQL sont fermés à la<br />
fin d'une transaction. Ouvrir un curseur avec la clause WITH HOLD<br />
permet <strong>de</strong> le maintenir ouvert jusqu'à la fin <strong>de</strong> la connexion ou jusqu'à sa<br />
fermeture explicite. Par défaut, ODBC, JDBC et Open Client laissent les<br />
curseurs ouverts à la fin <strong>de</strong>s transactions.<br />
Extraction <strong>de</strong> lignes via un curseur<br />
Le plus simple, pour traiter le jeu <strong>de</strong> résultats d'une requête via un curseur,<br />
est <strong>de</strong> parcourir toutes les lignes <strong>de</strong>s résultats jusqu'à la fin.<br />
21
Utilisation <strong>de</strong>s curseurs<br />
Extraction multiligne<br />
22<br />
v Pour parcourir entièrement les lignes d'un jeu <strong>de</strong> résultats :<br />
1 Déclarez et ouvrez le curseur (Embed<strong>de</strong>d SQL), ou exécutez une<br />
instruction qui renvoie un jeu <strong>de</strong> résultats (ODBC, JDBC ou Open<br />
Client).<br />
2 Lisez les lignes jusqu'à obtenir un message La ligne est introuvable.<br />
3 Fermez le curseur.<br />
Le mo<strong>de</strong> d'exécution <strong>de</strong> l'étape 2 dépend <strong>de</strong> l'interface utilisée. Par exemple :<br />
♦ ODBC SQLFetch, SQLExten<strong>de</strong>dFetch ou SQLFetchScroll déplace le<br />
curseur sur la ligne suivante et renvoie les données.<br />
$ Pour plus d'informations sur les curseurs dans ODBC, reportezvous<br />
à la section "Jeux <strong>de</strong> résultats", page 297.<br />
♦ Embed<strong>de</strong>d SQL L'instruction FETCH exécute la même opération.<br />
$ Pour plus d'informations sur l'utilisation <strong>de</strong>s curseurs dans<br />
Embed<strong>de</strong>d SQL, reportez-vous à la section "Utilisation <strong>de</strong> curseurs dans<br />
Embed<strong>de</strong>d SQL", page 212.<br />
♦ JDBC La métho<strong>de</strong> next <strong>de</strong> l'objet ResultSet déplace le curseur et<br />
renvoie les données.<br />
$ Pour plus d'informations sur l'utilisation <strong>de</strong> l'objet ResultSet dans<br />
JDBC, reportez-vous à la section "Requêtes avec JDBC", page 166.<br />
♦ Open Client La fonction ct_fetch déplace le curseur sur la ligne<br />
suivante et renvoie les données.<br />
$ Pour plus d'informations sur les curseurs dans les applications<br />
Open Client, reportez-vous à la section "Curseurs", page 390.<br />
Cette section traite <strong>de</strong> l'extraction simultanée <strong>de</strong> plusieurs lignes, technique<br />
susceptible d'améliorer les performances.<br />
Ne confon<strong>de</strong>z pas extraction multiligne et préextraction <strong>de</strong> lignes (décrite<br />
plus loin). L'extraction multiligne est réalisée par l'application, tandis que la<br />
préextraction est transparente pour l'application ; elle améliore également les<br />
performances.
Extraction<br />
multiligne<br />
Utilisation <strong>de</strong><br />
l’extraction<br />
multiligne<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Certaines interfaces permettent d'extraire simultanément plusieurs lignes<br />
dans les champs suivants d'un tableau. D'une façon générale, moins vous<br />
exécutez d'extractions distinctes, moindre est le nombre <strong>de</strong> requêtes<br />
auxquelles doit répondre le serveur et meilleures sont les performances. Une<br />
instruction FETCH modifiée qui extrait plusieurs lignes est également<br />
appelée extraction étendue. Les curseurs utilisant les extractions multiligne<br />
sont parfois appelés curseurs bloc ou curseurs "fat".<br />
♦ Dans ODBC, vous pouvez fixer le nombre <strong>de</strong> lignes renvoyées par<br />
chaque appel à SQLFetchScroll ou SQLExten<strong>de</strong>dFetch en définissant<br />
l'attribut SQL_ROWSET_SIZE.<br />
♦ Dans Embed<strong>de</strong>d SQL, l'instruction FETCH permet <strong>de</strong> contrôler le<br />
nombre <strong>de</strong> lignes extraites simultanément, via la clause ARRAY.<br />
♦ Open Client et JDBC ne supportent pas les extractions multiligne. Ils<br />
utilisent la préextraction.<br />
Extraction par <strong>de</strong>s curseurs avec défilement<br />
ODBC et Embed<strong>de</strong>d SQL proposent <strong>de</strong>s métho<strong>de</strong>s permettant d'exploiter les<br />
curseurs avec défilement et défilement dynamique. Ces métho<strong>de</strong>s permettent<br />
d'avancer <strong>de</strong> plusieurs lignes en une fois ou <strong>de</strong> remonter dans le jeu <strong>de</strong><br />
résultats.<br />
Les interfaces JDBC et Open Client ne supportent pas les curseurs avec<br />
défilement.<br />
La prélecture n'est pas applicable aux opérations <strong>de</strong> défilement. Par exemple,<br />
l'extraction d'une ligne située avant la ligne courante ne permet pas la<br />
préextraction <strong>de</strong> plusieurs lignes en amont.<br />
Modification <strong>de</strong> lignes via un curseur<br />
Les curseurs ne servent pas seulement à lire les résultats d'une requête. Vous<br />
pouvez également modifier les données d'une base pendant le traitement d'un<br />
curseur. Ces opérations sont généralement appelées opérations <strong>de</strong> mise à jour<br />
(UPDATE) et <strong>de</strong> suppression (DELETE) positionnées, ou opérations PUT<br />
s'il s'agit d'une insertion (INSERT).<br />
Les mises à jour et les suppressions positionnées ne sont pas admises dans<br />
tous les jeux <strong>de</strong> résultats <strong>de</strong> requêtes. Si vous exécutez une requête sur une<br />
vue non modifiable, aucune modification ne peut être apportée à la table<br />
sous-jacente. De plus, si la requête implique une jointure, vous <strong>de</strong>vez<br />
spécifier la table dans laquelle effectuer la suppression, ou les colonnes à<br />
mettre à jour lorsque vous exécutez l'opération.<br />
23
Utilisation <strong>de</strong>s curseurs<br />
Table dans<br />
laquelle sont<br />
supprimées les<br />
lignes<br />
24<br />
Les insertions via un curseur ne peuvent être exécutées que si les colonnes<br />
non insérées admettent la valeur NULL ou sont dotées d'une valeur par<br />
défaut.<br />
ODBC, Embed<strong>de</strong>d SQL et Open Client autorisent la modification <strong>de</strong>s<br />
données via un curseur, mais pas JDBC 1.1. Avec Open Client, vous pouvez<br />
supprimer et mettre à jour <strong>de</strong>s lignes, mais vous ne pouvez en insérer que<br />
dans une requête portant sur une seule table.<br />
Si vous tentez une suppression positionnée via un curseur, la table dans<br />
laquelle les lignes sont supprimées est déterminée comme suit :<br />
1 Si aucune clause FROM n'est incluse, le curseur ne doit pointer que sur<br />
une seule table.<br />
2 Si le curseur concerne une requête jointe (ce qui inclut les vues<br />
contenant une jointure), la clause FROM doit être employée. Seule la<br />
ligne courante <strong>de</strong> la table spécifiée est supprimée. Les autres tables<br />
participant à la jointure <strong>de</strong>meurent inchangées.<br />
3 Si une clause FROM est incluse mais qu'aucun propriétaire <strong>de</strong> table n'est<br />
spécifié, la valeur spécif_table est d'abord comparée aux alias existants :<br />
$ Pour plus d'information, reportez-vous à la section "Clause<br />
FROM", page 455 du document ASA Manuel <strong>de</strong> référence SQL.<br />
4 S'il existe un alias, la valeur spécif_table est i<strong>de</strong>ntifiée avec cet alias.<br />
5 Si aucun alias n'a été défini, la valeur spécif_table doit i<strong>de</strong>ntifier sans<br />
ambiguïté le nom d'une table appartenant au curseur.<br />
6 Si une clause FROM est incluse et qu'un nom <strong>de</strong> propriétaire est<br />
spécifié, la valeur spécif_table doit i<strong>de</strong>ntifier sans ambiguïté le nom<br />
d'une table appartenant au curseur.<br />
7 Vous pouvez utiliser l'instruction DELETE positionnée sur un curseur<br />
ouvert sur une vue, à condition que celle-ci soit modifiable.<br />
Annulation <strong>de</strong>s opérations sur un curseur<br />
Vous pouvez annuler une requête via une fonction <strong>de</strong> l'interface. Dans<br />
Interactive SQL, vous pouvez annuler une requête en cliquant sur le bouton<br />
Interrompt l'instruction SQL <strong>de</strong> la barre d'outils (ou en choisissant Arrêter<br />
dans le menu SQL).<br />
Si vous annulez une requête qui exécute une opération avec le curseur, la<br />
position du curseur est indéterminée. Une fois la requête annulée, vous <strong>de</strong>vez<br />
localiser le curseur à l'ai<strong>de</strong> <strong>de</strong> sa position absolue ou le fermer, juste après<br />
l'annulation.
Choix d’un type <strong>de</strong> curseur<br />
Disponibilité <strong>de</strong>s curseurs<br />
Propriétés <strong>de</strong> curseur<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Cette section décrit les mappages entre les curseurs <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> et les options proposées par les interfaces <strong>de</strong> <strong>programmation</strong><br />
supportées par <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
$ Pour plus d'informations sur les curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>,<br />
reportez-vous à la section "Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>", page 29.<br />
Toutes les interfaces ne supportent pas tous les types <strong>de</strong> curseur.<br />
♦ ODBC et OLE DB (ADO) supportent tous les types <strong>de</strong> curseur.<br />
$ Pour plus d'informations, reportez-vous à la section "Jeux <strong>de</strong><br />
résultats", page 297.<br />
♦ Embed<strong>de</strong>d SQL supporte tous les types <strong>de</strong> curseur.<br />
♦ Pour JDBC:<br />
♦ jConnect 4.x ne fournit que <strong>de</strong>s curseurs à sensibilité indéfinie.<br />
♦ jConnect 5.x supporte tous les types <strong>de</strong> curseurs, avec toutefois une<br />
baisse <strong>de</strong> performances pour les curseurs avec défilement.<br />
♦ La passerelle JDBC-ODBC supporte tous les types <strong>de</strong> curseurs.<br />
♦ <strong>Sybase</strong> Open Client supporte uniquement les curseurs à sensibilité<br />
indéfinie. Par ailleurs, l'utilisation <strong>de</strong> curseurs non uniques et<br />
modifiables a <strong>de</strong>s effets très néfastes sur les performances.<br />
C'est à l'interface <strong>de</strong> <strong>programmation</strong> que vous <strong>de</strong>man<strong>de</strong>z un type <strong>de</strong> curseur,<br />
que ce soit <strong>de</strong> façon explicite ou implicite. Les types <strong>de</strong> curseur proposés<br />
varient selon les bibliothèques d'interface. Par exemple, JDBC et ODBC<br />
offrent <strong>de</strong>s types <strong>de</strong> curseur différents.<br />
Chaque type <strong>de</strong> curseur présente plusieurs caractéristiques :<br />
♦ Unicité Lorsqu'un curseur est déclaré unique, la requête est contrainte <strong>de</strong><br />
renvoyer toutes les colonnes nécessaires pour i<strong>de</strong>ntifier chaque ligne <strong>de</strong><br />
façon unique. Cela signifie souvent le renvoi <strong>de</strong> toutes les colonnes <strong>de</strong> la<br />
clé primaire. Toute colonne requise mais non spécifiée est ajoutée dans<br />
le jeu <strong>de</strong> résultats. Le type <strong>de</strong> curseur par défaut est non-unique.<br />
25
Choix d’un type <strong>de</strong> curseur<br />
26<br />
♦ Possibilité <strong>de</strong> mise à jour Un curseur déclaré comme étant en lecture<br />
seule ne peut pas être utilisé dans une opération <strong>de</strong> mise à jour ou <strong>de</strong><br />
suppression positionnée. Le type <strong>de</strong> curseur par défaut est modifiable.<br />
♦ Défilement Vous pouvez déclarer <strong>de</strong>s curseurs qui auront <strong>de</strong>s<br />
comportements différents lors <strong>de</strong> leur déplacement dans le jeu <strong>de</strong><br />
résultats. Certains curseurs ne peuvent extraire que la ligne courante ou<br />
la suivante. D'autres peuvent se déplacer vers l'avant ou vers l'arrière<br />
dans le jeu <strong>de</strong> résultats.<br />
♦ Sensibilité Les modifications apportées à la base <strong>de</strong> données peuvent<br />
être visibles ou non via un curseur.<br />
Ces caractéristiques peuvent avoir <strong>de</strong>s effets secondaires considérables sur<br />
les performances et l'utilisation <strong>de</strong> mémoire du serveur <strong>de</strong> base <strong>de</strong> données.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> propose <strong>de</strong>s curseurs offrant différentes<br />
combinaisons <strong>de</strong> ces caractéristiques. Lorsque vous <strong>de</strong>man<strong>de</strong>z un curseur<br />
d'un type donné, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> tente <strong>de</strong> répondre au mieux aux<br />
critères spécifiés. Les sections suivantes expliquent comment les curseurs<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> correspon<strong>de</strong>nt aux types <strong>de</strong> curseur spécifiés<br />
dans les interfaces <strong>de</strong> <strong>programmation</strong>.<br />
Dans certains cas, il est impossible <strong>de</strong> réunir toutes les caractéristiques<br />
souhaitées. Par exemple, dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, les curseurs<br />
insensibles doivent être en lecture seule, pour les raisons décrites ci-après. Si<br />
votre application <strong>de</strong>man<strong>de</strong> un curseur insensible modifiable, un autre type <strong>de</strong><br />
curseur (tenant compte <strong>de</strong>s valeurs) est fourni à la place.<br />
Deman<strong>de</strong> <strong>de</strong> curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
ODBC et OLE DB<br />
Lorsque vous <strong>de</strong>man<strong>de</strong>z un type <strong>de</strong> curseur <strong>de</strong>puis votre application cliente,<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> en propose un. Les curseurs <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> sont définis en fonction <strong>de</strong> la sensibilité du jeu <strong>de</strong> résultats aux<br />
modifications apportées aux données sous-jacentes, et non du type spécifié<br />
dans l'interface <strong>de</strong> <strong>programmation</strong>. Selon le type <strong>de</strong>mandé, <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> propose un curseur dont le comportement correspond à ce type.<br />
La sensibilité <strong>de</strong>s curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est établie en fonction<br />
<strong>de</strong> la <strong>de</strong>man<strong>de</strong> <strong>de</strong> type <strong>de</strong> curseur <strong>de</strong> la part du client.<br />
Le tableau suivant illustre la sensibilité du curseur définie en fonction <strong>de</strong>s<br />
différents types <strong>de</strong> curseur avec défilement ODBC.
Exceptions<br />
Embed<strong>de</strong>d SQL<br />
Exceptions<br />
Type <strong>de</strong> curseur avec<br />
défilement ODBC<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
STATIC Insensible<br />
Curseur <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
KEYSET Tenant compte <strong>de</strong>s valeurs<br />
DYNAMIC Sensible<br />
MIXED Tenant compte <strong>de</strong>s valeurs<br />
$ Pour plus d’informations sur les curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> et<br />
leur comportement, reportez-vous à la section "Curseurs <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>", page 29. Pour plus d'informations sur la <strong>de</strong>man<strong>de</strong> d'un type <strong>de</strong><br />
curseur dans ODBC, reportez-vous à la section "Choix <strong>de</strong>s caractéristiques<br />
d'un curseur", page 297.<br />
Si un curseur STATIC est <strong>de</strong>mandé comme modifiable, un curseur tenant<br />
compte <strong>de</strong>s valeurs est fourni à la place et un avertissement est émis.<br />
Si un curseur DYNAMIC ou MIXED est <strong>de</strong>mandé et si la requête ne peut<br />
pas être exécutée sans utiliser <strong>de</strong> tables <strong>de</strong> travail, un avertissement est émis<br />
et un curseur à sensibilité indéfinie est fourni à la place.<br />
Pour <strong>de</strong>man<strong>de</strong>r un curseur <strong>de</strong>puis une application Embed<strong>de</strong>d SQL, vous<br />
indiquez le type <strong>de</strong> curseur dans l'instruction DECLARE. Le tableau suivant<br />
illustre la sensibilité <strong>de</strong>s curseurs définie en fonction <strong>de</strong>s différentes<br />
<strong>de</strong>man<strong>de</strong>s possibles.<br />
Type <strong>de</strong> curseur Curseur <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
NO SCROLL A sensibilité indéfinie<br />
DYNAMIC SCROLL A sensibilité indéfinie<br />
SCROLL Tenant compte <strong>de</strong>s valeurs<br />
INSENSITIVE Insensible<br />
SENSITIVE Sensible<br />
Si un curseur DYNAMIC SCROLL ou NO SCROLL est <strong>de</strong>mandé comme<br />
modifiable, c'est un curseur sensible ou tenant compte <strong>de</strong>s valeurs qui est<br />
proposé. Il est impossible <strong>de</strong> prévoir lequel <strong>de</strong>s <strong>de</strong>ux curseurs sera fourni.<br />
Cette incertitu<strong>de</strong> correspond à la définition d'une sensibilité indéfinie.<br />
Si un curseur INSENSITIVE est <strong>de</strong>mandé comme modifiable, c'est un<br />
curseur tenant compte <strong>de</strong>s valeurs qui est fourni.<br />
27
Choix d’un type <strong>de</strong> curseur<br />
JDBC<br />
Open Client<br />
Signets et curseurs<br />
Curseurs bloc<br />
28<br />
Si un curseur DYNAMIC SCROLL est <strong>de</strong>mandé, si l'option <strong>de</strong> base <strong>de</strong><br />
données PREFETCH est définie à OFF et si le plan d'exécution <strong>de</strong> la requête<br />
n'implique aucune table <strong>de</strong> travail, il est possible qu'un curseur sensible soit<br />
fourni. Là encore, cette incertitu<strong>de</strong> correspond à la définition d'une sensibilité<br />
indéfinie.<br />
Un seul type <strong>de</strong> curseur est disponible pour les applications JDBC. Il s'agit<br />
d'un curseur à sensibilité indéfinie. Dans JDBC, vous exécutez une<br />
instruction ExecuteQuery pour ouvrir un curseur.<br />
Un seul type <strong>de</strong> curseur est disponible pour les applications Open Client. Il<br />
s'agit d'un curseur à sensibilité indéfinie.<br />
ODBC fournit <strong>de</strong>s signets, qui sont <strong>de</strong>s valeurs utilisées pour i<strong>de</strong>ntifier <strong>de</strong>s<br />
lignes dans un curseur. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> accepte <strong>de</strong>s signets pour<br />
tous les types <strong>de</strong> curseur à l'exception <strong>de</strong>s curseurs dynamiques.<br />
ODBC fournit un type <strong>de</strong> curseur appelé curseur bloc. Avec un curseur bloc,<br />
vous pouvez utiliser SQLFetchScroll ou SQLExten<strong>de</strong>dFetch pour lire un<br />
bloc <strong>de</strong> lignes au lieu d'une seule ligne. Les curseurs bloc se comportent<br />
comme <strong>de</strong>s extractions SQL ARRAY dans Embed<strong>de</strong>d SQL.
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Modification <strong>de</strong><br />
l’appartenance, <strong>de</strong><br />
l’ordre et <strong>de</strong>s<br />
valeurs<br />
Une fois ouvert, un curseur est associé à un jeu <strong>de</strong> résultats. Il reste ouvert<br />
ainsi pendant un certain temps. Pendant cette durée, il est possible que le jeu<br />
<strong>de</strong> résultats associé au curseur soit modifié, soit via le curseur lui-même, soit<br />
par d'autres transactions en fonction du niveau d'isolement requis. Certains<br />
curseurs permettent d'afficher les modifications apportées aux données sousjacentes,<br />
tandis que d'autres n'en font pas état. Cette différence <strong>de</strong><br />
comportement par rapport aux modifications apportées aux données sousjacentes<br />
est appelée sensibilité du curseur.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> propose <strong>de</strong>s curseurs offrant différentes<br />
caractéristiques <strong>de</strong> sensibilité. Cette section définit le concept <strong>de</strong> sensibilité<br />
et décrit les caractéristiques <strong>de</strong>s curseurs dans ce domaine.<br />
Vous <strong>de</strong>vez au préalable avoir lu la section "Qu'est-ce qu'un curseur ?",<br />
page 15<br />
Les modifications apportées aux données sous-jacentes peuvent avoir<br />
plusieurs répercussions sur le jeu <strong>de</strong> résultats d'un curseur :<br />
♦ Appartenance Lignes du jeu <strong>de</strong> résultats, i<strong>de</strong>ntifiées par leur valeur <strong>de</strong><br />
clé primaire.<br />
♦ Ordre Ordre <strong>de</strong>s lignes dans le jeu <strong>de</strong> résultats.<br />
♦ Valeur Valeur <strong>de</strong>s lignes du jeu <strong>de</strong> résultats.<br />
Prenons l'exemple d'une table simple contenant <strong>de</strong>s informations sur les<br />
employés (emp_id étant la colonne <strong>de</strong> clé primaire) :<br />
emp_id emp_lname<br />
1 Whitney<br />
2 Cobb<br />
3 Chin<br />
Un curseur sur la requête suivante renvoie tous les résultats <strong>de</strong> la table par<br />
ordre <strong>de</strong> clé primaire :<br />
SELECT emp_id, emp_lname<br />
FROM employee<br />
ORDER BY emp_id<br />
L'appartenance du jeu <strong>de</strong> résultats pourrait être modifiée en ajoutant ou en<br />
supprimant une ligne. Les valeurs pourraient être modifiées en changeant un<br />
<strong>de</strong>s noms figurant dans la table. Quant à l'ordre, il pourrait lui aussi être<br />
modifié en changeant la valeur <strong>de</strong> clé primaire d'un <strong>de</strong>s employés.<br />
29
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Modifications<br />
visibles et<br />
invisibles<br />
30<br />
Selon le niveau d’isolement requis, il est possible <strong>de</strong> modifier l’appartenance,<br />
l'ordre et les valeurs du jeu <strong>de</strong> résultats d'un curseur après l'ouverture <strong>de</strong><br />
celui-ci. Le type <strong>de</strong> curseur utilisé détermine si le jeu <strong>de</strong> résultats visible par<br />
l'application peut changer ou non pour refléter ces modifications.<br />
Les modifications apportées aux données sous-jacentes peuvent être visibles<br />
ou invisibles par le biais du curseur. Une modification visible est un<br />
changement reporté dans le jeu <strong>de</strong> résultats du curseur. Les modifications <strong>de</strong>s<br />
données sous-jacentes non répercutées dans le jeu <strong>de</strong> résultats du curseur<br />
sont invisibles.<br />
Généralités sur la sensibilité <strong>de</strong>s curseurs<br />
Les curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> sont classés selon leur sensibilité<br />
aux modifications apportées aux données sous-jacentes. La sensibilité <strong>de</strong>s<br />
curseurs est en particulier définie en termes <strong>de</strong> visibilité <strong>de</strong>s modifications.<br />
♦ Curseurs insensibles Le jeu <strong>de</strong> résultats est fixé lors <strong>de</strong> l'ouverture du<br />
curseur. Les modifications apportées aux données sous-jacentes ne sont<br />
pas visibles.<br />
$ Pour plus d'informations, reportez-vous à la section "Curseurs<br />
insensibles", page 35.<br />
♦ Curseurs sensibles Le jeu <strong>de</strong> résultats peut être modifié après<br />
l'ouverture du curseur. Les modifications apportées aux données sousjacentes<br />
sont visibles.<br />
$ Pour plus d'informations, reportez-vous à la section "Curseurs<br />
sensibles", page 36.<br />
♦ Curseurs à sensibilité indéfinie Les modifications peuvent être<br />
répercutées sur l'appartenance, l'ordre ou les valeurs du jeu <strong>de</strong> résultats<br />
du curseur, ou ne pas être prises en compte du tout.<br />
$ Pour plus d'informations, reportez-vous à la section "Curseurs à<br />
sensibilité indéfinie", page 38.<br />
♦ Curseurs tenant compte <strong>de</strong>s valeurs Les modifications apportées<br />
à l'ordre ou aux valeurs <strong>de</strong>s données sous-jacentes sont répercutées.<br />
L'appartenance du jeu <strong>de</strong> résultats est fixé lors <strong>de</strong> l'ouverture du curseur.<br />
$ Pour plus d'informations, reportez-vous à la section "Curseurs<br />
tenant compte <strong>de</strong>s valeurs", page 39.<br />
Les différentes exigences en matière <strong>de</strong> curseurs entraînent <strong>de</strong>s contraintes<br />
sur l'exécution, donc les performances. Pour plus d'informations, reportezvous<br />
à la section "Sensibilité du curseur et performances", page 42.
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Exemple <strong>de</strong> sensibilité du curseur : suppression d'une ligne<br />
Cet exemple utilise une requête simple pour illustrer comment différents<br />
curseurs réagissent à la suppression d'une ligne du jeu <strong>de</strong> résultats.<br />
La succession <strong>de</strong>s événements est la suivante :<br />
1 Une application ouvre un curseur sur la requête suivante, qui concerne la<br />
base <strong>de</strong> données exemple :<br />
SELECT emp_id, emp_lname<br />
FROM employee<br />
ORDER BY emp_id<br />
emp_id emp_lname<br />
102 Whitney<br />
105 Cobb<br />
160 Breault<br />
… …<br />
2 L'application extrait la première ligne (102) au moyen du curseur.<br />
3 L'application extrait la ligne suivante (105) au moyen du curseur.<br />
4 Une autre transaction supprime l'employé 102 (Whitney) et vali<strong>de</strong> la<br />
modification.<br />
Dans ce cas, les résultats <strong>de</strong>s actions du curseur varient selon sa sensibilité :<br />
♦ Curseur insensible L'instruction DELETE n'est répercutée ni sur<br />
l'appartenance, si sur les valeurs du jeu <strong>de</strong> résultats associé au curseur.<br />
Action Résultat<br />
Extraction <strong>de</strong> la ligne<br />
précé<strong>de</strong>nte<br />
Extraction <strong>de</strong> la<br />
première ligne<br />
(extraction absolue)<br />
Extraction <strong>de</strong> la<br />
<strong>de</strong>uxième ligne<br />
(extraction absolue)<br />
Renvoie la copie originale <strong>de</strong> la ligne (102).<br />
Renvoie la copie originale <strong>de</strong> la ligne (102).<br />
Renvoie la ligne inchangée (105).<br />
♦ Curseur sensible L'appartenance du jeu <strong>de</strong> résultats a changé, <strong>de</strong> sorte<br />
que la ligne 105 est désormais la première du jeu <strong>de</strong> résultats.<br />
31
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
32<br />
Action Résultat<br />
Extraction <strong>de</strong> la ligne<br />
précé<strong>de</strong>nte<br />
Extraction <strong>de</strong> la<br />
première ligne<br />
(extraction absolue)<br />
Extraction <strong>de</strong> la<br />
<strong>de</strong>uxième ligne<br />
(extraction absolue)<br />
Renvoie une erreur La ligne est introuvable. Il<br />
n'y a pas <strong>de</strong> ligne précé<strong>de</strong>nte.<br />
Renvoie la ligne 105.<br />
Renvoie la ligne 160.<br />
♦ Curseur tenant compte <strong>de</strong>s valeurs L'appartenance du jeu <strong>de</strong> résultats<br />
étant fixe, la ligne 105 est toujours la <strong>de</strong>uxième du jeu <strong>de</strong> résultats.<br />
L'instruction DELETE est répercutée sur les valeurs du curseur et crée<br />
un "vi<strong>de</strong>" dans le jeu <strong>de</strong> résultats.<br />
Action Résultat<br />
Extraction <strong>de</strong> la ligne<br />
précé<strong>de</strong>nte<br />
Extraction <strong>de</strong> la<br />
première ligne<br />
(extraction absolue)<br />
Extraction <strong>de</strong> la<br />
<strong>de</strong>uxième ligne<br />
(extraction absolue)<br />
Renvoie le message Aucune ligne <strong>de</strong> curseur<br />
n'est actuellement sélectionnée. Il existe<br />
désormais un vi<strong>de</strong> dans le curseur à la place <strong>de</strong> la<br />
première ligne.<br />
Renvoie le message Aucune ligne <strong>de</strong> curseur<br />
n'est actuellement sélectionnée. Il existe<br />
désormais un vi<strong>de</strong> dans le curseur à la place <strong>de</strong> la<br />
première ligne.<br />
Renvoie la ligne 105.<br />
♦ Curseur à sensibilité indéfinie L’effet <strong>de</strong>s modifications sur<br />
l'appartenance et les valeurs du jeu <strong>de</strong> résultats est indéterminé. La<br />
réponse à une extraction <strong>de</strong> la ligne précé<strong>de</strong>nte, <strong>de</strong> la première ligne ou<br />
<strong>de</strong> la <strong>de</strong>uxième dépend <strong>de</strong> la métho<strong>de</strong> d'optimisation <strong>de</strong> la requête, selon<br />
que cette métho<strong>de</strong> implique la formation d'une table <strong>de</strong> travail et que la<br />
ligne extraite a été préextraite à partir du client.<br />
Pour la plupart <strong>de</strong>s applications, la sensibilité du curseur est sans<br />
importance, d'où l'avantage <strong>de</strong>s curseurs à sensibilité indéfinie. Ainsi, si<br />
vous utilisez un curseur en lecture seule à défilement avant uniquement,<br />
aucune modification sous-jacente n'est visible. De même, si vous utilisez<br />
un niveau d'isolement élevé, les modifications sous-jacentes sont<br />
interdites.
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Exemple <strong>de</strong> sensibilité du curseur : mise à jour d'une ligne<br />
Cet exemple utilise une requête simple pour illustrer comment différents<br />
types <strong>de</strong> curseur réagissent à la mise à jour d'une ligne du jeu <strong>de</strong> résultats<br />
entraînant une modification <strong>de</strong> l'ordre <strong>de</strong>s résultats.<br />
La succession <strong>de</strong>s événements est la suivante :<br />
1 Une application ouvre un curseur sur la requête suivante, qui concerne la<br />
base <strong>de</strong> données exemple.<br />
SELECT emp_id, emp_lname<br />
FROM employee<br />
emp_id emp_lname<br />
102 Whitney<br />
105 Cobb<br />
160 Breault<br />
… …<br />
2 L'application extrait la première ligne (102) au moyen du curseur.<br />
3 L'application extrait la ligne suivante (105) au moyen du curseur.<br />
4 Une autre transaction remplace l'ID <strong>de</strong> l'employé 102 (Whitney) par 165<br />
et vali<strong>de</strong> la modification.<br />
Dans ce cas, les résultats <strong>de</strong>s actions du curseur varient selon sa sensibilité :<br />
♦ Curseur insensible L'instruction UPDATE n'est répercutée ni sur<br />
l'appartenance, si sur les valeurs du jeu <strong>de</strong> résultats associé au curseur.<br />
Action Résultat<br />
Extraction <strong>de</strong> la ligne<br />
précé<strong>de</strong>nte<br />
Extraction <strong>de</strong> la<br />
première ligne<br />
(extraction absolue)<br />
Extraction <strong>de</strong> la<br />
<strong>de</strong>uxième ligne<br />
(extraction absolue)<br />
Renvoie la copie originale <strong>de</strong> la ligne (102).<br />
Renvoie la copie originale <strong>de</strong> la ligne (102).<br />
Renvoie la ligne inchangée (105).<br />
♦ Curseur sensible L'appartenance du jeu <strong>de</strong> résultats a changé, <strong>de</strong> sorte<br />
que la ligne 105 est désormais la première du jeu <strong>de</strong> résultats.<br />
33
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
34<br />
Action Résultat<br />
Extraction <strong>de</strong> la ligne<br />
précé<strong>de</strong>nte<br />
Extraction <strong>de</strong> la<br />
première ligne<br />
(extraction absolue)<br />
Extraction <strong>de</strong> la<br />
<strong>de</strong>uxième ligne<br />
(extraction absolue)<br />
Renvoie une erreur La ligne est introuvable.<br />
L'appartenance du jeu <strong>de</strong> résultats a changé :<br />
105 est désormais la première ligne. Le curseur est<br />
placé avant la première ligne.<br />
Renvoie la ligne 105.<br />
Renvoie la ligne 160.<br />
En outre, une extraction sur un curseur sensible renvoie l’avertissement<br />
SQLE_ROW_UPDATED_WARNING si la ligne a été modifiée <strong>de</strong>puis sa<br />
<strong>de</strong>rnière extraction. L'avertissement n'est émis qu'une seule fois. Les<br />
lectures suivantes <strong>de</strong> la même ligne ne le génèrent pas.<br />
De même, une mise à jour ou une suppression positionnée effectuée via<br />
le curseur sur une ligne <strong>de</strong>puis sa <strong>de</strong>rnière extraction renvoie l'erreur<br />
SQLE_ROW_UPDATED_SINCE_READ. L'application doit <strong>de</strong><br />
nouveau extraire la ligne avant <strong>de</strong> pouvoir exécuter une opération <strong>de</strong><br />
mise à jour ou <strong>de</strong> suppression sur un curseur sensible.<br />
Toute mise à jour d'une colonne entraîne un avertissement ou une erreur,<br />
même si cette colonne n'est pas référencée par le curseur. Par exemple,<br />
un curseur positionné sur une requête renvoyant emp_lname signale la<br />
mise à jour, même si seule la colonne salary a été modifiée.<br />
♦ Curseur tenant compte <strong>de</strong>s valeurs L'appartenance du jeu <strong>de</strong> résultats<br />
étant fixe, la ligne 105 est toujours la <strong>de</strong>uxième du jeu <strong>de</strong> résultats.<br />
L'instruction DELETE est répercutée sur les valeurs du curseur et crée<br />
un "vi<strong>de</strong>" dans le jeu <strong>de</strong> résultats.
Curseurs insensibles<br />
Normes<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Action Résultat<br />
Extraction <strong>de</strong> la ligne<br />
précé<strong>de</strong>nte<br />
Extraction <strong>de</strong> la<br />
première ligne<br />
(extraction absolue)<br />
Extraction <strong>de</strong> la<br />
<strong>de</strong>uxième ligne<br />
(extraction absolue)<br />
Renvoie une erreur La ligne est introuvable.<br />
L'appartenance du jeu <strong>de</strong> résultats a changé :<br />
105 est désormais la première ligne. Le curseur est<br />
positionné sur l'emplacement "vi<strong>de</strong>" : il se trouve<br />
avant la ligne 105.<br />
Renvoie une erreur La ligne est introuvable.<br />
L'appartenance du jeu <strong>de</strong> résultats a changé :<br />
105 est désormais la première ligne. Le curseur est<br />
positionné sur le "vi<strong>de</strong>" : il se trouve avant la<br />
ligne 105.<br />
Renvoie la ligne 105.<br />
♦ Curseur à sensibilité indéfinie L’effet <strong>de</strong>s modifications sur<br />
l'appartenance et les valeurs du jeu <strong>de</strong> résultats est indéterminé. La<br />
réponse à une extraction <strong>de</strong> la ligne précé<strong>de</strong>nte, <strong>de</strong> la première ligne ou<br />
<strong>de</strong> la <strong>de</strong>uxième dépend <strong>de</strong> la métho<strong>de</strong> d'optimisation <strong>de</strong> la requête, selon<br />
que cette métho<strong>de</strong> implique la formation d'une table <strong>de</strong> travail ou que la<br />
ligne extraite a été préextraite à partir du client.<br />
Pas d’avertissements ni d’erreurs en mo<strong>de</strong> bulkcopy<br />
Aucun avertissement ni message d'erreur n'est généré en mo<strong>de</strong> bulkcopy<br />
(option -b du serveur <strong>de</strong> base <strong>de</strong> données).<br />
Ces curseurs sont insensibles en termes d'appartenance, d'ordre et <strong>de</strong> valeurs.<br />
Aucune modification apportée après leur ouverture n'est visible.<br />
Les curseurs insensibles ne sont utilisés qu'en lecture seule.<br />
Les curseurs insensibles correspon<strong>de</strong>nt à la définition <strong>de</strong> la norme ISO/ANSI<br />
en matière <strong>de</strong> curseurs insensibles et aux curseurs statiques ODBC.<br />
35
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Interfaces <strong>de</strong><br />
<strong>programmation</strong><br />
Description<br />
Curseurs sensibles<br />
Normes<br />
36<br />
Interface Type <strong>de</strong><br />
curseur<br />
ODBC, OLE DB<br />
et ADO<br />
Embed<strong>de</strong>d SQL INSENSITIVE<br />
ou NO SCROLL<br />
JDBC Non supporté.<br />
Open Client Non supporté.<br />
Commentaire<br />
Statique Si un curseur statique modifiable est<br />
<strong>de</strong>mandé, un curseur tenant compte <strong>de</strong>s<br />
valeurs est utilisé à la place.<br />
Les curseurs insensibles renvoient toujours <strong>de</strong>s lignes répondant aux critères<br />
<strong>de</strong> sélection <strong>de</strong> la requête, dans l'ordre spécifié par la clause ORDER BY.<br />
Le jeu <strong>de</strong> résultats d'un curseur insensible est matérialisé sous forme <strong>de</strong> table<br />
<strong>de</strong> travail lors <strong>de</strong> l'ouverture du curseur. Les conséquences sont les<br />
suivantes :<br />
♦ Si le jeu <strong>de</strong> résultats est très volumineux, l'espace disque et la mémoire<br />
nécessaires pour le gérer peuvent être importants.<br />
♦ Aucune ligne n'est renvoyée à l'application avant l'assemblage du jeu <strong>de</strong><br />
résultats sous forme <strong>de</strong> table <strong>de</strong> travail. Pour les requêtes complexes, il<br />
peut ainsi s'écouler un certain temps avant que la première ligne ne soit<br />
renvoyée à l'application.<br />
♦ Les lignes suivantes peuvent être directement extraites <strong>de</strong> la table <strong>de</strong><br />
travail et sont donc renvoyées plus rapi<strong>de</strong>ment. La bibliothèque cliente<br />
peut préextraire plusieurs lignes à la fois, ce qui améliore encore les<br />
performances.<br />
♦ Les instructions ROLLBACK et ROLLBACK TO SAVEPOINT n'ont<br />
aucune inci<strong>de</strong>nce sur les curseurs insensibles.<br />
Ces curseurs sont sensibles en termes d'appartenance, d'ordre et <strong>de</strong> valeurs.<br />
Ils peuvent être utilisés pour les types <strong>de</strong> curseur en lecture seule ou<br />
modifiables.<br />
Les curseurs sensibles correspon<strong>de</strong>nt à la définition <strong>de</strong> la norme ISO/ANSI<br />
en matière <strong>de</strong> curseurs sensibles, et aux curseurs dynamiques ODBC.
Interfaces <strong>de</strong><br />
<strong>programmation</strong><br />
Description<br />
Interface Type <strong>de</strong><br />
curseur<br />
ODBC, OLE DB<br />
et ADO<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Dynamique<br />
Commentaire<br />
Embed<strong>de</strong>d SQL SENSITIVE Egalement fourni en réponse à une<br />
<strong>de</strong>man<strong>de</strong> <strong>de</strong> curseur DYNAMIC<br />
SCROLL lorsqu'aucune table <strong>de</strong> travail<br />
n'est requise et que l'option PREFETCH<br />
est désactivée (OFF).<br />
Toutes les modifications sont visibles via le curseur, y compris celles<br />
apportées au moyen du curseur et par d'autres transactions. Des niveaux<br />
d'isolement supérieurs peuvent masquer certaines modifications apportées<br />
dans d'autres transactions en raison d'un verrouillage.<br />
Toutes les modifications apportées à l'appartenance, à l'ordre et aux valeurs<br />
<strong>de</strong> colonne du curseur sont visibles. Par exemple, si un curseur sensible<br />
contient une jointure et si une valeur d'une <strong>de</strong>s tables sous-jacentes est<br />
modifiée, toutes les lignes <strong>de</strong> résultat reposant sur cette ligne <strong>de</strong> base<br />
affichent la nouvelle valeur. L'appartenance et l'ordre du jeu <strong>de</strong> résultats<br />
peuvent changer à chaque extraction.<br />
Les curseurs sensibles renvoient toujours <strong>de</strong>s lignes répondant aux critères <strong>de</strong><br />
sélection <strong>de</strong> la requête, dans l'ordre spécifié par la clause ORDER BY.<br />
L'appartenance, l'ordre et les valeurs du jeu <strong>de</strong> résultats peuvent être<br />
modifiés.<br />
La mise en oeuvre <strong>de</strong>s curseurs sensibles est soumise à certaines restrictions :<br />
♦ Les lignes ne peuvent pas être préextraites, puisque les modifications<br />
apportées aux lignes préextraites ne seraient pas visibles via le curseur.<br />
Cette restriction peut avoir <strong>de</strong>s répercussions sur les performances.<br />
♦ Les curseurs sensibles doivent être mis en oeuvre sans table <strong>de</strong> travail,<br />
puisque les modifications apportées aux lignes stockées sous forme <strong>de</strong><br />
tables <strong>de</strong> travail ne seraient pas visibles via le curseur.<br />
♦ Cette restriction limite le choix <strong>de</strong> l'optimiseur en matière <strong>de</strong> métho<strong>de</strong> <strong>de</strong><br />
jointure et peut donc avoir <strong>de</strong>s répercussions sur les performances.<br />
♦ Pour certaines requêtes, l'optimiseur est incapable d'établir un plan ne<br />
comportant pas <strong>de</strong> table <strong>de</strong> travail qui rendrait le curseur sensible.<br />
37
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Curseurs à sensibilité indéfinie<br />
Normes<br />
Interfaces <strong>de</strong><br />
<strong>programmation</strong><br />
38<br />
Les tables <strong>de</strong> travail sont généralement utilisées pour trier et regrouper<br />
les résultats intermédiaires. Elles ne sont pas nécessaires pour le tri si les<br />
lignes sont accessibles au moyen d'un in<strong>de</strong>x. S'il est impossible d'établir<br />
une liste exhaustive <strong>de</strong>s requêtes qui utilisent <strong>de</strong>s tables <strong>de</strong> travail, en<br />
voici toutefois quelques-unes :<br />
♦ Requêtes UNION, même si UNION ALL n'utilise pas<br />
nécessairement <strong>de</strong>s tables <strong>de</strong> travail.<br />
♦ Instructions comprenant une clause ORDER BY, si la colonne<br />
ORDER BY ne comporte pas d'in<strong>de</strong>x.<br />
♦ Requêtes optimisées à l'ai<strong>de</strong> d'une jointure <strong>de</strong> hachage.<br />
♦ La plupart <strong>de</strong>s requêtes impliquant une clause DISTINCT ou<br />
GROUP BY.<br />
Dans ces cas, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> renvoie une erreur à<br />
l'application ou remplace le curseur par un curseur à sensibilité indéfinie<br />
avant d'émettre un avertissement.<br />
$ Pour plus d'informations sur l'optimisation <strong>de</strong>s requêtes et<br />
l'utilisation <strong>de</strong> tables <strong>de</strong> travail, reportez-vous à la section "Optimisation<br />
et exécution <strong>de</strong>s requêtes", page 333 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong><br />
l’utilisateur SQL.<br />
La sensibilité <strong>de</strong> ces curseurs en termes d'appartenance, d'ordre ou <strong>de</strong> valeurs<br />
est mal définie. La souplesse autorisée en matière <strong>de</strong> sensibilité permet<br />
d'optimiser les performances <strong>de</strong> ces curseurs.<br />
Les curseurs à sensibilité indéfinie ne sont utilisés que pour les types <strong>de</strong><br />
curseur en lecture seule.<br />
Les curseurs à sensibilité indéfinie correspon<strong>de</strong>nt à la définition <strong>de</strong> la norme<br />
ISO/ANSI en matière <strong>de</strong> curseurs à sensibilité indéfinie, et aux curseurs<br />
ODBC <strong>de</strong> sensibilité indéterminée.<br />
Interface Type <strong>de</strong> curseur<br />
ODBC, OLE DB et ADO Sensibilité indéterminée<br />
Embed<strong>de</strong>d SQL DYNAMIC SCROLL
Description<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Une <strong>de</strong>man<strong>de</strong> <strong>de</strong> curseur à sensibilité indéfinie impose peu <strong>de</strong> restrictions sur<br />
les métho<strong>de</strong>s qu'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> peut utiliser pour optimiser la<br />
requête et renvoyer <strong>de</strong>s lignes à l'application. Ces raisons expliquent que les<br />
curseurs à sensibilité indéfinie offrent les meilleures performances.<br />
L'optimiseur est en particulier libre d'utiliser n'importe quel moyen <strong>de</strong><br />
matérialisation <strong>de</strong>s résultats intermédiaires sous forme <strong>de</strong> tables <strong>de</strong> travail, et<br />
les lignes peuvent être préextraites par le client.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> n'offre aucune garantie quant à la visibilité <strong>de</strong>s<br />
modifications apportées aux lignes sous-jacentes <strong>de</strong> base. Certaines<br />
modifications peuvent être visibles, d'autres non. L'appartenance et l'ordre du<br />
jeu <strong>de</strong> résultats peuvent changer à chaque extraction. Ainsi, il est possible<br />
qu'après une modification <strong>de</strong>s lignes <strong>de</strong> base, seules certaines colonnes mises<br />
à jour soient reportées dans les résultats du curseur.<br />
Il n'est pas certain que les curseurs à sensibilité indéfinie renvoient <strong>de</strong>s lignes<br />
répondant aux critères <strong>de</strong> sélection et à l'ordre spécifiés dans la requête.<br />
L'appartenance <strong>de</strong>s lignes est fixée à l'ouverture du curseur, mais les<br />
modifications suivantes apportées aux valeurs sous-jacentes sont répercutées<br />
sur les résultats.<br />
Les curseurs à sensibilité indéfinie renvoient toujours <strong>de</strong>s lignes<br />
correspondant aux clauses WHERE et ORDER BY du client au moment où<br />
l'appartenance du curseur est établie. En cas <strong>de</strong> modification <strong>de</strong>s valeurs <strong>de</strong><br />
colonne après l'ouverture du curseur, il est possible que <strong>de</strong>s lignes ne<br />
correspondant plus aux clauses WHERE et ORDER BY soient renvoyées.<br />
Curseurs tenant compte <strong>de</strong>s valeurs<br />
Normes<br />
Interfaces <strong>de</strong><br />
<strong>programmation</strong><br />
Ces curseurs sont insensibles en termes d'appartenance et sensibles en<br />
matière d'ordre et <strong>de</strong> valeurs du jeu <strong>de</strong> résultats.<br />
Ils peuvent être utilisés pour les types <strong>de</strong> curseur en lecture seule ou<br />
modifiables.<br />
Les curseurs tenant compte <strong>de</strong>s valeurs ne correspon<strong>de</strong>nt à aucune définition<br />
<strong>de</strong> norme ISO/ANSI. Ils correspon<strong>de</strong>nt aux curseurs keyset ODBC.<br />
Interface Type <strong>de</strong> curseur<br />
ODBC, OLE DB et ADO Keyset<br />
Embed<strong>de</strong>d SQL SCROLL<br />
JDBC Keyset<br />
Open Client Keyset<br />
39
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Description<br />
40<br />
Si l'application extrait une ligne composée d'une ligne sous-jacente <strong>de</strong> base<br />
ayant été modifiée, la valeur mise à jour et l'état SQL_ROW_UPDATED<br />
doivent lui être transmis. Si l'application tente d'extraire une ligne qui était<br />
composée d'une ligne sous-jacente <strong>de</strong> base supprimée, un état<br />
SQL_ROW_DELETED doit lui être transmis.<br />
Les modifications apportées aux valeurs <strong>de</strong> clé primaire retirent la ligne du<br />
jeu <strong>de</strong> résultats (opération traitée comme une suppression suivie d'une<br />
insertion). Lorsqu'une ligne du jeu <strong>de</strong> résultats est supprimée (que ce soit du<br />
curseur ou en <strong>de</strong>hors du curseur) et qu'une nouvelle ligne comportant la<br />
même valeur <strong>de</strong> clé est insérée, il s'agit d'un cas particulier. La nouvelle ligne<br />
remplace alors l'ancienne, au même endroit.<br />
Il n'est pas certain que les lignes du jeu <strong>de</strong> résultats répon<strong>de</strong>nt aux critères <strong>de</strong><br />
sélection ou à l'ordre indiqués dans la requête. L'appartenance <strong>de</strong>s lignes<br />
étant fixée lors <strong>de</strong> l'ouverture du curseur, les modifications suivantes, qui<br />
font qu'une ligne ne correspond plus à la clause WHERE ou ORDER BY,<br />
sont sans effet sur l'appartenance <strong>de</strong> la ligne, ni sur sa position.<br />
Toutes les valeurs sont sensibles aux modifications apportées via le curseur.<br />
La sensibilité <strong>de</strong> l'appartenance aux modifications apportées via le curseur<br />
est contrôlée par l'option ODBC SQL_STATIC_SENSITIVITY. Si cette<br />
option est activée, les insertions effectuées au moyen du curseur ajoutent la<br />
ligne dans le curseur. Dans le cas contraire, elles ne sont pas incluses dans le<br />
jeu <strong>de</strong> résultats. Les suppressions effectuées via le curseur retirent la ligne du<br />
jeu <strong>de</strong> résultats, ce qui empêche tout "vi<strong>de</strong>" renvoyant l'état<br />
SQL_ROW_DELETED.<br />
Les curseurs tenant compte <strong>de</strong>s valeurs utilisent une table keyset. A<br />
l'ouverture du curseur, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> remplit une table <strong>de</strong><br />
travail avec <strong>de</strong>s informations qui i<strong>de</strong>ntifient chaque ligne faisant partie du jeu<br />
<strong>de</strong> résultats. Lors du défilement du jeu <strong>de</strong> résultats, la table keyset est utilisée<br />
pour en i<strong>de</strong>ntifier l'appartenance. En revanche, les valeurs sont extraites, si<br />
nécessaire, à partir <strong>de</strong>s tables sous-jacentes.<br />
La propriété d'appartenance fixe <strong>de</strong>s curseurs tenant compte <strong>de</strong>s valeurs<br />
permet à votre application <strong>de</strong> mémoriser la position <strong>de</strong>s lignes d'un curseur<br />
avec la certitu<strong>de</strong> que ces positions ne changeront pas. Pour plus<br />
d'informations, reportez-vous à la section "Exemple <strong>de</strong> sensibilité du<br />
curseur : suppression d'une ligne", page 31.<br />
♦ Si une ligne a été mise à jour ou est susceptible <strong>de</strong> l'avoir été <strong>de</strong>puis<br />
l'ouverture du curseur, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> renvoie un état<br />
SQLE_ROW_UPDATED_WARNING lors <strong>de</strong> l'extraction <strong>de</strong> la ligne.<br />
L'avertissement n'est émis qu'une seule fois. Il ne réapparaît pas en cas<br />
<strong>de</strong> nouvelle extraction <strong>de</strong> la ligne.
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
La mise à jour d'une colonne <strong>de</strong> la ligne entraîne cet avertissement,<br />
même si cette colonne n'est pas référencée par le curseur. Par exemple,<br />
un curseur positionné sur emp_lname et emp_fname signale la mise à<br />
jour, même si seule la colonne birthdate est modifiée. Ces messages et<br />
conditions d'erreur n'apparaissent pas lorsque les opérations <strong>de</strong> mise à<br />
jour sont effectuées en mo<strong>de</strong> bulkcopy (option -b du serveur <strong>de</strong> base <strong>de</strong><br />
données) et que le verrouillage <strong>de</strong> ligne est désactivé. Voir<br />
"Considérations sur les performances relatives au déplacement <strong>de</strong><br />
données", page 450 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL.<br />
$ Pour plus d'informations, reportez-vous à la section "La ligne a été<br />
mise à jour <strong>de</strong>puis la <strong>de</strong>rnière fois qu'elle a été lue", page 176 du<br />
document ASA Messages d’erreur.<br />
♦ Une tentative d'exécution <strong>de</strong> mise à jour ou <strong>de</strong> suppression positionnée<br />
sur une ligne ayant été modifiée <strong>de</strong>puis sa <strong>de</strong>rnière extraction renvoie<br />
une erreur SQLE_ROW_UPDATED_SINCE_READ et annule<br />
l'instruction. L'application doit <strong>de</strong> nouveau extraire la ligne avant <strong>de</strong><br />
pouvoir exécuter l'opération UPDATE ou DELETE.<br />
La mise à jour d'une colonne <strong>de</strong> la ligne entraîne cette erreur, même si la<br />
colonne n'est pas référencée par le curseur. Cette erreur ne se produit pas<br />
en mo<strong>de</strong> bulkcopy.<br />
$ Pour plus d'informations, reportez-vous à la section "La ligne a été<br />
modifiée <strong>de</strong>puis qu'elle a été lue pour la <strong>de</strong>rnière fois - l'opération est<br />
annulée", page 176 du document ASA Messages d’erreur.<br />
♦ Si une ligne a été supprimée après l'ouverture du curseur, que ce soit au<br />
moyen du curseur ou par une autre transaction, un vi<strong>de</strong> est créé dans le<br />
curseur. L'appartenance du curseur étant fixe, une position <strong>de</strong> ligne est<br />
réservée, mais l'opération DELETE est répercutée sur la valeur modifiée<br />
<strong>de</strong> la ligne. Si vous extrayez la ligne au niveau <strong>de</strong> ce vi<strong>de</strong>, une erreur<br />
Aucune ligne <strong>de</strong> curseur n'est actuellement sélectionnée<br />
(état SQL 24503) est générée. Elle indique qu'il n'existe pas <strong>de</strong> ligne<br />
courante, et le curseur reste positionné sur le vi<strong>de</strong>. Vous pouvez éviter<br />
les vi<strong>de</strong>s en utilisant <strong>de</strong>s curseurs sensibles, dont l'appartenance change<br />
avec les valeurs.<br />
$ Pour plus d'informations, reportez-vous à la section "Aucune ligne<br />
<strong>de</strong> curseur n'est actuellement sélectionnée", page 88 du document ASA<br />
Messages d’erreur.<br />
Avec les curseurs tenant compte <strong>de</strong>s valeurs, les lignes ne peuvent pas être<br />
préextraites. Cette restriction peut avoir <strong>de</strong>s répercussions sur les<br />
performances.<br />
41
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Sensibilité du curseur et performances<br />
42<br />
Il existe un compromis entre les performances et les autres propriétés du<br />
curseur. C'est en particulier le cas lorsqu'un curseur est rendu modifiable.<br />
Des restrictions sont alors imposées au traitement et à la transmission <strong>de</strong> la<br />
requête du curseur, d'où une réduction <strong>de</strong>s performances. De même, imposer<br />
<strong>de</strong>s conditions <strong>de</strong> sensibilité du curseur peut entraîner une diminution <strong>de</strong> ses<br />
performances.<br />
Pour saisir pourquoi la possibilité <strong>de</strong> mise à jour et la sensibilité <strong>de</strong>s curseurs<br />
ont une inci<strong>de</strong>nce sur les performances, vous <strong>de</strong>vez comprendre comment la<br />
base <strong>de</strong> données transmet les résultats visibles via un curseur à l'application<br />
cliente.<br />
Les résultats peuvent être stockés dans <strong>de</strong>ux emplacements intermédiaires<br />
pour <strong>de</strong>s raisons <strong>de</strong> performances :<br />
♦ Tables <strong>de</strong> travail Les résultats intermédiaires ou finaux peuvent être<br />
stockés sous forme <strong>de</strong> tables <strong>de</strong> travail. Les curseurs tenant compte <strong>de</strong>s<br />
valeurs utilisent une table <strong>de</strong> travail <strong>de</strong>s valeurs <strong>de</strong> clé primaire. Les<br />
caractéristiques <strong>de</strong> la requête peuvent également amener l'optimiseur à<br />
utiliser <strong>de</strong>s tables <strong>de</strong> travail dans le plan d'exécution qu'il a choisi.<br />
♦ Préextraction Dans une communication, le client peut extraire <strong>de</strong>s<br />
lignes dans un buffer <strong>de</strong> son côté pour éviter qu'une <strong>de</strong>man<strong>de</strong> soit<br />
envoyée au serveur <strong>de</strong> base <strong>de</strong> données pour chaque ligne.<br />
Application<br />
cliente<br />
Pilote ODBC ou<br />
bibliothèque réseau<br />
Prélecture<br />
<strong>de</strong> lignes<br />
Serveur <strong>de</strong> base<br />
<strong>de</strong> données<br />
Table <strong>de</strong><br />
travail<br />
La définition <strong>de</strong> la sensibilité et <strong>de</strong> la possibilité <strong>de</strong> mise à jour limitent<br />
l'utilisation <strong>de</strong>s emplacements intermédiaires.<br />
Les curseurs modifiables ne peuvent pas utiliser <strong>de</strong> tables <strong>de</strong> travail, ni<br />
préextraire <strong>de</strong>s résultats. S'ils y étaient autorisés, ils seraient vulnérables en<br />
termes <strong>de</strong> perte <strong>de</strong> mises à jour. Par exemple :<br />
1 Une application ouvre un curseur sur la requête suivante, qui concerne la<br />
base <strong>de</strong> données exemple.
Préextraction <strong>de</strong> lignes<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
SELECT id, quantity<br />
FROM product<br />
id quantity<br />
300 28<br />
301 54<br />
302 75<br />
… …<br />
2 L’application extrait la ligne comportant l’id 300 au moyen du curseur.<br />
3 Une autre transaction met la ligne à jour au moyen <strong>de</strong> l'instruction<br />
suivante :<br />
UPDATE product<br />
SET quantity = quantity - 10<br />
WHERE id = 300<br />
4 L'application remplace la valeur <strong>de</strong> la ligne via le curseur par<br />
(quantity - 5 ).<br />
5 La valeur correcte finale <strong>de</strong> la ligne est 13. Si le curseur avait préextrait<br />
la ligne, sa nouvelle valeur aurait été 23. La mise à jour <strong>de</strong> l'autre<br />
transaction aurait donc été perdue.<br />
La sensibilité est soumise à <strong>de</strong>s restrictions <strong>de</strong> même ordre. Pour plus<br />
d'informations, reportez-vous à la <strong>de</strong>scription <strong>de</strong>s différents types <strong>de</strong> curseur.<br />
Prélecture et extractions multiligne sont <strong>de</strong>ux opérations distinctes. Vous<br />
pouvez effectuer une prélecture sans instruction explicite <strong>de</strong> l'application<br />
cliente. La prélecture extrait <strong>de</strong>s lignes d'un serveur pour les placer dans un<br />
buffer du côté client, mais ne met ces lignes à disposition <strong>de</strong> l'application<br />
cliente que lorsque la ligne concernée est lue par l'application.<br />
Par défaut, la bibliothèque client <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> effectue une<br />
prélecture <strong>de</strong> plusieurs lignes dès qu'une application lit une ligne. Elle stocke<br />
les lignes supplémentaires dans un buffer.<br />
La prélecture améliore les performances en réduisant le trafic client/serveur,<br />
et accélère les opérations en mettant à disposition plusieurs lignes<br />
simultanément sans qu'il soit nécessaire <strong>de</strong> <strong>de</strong>man<strong>de</strong>r au serveur chaque ligne<br />
ou chaque bloc <strong>de</strong> lignes séparément.<br />
$ Pour plus d'informations sur le contrôle <strong>de</strong>s préextractions, reportezvous<br />
à la section "Option PREFETCH", page 646 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
43
Curseurs <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Contrôle <strong>de</strong> la<br />
prélecture à partir<br />
d'une application<br />
44<br />
♦ L'option PREFETCH permet d'indiquer si une prélecture doit avoir lieu<br />
ou non. Elle peut être définie à ON ou OFF pour une seule connexion.<br />
ON est la valeur par défaut.<br />
♦ Dans Embed<strong>de</strong>d SQL, vous pouvez contrôler la préextraction lorsque<br />
vous ouvrez un curseur, ou en spécifiant la clause BLOCK dans une<br />
opération FETCH.<br />
L'application peut spécifier la clause BLOCK, qui permet <strong>de</strong> préciser le<br />
nombre maximal <strong>de</strong> lignes pouvant être contenues dans un bloc. Par<br />
exemple, spécifiez BLOCK 5 pour extraire et afficher 5 lignes à la fois.<br />
BLOCK 0 ne permet d'extraire qu'un seul enregistrement à la fois et<br />
génère un FETCH RELATIVE 0 (réextraction <strong>de</strong> la ligne).<br />
Bien qu'il soit possible <strong>de</strong> désactiver la prélecture en définissant un<br />
paramètre <strong>de</strong> connexion au niveau <strong>de</strong> l'application, il est préférable<br />
d'utiliser BLOCK=0 à la place d'une option PREFETCH définie à OFF.<br />
$ Pour plus d'informations, reportez-vous à la section "Option<br />
PREFETCH", page 646 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
♦ Dans Open Client, vous pouvez contrôler la prélecture, une fois le<br />
curseur déclaré, mais pas encore ouvert, via ct_cursor avec<br />
CS_CURSOR_ROWS.<br />
Sensibilité du curseur et niveaux d'isolement<br />
La sensibilité du curseur et les niveaux d'isolement <strong>de</strong>s transactions<br />
répon<strong>de</strong>nt au problème <strong>de</strong> la concurrence d'accès, mais <strong>de</strong> façon différente.<br />
En choisissant un niveau d'isolement pour une transaction (généralement au<br />
niveau <strong>de</strong> la connexion), vous déterminez à quel moment <strong>de</strong>s verrous sont<br />
appliqués aux lignes <strong>de</strong> la base <strong>de</strong> données. Les verrous empêchent les autres<br />
transactions d'accé<strong>de</strong>r aux valeurs <strong>de</strong> la base ou <strong>de</strong> les modifier.<br />
En choisissant une sensibilité <strong>de</strong> curseur, vous déterminez les modifications<br />
visibles par l'application au moyen du curseur. En définissant la sensibilité<br />
du curseur, vous ne déterminez pas à quel moment <strong>de</strong>s verrous sont posés sur<br />
les lignes <strong>de</strong> la base <strong>de</strong> données, pas plus que vous ne limitez les<br />
modifications autorisées dans la base elle-même.
Description <strong>de</strong>s jeux <strong>de</strong> résultats<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Certaines applications construisent <strong>de</strong>s instructions SQL qui ne peuvent pas<br />
être entièrement spécifiées dans l'application. Ainsi, dans certains cas, les<br />
instructions dépen<strong>de</strong>nt <strong>de</strong> la réponse que l'utilisateur va apporter, <strong>de</strong> sorte<br />
que l'application ne sait pas exactement quelle information renvoyer ; c'est<br />
par exemple le cas lorsqu'une application <strong>de</strong> génération <strong>de</strong> rapport autorise<br />
un utilisateur à sélectionner les colonnes qu'il souhaite afficher.<br />
Dans ce type <strong>de</strong> situation, l'application doit faire appel à une métho<strong>de</strong> pour<br />
rechercher les informations sur la nature du jeu <strong>de</strong> résultats et sur son<br />
contenu. Les informations sur la nature du jeu <strong>de</strong> résultats, appelées<br />
<strong>de</strong>scripteur, i<strong>de</strong>ntifient la structure <strong>de</strong>s données, y compris le nombre et le<br />
type <strong>de</strong> colonnes qu'il est prévu <strong>de</strong> renvoyer. Une fois que l'application a<br />
déterminé la nature du jeu <strong>de</strong> résultats, elle peut récupérer directement son<br />
contenu.<br />
Ces métadonnées du jeu <strong>de</strong> résultats (c'est-à-dire les informations sur la<br />
nature et le contenu <strong>de</strong>s données) sont manipulées par <strong>de</strong>s <strong>de</strong>scripteurs. Le<br />
processus d'obtention et <strong>de</strong> gestion <strong>de</strong>s métadonnées du jeu <strong>de</strong> résultats<br />
s'appelle la <strong>de</strong>scription.<br />
Les jeux <strong>de</strong> résultats étant généralement obtenus à partir <strong>de</strong>s curseurs,<br />
<strong>de</strong>scripteurs et curseurs sont étroitement liés, bien que dans certaines<br />
interfaces, l'utilisation <strong>de</strong>s <strong>de</strong>scripteurs soit transparente pour l'utilisateur. En<br />
règle générale, les instructions qui requièrent un <strong>de</strong>scripteur sont soit <strong>de</strong>s<br />
instructions SELECT, soit <strong>de</strong>s procédures stockées qui renvoient <strong>de</strong>s jeux <strong>de</strong><br />
résultats.<br />
La séquence d'utilisation d'un <strong>de</strong>scripteur avec une opération fondée sur un<br />
curseur est la suivante :<br />
1 Allouez le <strong>de</strong>scripteur. Cette opération peut être implicite, bien que<br />
certaines interfaces autorisent l'allocation implicite.<br />
2 Préparez l'instruction.<br />
3 Décrivez l'instruction. Si celle-ci est un appel <strong>de</strong> procédure stockée ou<br />
un batch et si le résultat ne dépend pas d'une clause <strong>de</strong> résultat dans la<br />
définition <strong>de</strong> la procédure, la <strong>de</strong>scription doit intervenir après l'ouverture<br />
du curseur.<br />
4 Déclarez et ouvrez un curseur pour l'instruction (Embed<strong>de</strong>d SQL) ou<br />
exécutez l'instruction.<br />
5 Récupérez le <strong>de</strong>scripteur et modifiez si nécessaire la zone allouée. Cette<br />
opération est souvent implicite.<br />
6 Lisez et traitez les résultats <strong>de</strong> l'instruction.<br />
45
Description <strong>de</strong>s jeux <strong>de</strong> résultats<br />
Remarques sur la<br />
mise en oeuvre<br />
46<br />
7 Annulez l’allocation du <strong>de</strong>scripteur.<br />
8 Ferme le curseur.<br />
9 Supprimez l’instruction. Certaines interfaces le font automatiquement.<br />
♦ Dans Embed<strong>de</strong>d SQL, une structure SQLDA (SQL Descriptor Area)<br />
contient les informations propres au <strong>de</strong>scripteur.<br />
$ Pour plus d'informations, reportez-vous à la section "Zone<br />
<strong>de</strong>scripteur SQL (SQLDA)", page 226.<br />
♦ Dans ODBC, un gestionnaire <strong>de</strong> <strong>de</strong>scripteur, alloué via<br />
SQLAllocHandle, donne accès aux champs <strong>de</strong>s <strong>de</strong>scripteurs. Vous<br />
manipulez ces champs à l'ai<strong>de</strong> <strong>de</strong> SQLSetDescRec, SQLSetDescField,<br />
SQLGetDescRec et SQLGetDescField.<br />
Vous pouvez également utiliser SQLDescribeCol et SQLColAttributes<br />
pour obtenir <strong>de</strong>s informations sur les colonnes.<br />
♦ Dans Open Client, vous pouvez utiliser ct_dynamic pour préparer une<br />
instruction et ct_<strong>de</strong>scribe pour décrire le jeu <strong>de</strong> résultats obtenu. Mais il<br />
est également possible d'utiliser ct_command pour envoyer une<br />
instruction SQL sans préparation préalable, puis ct_results pour gérer<br />
les lignes renvoyées une par une. C'est la métho<strong>de</strong> la plus courante pour<br />
le développement d'applications Open Client.<br />
♦ Dans JDBC, la classe java.SQL.ResultSetMetaData fournit <strong>de</strong>s<br />
informations sur les jeux <strong>de</strong> résultats.<br />
♦ Vous pouvez également utiliser <strong>de</strong>s <strong>de</strong>scripteurs pour envoyer <strong>de</strong>s<br />
données au moteur (avec une instruction INSERT, par exemple).<br />
Toutefois, ce type <strong>de</strong> <strong>de</strong>scripteur diffère <strong>de</strong> celui mis en oeuvre dans <strong>de</strong>s<br />
jeux <strong>de</strong> résultats.<br />
$ Pour plus d'informations sur les paramètres d'entrée et <strong>de</strong> sortie <strong>de</strong><br />
l'instruction DESCRIBE, reportez-vous à la section "Instruction<br />
DESCRIBE [ESQL]", page 414 du document ASA Manuel <strong>de</strong> référence<br />
SQL.
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
Contrôle <strong>de</strong>s transactions dans les applications<br />
Les transactions sont <strong>de</strong>s ensembles atomiques d’instructions SQL. Toutes<br />
les instructions d'une transaction sont exécutées ou aucune ne l'est. Cette<br />
section traite <strong>de</strong> quelques aspects <strong>de</strong>s transactions dans les applications.<br />
$ Pour en savoir plus sur les transactions, reportez-vous au chapitre<br />
"Transactions et niveaux d'isolement", page 93 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong><br />
l’utilisateur SQL.<br />
Définition du mo<strong>de</strong> autocommit ou commit manuel<br />
Les interfaces <strong>de</strong> <strong>programmation</strong> <strong>de</strong> bases <strong>de</strong> données peuvent fonctionner en<br />
mo<strong>de</strong> commit manuel ou autocommit.<br />
♦ Mo<strong>de</strong> commit manuel Les opérations ne sont validées que lorsque<br />
l'application effectue une opération COMMIT explicite ou lorsque le<br />
serveur <strong>de</strong> base <strong>de</strong> données procè<strong>de</strong> à une validation automatique, par<br />
exemple lors <strong>de</strong> l'exécution d'une instruction ALTER TABLE ou <strong>de</strong><br />
toute autre instruction <strong>de</strong> définition <strong>de</strong> données. Le mo<strong>de</strong> commit<br />
manuel est quelquefois appelé mo<strong>de</strong> chaîné.<br />
Pour utiliser <strong>de</strong>s transactions dans votre application, notamment <strong>de</strong>s<br />
transactions imbriquées et <strong>de</strong>s points <strong>de</strong> sauvegar<strong>de</strong>, vous <strong>de</strong>vez<br />
travailler en mo<strong>de</strong> commit manuel.<br />
♦ Mo<strong>de</strong> autocommit Chaque instruction est traitée comme une transaction<br />
distincte. Ce mo<strong>de</strong> revient en effet à ajouter une instruction COMMIT à<br />
la fin <strong>de</strong> chacune <strong>de</strong> vos comman<strong>de</strong>s. Le mo<strong>de</strong> autocommit est<br />
quelquefois appelé mo<strong>de</strong> non chaîné.<br />
Ce mo<strong>de</strong> <strong>de</strong> fonctionnement peut avoir <strong>de</strong>s répercussions sur les<br />
performances et le comportement <strong>de</strong> votre application. Ne l'utilisez pas si<br />
l'intégrité transactionnelle doit être respectée dans votre application.<br />
$ Pour plus d'informations sur les effets du mo<strong>de</strong> autocommit sur les<br />
performances, reportez-vous à la section "Désactivez le mo<strong>de</strong> <strong>de</strong> validation<br />
automatique", page 158 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL.<br />
Contrôle du comportement du mo<strong>de</strong> autocommit<br />
La façon dont vous contrôlez le comportement <strong>de</strong> votre application en<br />
matière <strong>de</strong> validation dépend <strong>de</strong> l'interface <strong>de</strong> <strong>programmation</strong> utilisée. Selon<br />
l'interface, la mise en oeuvre du mo<strong>de</strong> autocommit peut en effet être<br />
effectuée côté client ou côté serveur.<br />
47
Contrôle <strong>de</strong>s transactions dans les applications<br />
48<br />
$ Pour plus d'informations, reportez-vous à la section "Détails <strong>de</strong> mise en<br />
oeuvre du mo<strong>de</strong> autocommit", page 48.<br />
v Pour contrôler le mo<strong>de</strong> autocommit (ODBC) :<br />
♦ Par défaut, ODBC opère en mo<strong>de</strong> autocommit. La façon dont vous<br />
pouvez désactiver le mo<strong>de</strong> autocommit varie selon que vous utilisez<br />
directement ODBC ou un outil <strong>de</strong> développement d'applications. Si vous<br />
procé<strong>de</strong>z à la <strong>programmation</strong> directement dans l'interface ODBC,<br />
définissez l'attribut <strong>de</strong> connexion SQL_ATTR_AUTOCOMMIT.<br />
v Pour contrôler le mo<strong>de</strong> autocommit (JDBC) :<br />
♦ Par défaut, JDBC opère en mo<strong>de</strong> autocommit. Pour désactiver le mo<strong>de</strong><br />
autocommit, utilisez la métho<strong>de</strong> setAutoCommit <strong>de</strong> l'objet Connection :<br />
conn.setAutoCommit( false );<br />
v Pour contrôler le mo<strong>de</strong> autocommit (Open Client) :<br />
♦ Par défaut, une connexion établie via Open Client opère en mo<strong>de</strong><br />
autocommit. Vous pouvez changer <strong>de</strong> mo<strong>de</strong> en définissant l'option <strong>de</strong><br />
base <strong>de</strong> données CHAINED à ON dans votre application, par le biais<br />
d'une instruction similaire à celle qui suit :<br />
SET OPTION CHAINED=’ON’<br />
v Pour contrôler le mo<strong>de</strong> autocommit (Embed<strong>de</strong>d SQL) :<br />
♦ Par défaut, les applications Embed<strong>de</strong>d SQL opèrent en mo<strong>de</strong> commit<br />
manuel. Pour activer le mo<strong>de</strong> autocommit, définissez l'option <strong>de</strong> base <strong>de</strong><br />
données CHAINED à OFF par le biais d'une instruction similaire à celle<br />
qui suit :<br />
SET OPTION CHAINED=’OFF’<br />
Détails <strong>de</strong> mise en oeuvre du mo<strong>de</strong> autocommit<br />
La section précé<strong>de</strong>nte, "Contrôle du comportement du mo<strong>de</strong> autocommit",<br />
page 47, décrit comment contrôler le comportement du mo<strong>de</strong> autocommit à<br />
partir <strong>de</strong> chacune <strong>de</strong>s interfaces <strong>de</strong> <strong>programmation</strong> d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>. Le comportement du mo<strong>de</strong> autocommit varie légèrement selon<br />
l'interface que vous utilisez et la façon dont vous le contrôlez.<br />
Il peut être mis en oeuvre <strong>de</strong> <strong>de</strong>ux façons :<br />
♦ Autocommit côté client Lorsqu’une application utilise le mo<strong>de</strong><br />
autocommit, la bibliothèque cliente émet une instruction COMMIT<br />
après chaque instruction SQL exécutée.
Contrôle du niveau d'isolement<br />
Curseurs et transactions<br />
Chapitre 2 Utilisation <strong>de</strong> SQL dans les applications<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> se sert du mo<strong>de</strong> autocommit côté client pour<br />
les applications ODBC et OLE DB.<br />
♦ Autocommit côté serveur Lorsqu’une application utilise le mo<strong>de</strong><br />
autocommit, le serveur <strong>de</strong> base <strong>de</strong> données émet une instruction<br />
COMMIT après chaque instruction SQL. Ce comportement est contrôlé,<br />
implicitement en ce qui concerne JDBC, par l'option <strong>de</strong> base <strong>de</strong> données<br />
CHAINED.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> se sert du mo<strong>de</strong> autocommit côté serveur<br />
pour les applications Embed<strong>de</strong>d SQL, JDBC et Open Client.<br />
Il existe une différence entre le mo<strong>de</strong> autocommit côté client et côté serveur<br />
en cas d'instructions composées telles que les procédures stockées ou les<br />
triggers. Côté client, une procédure stockée est une instruction unique. Le<br />
mo<strong>de</strong> autocommit envoie donc une instruction COMMIT une fois la<br />
procédure entièrement exécutée. Du point <strong>de</strong> vue du serveur <strong>de</strong> base <strong>de</strong><br />
données, la procédure stockée peut être composée <strong>de</strong> plusieurs<br />
instructions SQL. Le mo<strong>de</strong> autocommit côté serveur émet alors une<br />
instruction COMMIT après chaque instruction SQL <strong>de</strong> la procédure.<br />
Ne combinez pas les mises en oeuvre côté client et côté serveur<br />
N'utilisez pas l'option CHAINED en même temps que le mo<strong>de</strong><br />
autocommit dans une application ODBC ou OLE DB.<br />
Le niveau d'isolement d'une connexion active est défini via l'option <strong>de</strong> base<br />
<strong>de</strong> données ISOLATION_LEVEL.<br />
Certaines interfaces, telle qu'ODBC, permettent <strong>de</strong> définir le niveau<br />
d'isolement d'une connexion au moment <strong>de</strong> la connexion. Ce niveau peut être<br />
réinitialisé ultérieurement via l'option <strong>de</strong> base <strong>de</strong> données<br />
ISOLATION_LEVEL.<br />
En général, un curseur est fermé lorsqu'un COMMIT est exécuté. Il existe<br />
<strong>de</strong>ux exceptions :<br />
♦ L'option <strong>de</strong> base <strong>de</strong> données CLOSE_ON_ENDTRANS a la<br />
valeur OFF.<br />
♦ Un curseur est ouvert avec la clause WITH HOLD, ce qui est le<br />
comportement par défaut avec Open Client et JDBC.<br />
49
Contrôle <strong>de</strong>s transactions dans les applications<br />
ROLLBACK et<br />
curseurs<br />
Points <strong>de</strong><br />
sauvegar<strong>de</strong><br />
Curseurs et<br />
niveaux<br />
d’isolement<br />
50<br />
Dans l’un ou l’autre cas, le curseur reste ouvert en cas <strong>de</strong> COMMIT.<br />
Si une transaction est annulée, les curseurs sont fermés, sauf ceux ouverts<br />
WITH HOLD. Cependant, n'oubliez pas qu'après une annulation, le contenu<br />
<strong>de</strong>s curseurs, quels qu'ils soient, n'est pas fiable.<br />
L'avant-projet <strong>de</strong> norme ISO SQL3 spécifie qu'après une annulation, tous les<br />
curseurs (même ceux ouverts avec la clause WITH HOLD) doivent être<br />
fermés. Pour ce faire, donnez à l'option<br />
ANSI_CLOSE_CURSORS_AT_ROLLBACK la valeur ON.<br />
Si une transaction est annulée jusqu'à un point <strong>de</strong> sauvegar<strong>de</strong> et si l'option<br />
ANSI_CLOSE_CURSORS_AT_ROLLBACK a la valeur ON, tous les<br />
curseurs ouverts après le point <strong>de</strong> sauvegar<strong>de</strong> (même ceux ouverts avec la<br />
clause WITH HOLD) sont fermés.<br />
Vous pouvez modifier le niveau d'isolement d'une connexion pendant une<br />
transaction via l'instruction SET OPTION pour modifier l'option<br />
ISOLATION_LEVEL. Toutefois, ce changement n'a d'inci<strong>de</strong>nce que sur les<br />
curseurs fermés.
CHAPITRE 3<br />
Présentation <strong>de</strong> Java dans la base <strong>de</strong><br />
données<br />
Présentation<br />
Sommaire<br />
Ce chapitre présente les concepts <strong>de</strong> l'utilisation <strong>de</strong> Java dans la base <strong>de</strong><br />
données et décrit les avantages qu'elle procure.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est un environnement d'exécution <strong>de</strong> Java.<br />
Véritable extension naturelle <strong>de</strong> SQL, Java fait d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
une véritable plate-forme pour la prochaine génération d'applications<br />
d'entreprise.<br />
Sujet Page<br />
Introduction 52<br />
FAQ concernant Java dans la base <strong>de</strong> données 55<br />
Séminaire Java 62<br />
Environnement d'exécution pour Java dans la base <strong>de</strong> données 73<br />
Didacticiel : Java dans la base <strong>de</strong> données - Exercice pratique 82<br />
51
Introduction<br />
Introduction<br />
Composant sous<br />
licence séparée<br />
La norme SQLJ<br />
52<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est un environnement d'exécution <strong>de</strong> Java.<br />
Cela signifie que les classes Java peuvent être exécutées dans le serveur <strong>de</strong> la<br />
base <strong>de</strong> données. Cette intégration d'un environnement d'exécution <strong>de</strong>s<br />
classes Java dans le serveur <strong>de</strong> la base <strong>de</strong> données ouvre <strong>de</strong> très vastes<br />
perspectives en matière <strong>de</strong> gestion et <strong>de</strong> stockage <strong>de</strong>s données et <strong>de</strong> la<br />
logique.<br />
Au niveau <strong>de</strong> la base <strong>de</strong> données, Java apporte les avantages suivants :<br />
♦ Vous pouvez réutiliser les composants Java dans les différentes couches<br />
<strong>de</strong> l'application (client, niveau intermédiaire et serveur) et les appliquer<br />
aux endroits qui vous paraissent les plus pertinents. <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> <strong>de</strong>vient une véritable plate-forme pour l'informatique<br />
distribuée.<br />
♦ Java est un langage bien plus puissant que les procédures stockées pour<br />
intégrer <strong>de</strong> la logique dans la base <strong>de</strong> données.<br />
♦ Les classes Java <strong>de</strong>viennent <strong>de</strong> puissants types <strong>de</strong> données définis par<br />
l'utilisateur.<br />
♦ Les métho<strong>de</strong>s <strong>de</strong>s classes Java offrent <strong>de</strong> nouvelles fonctions accessibles<br />
<strong>de</strong>puis SQL.<br />
♦ Vous pouvez utiliser Java dans la base <strong>de</strong> données sans mettre en péril<br />
son intégrité, sa sécurité ou sa fiabilité.<br />
Java dans la base <strong>de</strong> données est un composant faisant l'objet d'une licence<br />
séparée. Pour comman<strong>de</strong>r ce composant, utilisez le formulaire disponible<br />
dans votre package SQL <strong>Anywhere</strong> Studio package ou reportez-vous à<br />
l'adresse http://www.sybase.com/<strong>de</strong>tail?id=1015780.<br />
Java dans la base <strong>de</strong> données repose sur les normes proposées SQLJ Partie 1<br />
et SQLJ Partie 2. SQLJ Partie 1 fournit les spécifications pour les appels <strong>de</strong><br />
métho<strong>de</strong>s statiques comme les procédures stockées SQL et les fonctions<br />
définies par l'utilisateur. SQLJ Partie 2 fournit les spécifications d'utilisation<br />
<strong>de</strong>s classes Java, telles que les domaines SQL.<br />
Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Java est un langage <strong>de</strong> <strong>programmation</strong> relativement récent pour lequel la<br />
base <strong>de</strong> connaissances, certes en plein développement, reste limitée. La<br />
présente documentation s'adresse non seulement à tous ceux qui ne<br />
maîtrisent pas encore ce langage, ses possibilités, sa syntaxe et son<br />
utilisation, mais aussi aux développeurs Java expérimentés.
Documentation<br />
relative à Java<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Ces <strong>de</strong>rniers découvriront avec profit l'utilisation <strong>de</strong> Java dans la base <strong>de</strong><br />
données. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> accroît non seulement les capacités <strong>de</strong><br />
la base <strong>de</strong> données grâce à Java, mais élargit aussi les possibilités <strong>de</strong> Java en<br />
l'associant à la base <strong>de</strong> données.<br />
Le tableau suivant présente les différents éléments <strong>de</strong> la documentation<br />
relative à l'utilisation <strong>de</strong> Java dans la base <strong>de</strong> données.<br />
Titre Fonction<br />
"Présentation <strong>de</strong> Java dans la<br />
base <strong>de</strong> données", page 51 (le<br />
présent chapitre)<br />
"Utilisation <strong>de</strong> Java dans la<br />
base <strong>de</strong> données", page 91<br />
"Accès aux données via<br />
JDBC", page 139<br />
"Débogage d'une logique dans<br />
une base <strong>de</strong> données",<br />
page 607 du document ASA<br />
<strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL<br />
Documentation d'<strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong><br />
Reference gui<strong>de</strong> to Sun's Java<br />
API<br />
Thinking in Java, <strong>de</strong> Bruce<br />
Eckel.<br />
Utilisation <strong>de</strong> la documentation Java<br />
Présentation <strong>de</strong>s concepts <strong>de</strong> Java et <strong>de</strong> leur<br />
application dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Présentation <strong>de</strong>s différentes étapes <strong>de</strong><br />
l'utilisation <strong>de</strong> Java dans la base <strong>de</strong> données.<br />
Description <strong>de</strong> l'accès aux données à partir <strong>de</strong>s<br />
classes Java, et notamment l'informatique<br />
distribuée.<br />
Présentation <strong>de</strong>s procédures <strong>de</strong> test et <strong>de</strong><br />
débogage du co<strong>de</strong> Java exécuté dans la base <strong>de</strong><br />
données.<br />
Le Manuel <strong>de</strong> référence SQL comprend <strong>de</strong>s<br />
informations sur les extensions SQL qui<br />
supportent Java dans la base <strong>de</strong> données.<br />
<strong>Gui<strong>de</strong></strong> en ligne relatif aux classes, champs et<br />
métho<strong>de</strong>s <strong>de</strong> l'API Java. Disponible uniquement<br />
comme ai<strong>de</strong> Windows.<br />
Documentation en ligne pour l'apprentissage <strong>de</strong><br />
la <strong>programmation</strong> en Java. Disponible au<br />
format PDF d'Adobe dans le sous-répertoire<br />
Samples\ASA\Java du répertoire<br />
SQL <strong>Anywhere</strong>.<br />
Le tableau suivant indique quelles parties <strong>de</strong> la documentation relative à Java<br />
consulter en fonction <strong>de</strong>s thèmes recherchés. Ces orientations n'ont qu'une<br />
valeur indicative et ne doivent en rien bri<strong>de</strong>r votre exploration <strong>de</strong> l'utilisation<br />
<strong>de</strong> Java dans la base <strong>de</strong> données.<br />
53
Introduction<br />
54<br />
Si... Consultez...<br />
Vous débutez dans la <strong>programmation</strong><br />
orientée objet.<br />
Vous voulez une définition <strong>de</strong> termes tels<br />
que instance, champ et métho<strong>de</strong> <strong>de</strong><br />
classe.<br />
Vous maîtrisez déjà le développement en<br />
Java et souhaitez juste quelques<br />
informations pour démarrer.<br />
Vous voulez connaître les fonctionnalités<br />
clés <strong>de</strong> Java dans la base <strong>de</strong> données.<br />
Vous voulez maîtriser l'accès aux<br />
données à partir <strong>de</strong> Java.<br />
Vous voulez préparer une base <strong>de</strong><br />
données pour Java.<br />
Vous voulez consulter une liste complète<br />
<strong>de</strong>s API Java gérées.<br />
Vous voulez obtenir <strong>de</strong>s informations <strong>de</strong><br />
référence sur Java pendant l'utilisation<br />
d'une classe d'API Java.<br />
Vous voulez découvrir un exemple<br />
d'informatique distribuée.<br />
"Séminaire Java", page 62<br />
Thinking in Java <strong>de</strong> Bruce Eckel.<br />
"Séminaire Java", page 62<br />
"Environnement d'exécution pour<br />
Java dans la base <strong>de</strong> données",<br />
page 73<br />
"Didacticiel : Java dans la base <strong>de</strong><br />
données - Exercice pratique", page 82<br />
"FAQ concernant Java dans la base<br />
<strong>de</strong> données", page 55<br />
"Accès aux données via JDBC",<br />
page 139<br />
"Configuration <strong>de</strong> la base <strong>de</strong> données<br />
pour Java", page 95<br />
"Types <strong>de</strong> données <strong>de</strong> classe Java",<br />
page 82 du document ASA Manuel <strong>de</strong><br />
référence SQL<br />
Le gui<strong>de</strong> en ligne <strong>de</strong>s classes d'API<br />
Java (Ai<strong>de</strong> Windows uniquement)<br />
"Création d'applications distribuées",<br />
page 171.
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
FAQ concernant Java dans la base <strong>de</strong> données<br />
Cette section présente les fonctionnalités clés <strong>de</strong> Java dans la base <strong>de</strong><br />
données.<br />
Fonctionnalités clés <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Tous les points ci-<strong>de</strong>ssous sont décrits en détail dans les sections suivantes.<br />
♦ Exécution <strong>de</strong> Java dans le serveur <strong>de</strong> la base <strong>de</strong> données Une<br />
machine virtuelle (VM) Java interne exécute le co<strong>de</strong> Java dans le<br />
serveur <strong>de</strong> la base <strong>de</strong> données.<br />
♦ Appel <strong>de</strong> Java à partir <strong>de</strong> SQL Vous pouvez appeler les fonctions Java<br />
(métho<strong>de</strong>s) à partir d'instructions SQL. Les métho<strong>de</strong>s Java constituent<br />
un langage bien plus puissant que les procédures stockées SQL pour<br />
ajouter <strong>de</strong> la logique à la base <strong>de</strong> données.<br />
♦ Accès aux données <strong>de</strong>puis Java Un gestionnaire JDBC interne permet<br />
d'accé<strong>de</strong>r aux données <strong>de</strong>puis Java.<br />
♦ Débogage <strong>de</strong> Java dans la base <strong>de</strong> données Le débogueur <strong>Sybase</strong><br />
permet <strong>de</strong> tester et déboguer les classes Java dans la base <strong>de</strong> données.<br />
♦ Utilisation <strong>de</strong> classes Java comme types <strong>de</strong> données Toute classe<br />
Java installée dans une base <strong>de</strong> données est utilisable comme type <strong>de</strong><br />
données d'une colonne dans une table ou une variable.<br />
♦ Enregistrement d’objets Java dans <strong>de</strong>s tables Toute instance d'une<br />
classe Java (un objet Java) peut être enregistrée sous forme <strong>de</strong> valeur<br />
dans une table. Vous pouvez insérer les objets Java dans une table,<br />
exécuter <strong>de</strong>s instructions SELECT sur les champs et les métho<strong>de</strong>s <strong>de</strong>s<br />
objets stockés dans une table et extraire les objets Java d'une table.<br />
Avec cette fonctionnalité, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> <strong>de</strong>vient une base<br />
<strong>de</strong> données relationnelle objet, capable <strong>de</strong> gérer les objets sans altérer la<br />
fonctionnalité relationnelle existante.<br />
♦ Préservation <strong>de</strong> SQL L'utilisation <strong>de</strong> Java n'altère en rien l'action <strong>de</strong>s<br />
instructions SQL existantes ou celle d'autres aspects <strong>de</strong>s bases <strong>de</strong><br />
données relationnelles non Java.<br />
55
FAQ concernant Java dans la base <strong>de</strong> données<br />
Stockage <strong>de</strong>s instructions Java dans la base <strong>de</strong> données<br />
56<br />
Java est un langage orienté objet, c'est-à-dire que ses instructions (son co<strong>de</strong><br />
source) se présentent sous forme <strong>de</strong> classes. Pour exécuter Java dans une<br />
base <strong>de</strong> données, vous <strong>de</strong>vez écrire les instructions Java, puis les compiler en<br />
classes (co<strong>de</strong> octet), c'est-à-dire en fichiers binaires contenant les<br />
instructions Java, en <strong>de</strong>hors <strong>de</strong> la base <strong>de</strong> données.<br />
Ensuite, vous installez ces classes compilées dans la base <strong>de</strong> données. Une<br />
fois installées, ces classes peuvent être exécutées dans le serveur <strong>de</strong> la base<br />
<strong>de</strong> données.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est un environnement d'exécution <strong>de</strong>s classes<br />
Java, pas un environnement <strong>de</strong> développement Java. Pour écrire et compiler<br />
en Java, il faut un environnement <strong>de</strong> développement Java, tel que<br />
<strong>Sybase</strong> PowerJ ou le Java Development Kit <strong>de</strong> Sun Microsystems.<br />
$ Pour plus d'informations, reportez-vous à la section "Installation <strong>de</strong><br />
classes Java dans une base <strong>de</strong> données", page 101.<br />
Exécution <strong>de</strong> Java dans une base <strong>de</strong> données<br />
Différences avec<br />
une machine<br />
virtuelle autonome<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> comprend une machine virtuelle Java qui est<br />
exécutée dans l'environnement <strong>de</strong> la base <strong>de</strong> données. La machine virtuelle<br />
<strong>Sybase</strong> Java interprète les instructions Java compilées, puis les exécute dans<br />
le serveur <strong>de</strong> la base <strong>de</strong> données.<br />
En plus <strong>de</strong> la machine virtuelle, le processeur <strong>de</strong> requêtes SQL du serveur <strong>de</strong><br />
la base <strong>de</strong> données a également été étendu <strong>de</strong> façon à pouvoir lancer la<br />
machine virtuelle pour exécuter <strong>de</strong>s instructions Java. Il peut aussi traiter <strong>de</strong>s<br />
requêtes à partir <strong>de</strong> la machine virtuelle, pour permettre l'accès aux données<br />
<strong>de</strong>puis Java.<br />
Exécuter du co<strong>de</strong> Java à l'ai<strong>de</strong> d'une machine virtuelle standard (comme la<br />
machine virtuelle Sun Java java.exe) n'est pas la même chose qu'exécuter du<br />
co<strong>de</strong> Java dans la base <strong>de</strong> données. En effet, la machine virtuelle Sun est<br />
exécutée à partir d'une ligne <strong>de</strong> comman<strong>de</strong>, tandis que la machine virtuelle<br />
Java d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est disponible à tous moments pour<br />
exécuter une opération Java requise dans l'exécution d'une instruction SQL.<br />
En outre, l'interpréteur Java <strong>de</strong> <strong>Sybase</strong> est inaccessible <strong>de</strong>puis l'extérieur. Il<br />
est utilisé uniquement lorsque l'exécution d'une instruction SQL implique la<br />
réalisation d'une opération Java. Lorsque cela est nécessaire, le serveur <strong>de</strong> la<br />
base <strong>de</strong> données lance automatiquement la machine virtuelle. Vous<br />
n'intervenez à aucun moment pour lancer ou arrêter la machine virtuelle.
Avantages <strong>de</strong> Java<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Java offre un certain nombre <strong>de</strong> fonctionnalités parfaitement adaptées à son<br />
utilisation dans la base <strong>de</strong> données.<br />
♦ Recherche approfondie d'erreurs lors <strong>de</strong> la compilation.<br />
♦ Gestion intégrée <strong>de</strong>s erreurs sur la base d'une méthodologie clairement<br />
définie.<br />
♦ Défragmentation intégrée <strong>de</strong> la mémoire (récupération <strong>de</strong> la mémoire).<br />
♦ Elimination <strong>de</strong> nombreuses techniques <strong>de</strong> <strong>programmation</strong> sujettes aux<br />
bugs.<br />
♦ Puissantes fonctionnalités <strong>de</strong> sécurité.<br />
♦ Le co<strong>de</strong> Java étant interprété, aucune opération n'est exécutée si elle ne<br />
peut pas être acceptée par la machine virtuelle.<br />
Plates-formes supportant Java dans la base <strong>de</strong> données<br />
Java dans la base <strong>de</strong> données n'est pas supporté par Windows CE. Il est<br />
supporté par les autres plates-formes Windows, UNIX et NetWare.<br />
Utilisation combinée <strong>de</strong> Java et SQL<br />
L'intégration <strong>de</strong> Java dans la base <strong>de</strong> données a été conçue pour constituer<br />
une extension naturelle et ouverte à la fonctionnalité SQL existante.<br />
♦ Appel <strong>de</strong>s opérations Java à partir <strong>de</strong> SQL <strong>Sybase</strong> a étendu la gamme<br />
<strong>de</strong>s expressions SQL pour y inclure les propriétés et métho<strong>de</strong>s <strong>de</strong>s objets<br />
Java, ce qui permet d'intégrer <strong>de</strong>s opérations Java dans une instruction<br />
SQL.<br />
♦ Classes Java, véritables domaines Le stockage <strong>de</strong>s classes Java<br />
s'opère via les mêmes instructions SQL que celles employées pour les<br />
types <strong>de</strong> données SQL classiques.<br />
Vous pouvez utiliser <strong>de</strong> nombreuses classes <strong>de</strong> l'API Java contenues dans le<br />
JDK (Java Development Kit) <strong>de</strong> Sun Microsystems. Vous pouvez également<br />
utiliser <strong>de</strong>s classes créées et compilées par les développeurs Java.<br />
57
FAQ concernant Java dans la base <strong>de</strong> données<br />
Présentation <strong>de</strong> l'API Java<br />
Accès à Java à partir <strong>de</strong> SQL<br />
58<br />
L’API (Application Programmer’s Interface) Java est un ensemble <strong>de</strong> classes<br />
créé par Sun Microsystems. Elle offre une gamme <strong>de</strong> fonctionnalités <strong>de</strong> base<br />
que les développeurs Java peuvent utiliser et même développer. C'est elle qui<br />
confère à Java toute sa valeur.<br />
A elle seule, l'API Java offre un nombre considérable <strong>de</strong> fonctionnalités.<br />
Toute base <strong>de</strong> données capable d'utiliser le co<strong>de</strong> Java comporte une part<br />
importante <strong>de</strong> l'API Java. En l'occurrence, il s'agit <strong>de</strong> la majorité <strong>de</strong>s classes<br />
non visuelles <strong>de</strong> l'API Java, auxquelles sont déjà habitués les développeurs<br />
qui utilisent le JDK (Java Development Kit) <strong>de</strong> Sun Microsystems.<br />
$ Pour plus d'informations sur les API Java supportées, reportez-vous à la<br />
section "Packages Java supportés", page 83 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
L'API Java peut être utilisée dans <strong>de</strong>s classes, mais également dans <strong>de</strong>s<br />
procédures stockées et <strong>de</strong>s instructions SQL. Vous pouvez effectivement<br />
considérer les classes <strong>de</strong> l'API Java comme <strong>de</strong>s extensions <strong>de</strong>s fonctions<br />
intégrées proposées par SQL.<br />
Par exemple, la fonction SQL PI(*) renvoie la valeur <strong>de</strong> PI. La classe API<br />
Java java.lang.Math comprend un champ parallèle appelé PI renvoyant la<br />
même valeur. Cependant, java.lang.Math comporte également un champ<br />
nommé E qui renvoie la base <strong>de</strong>s logarithmes naturels, ainsi qu'une métho<strong>de</strong><br />
calculant le reste sur <strong>de</strong>ux arguments, comme le prévoit la norme IEEE 754.<br />
D'autres éléments <strong>de</strong> l'API Java offrent <strong>de</strong>s fonctionnalités encore plus<br />
spécialisées. Par exemple, java.util.Stack génère une file d'attente LIFO<br />
(<strong>de</strong>rnier entré, premier sorti) capable <strong>de</strong> stocker une liste triée,<br />
java.util.HashTable met en correspondance <strong>de</strong>s valeurs et <strong>de</strong>s clés, et<br />
java.util.StringTokenizer découpe une chaîne <strong>de</strong> caractères en mots.<br />
$ Pour plus d'informations, reportez-vous à la section "Insertion, mise à<br />
jour et suppression d'objets Java", page 108.
Classes Java supportées<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
La base <strong>de</strong> données ne supporte pas toutes le classes <strong>de</strong> l'API Java. Certaines<br />
classes, telles que le package java.awt qui contient <strong>de</strong>s composants<br />
d'interface utilisateur <strong>de</strong>stinés à <strong>de</strong>s applications, n'ont pas leur place dans un<br />
serveur <strong>de</strong> base <strong>de</strong> données. D'autres, notamment certaines parties <strong>de</strong> java.io,<br />
ont trait à l'écriture d'informations sur disque et ne sont pas supportées dans<br />
l'environnement <strong>de</strong> serveur <strong>de</strong> base <strong>de</strong> données.<br />
$ Pour plus d'informations sur les classes supportées et non supportées,<br />
reportez-vous aux sections "Packages Java supportés", page 83 du document<br />
ASA Manuel <strong>de</strong> référence SQL et "Packages et classes Java non supportés",<br />
page 84 du document ASA Manuel <strong>de</strong> référence SQL.<br />
Utilisation <strong>de</strong> classes Java personnelles dans <strong>de</strong>s bases <strong>de</strong><br />
données<br />
Vous pouvez installer vos propres classes Java dans une base <strong>de</strong> données. Par<br />
exemple, il peut s'agir d'une classe Employee ou Package créée par un<br />
développeur qui l'a écrite en Java, puis compilée à l'ai<strong>de</strong> d'un compilateur<br />
Java.<br />
Les classes Java créées par l'utilisateur peuvent contenir <strong>de</strong>s informations sur<br />
le sujet, ainsi que certains éléments <strong>de</strong> logique <strong>de</strong> calcul. Dès lors que ces<br />
classes sont installées dans une base <strong>de</strong> données, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
vous permet <strong>de</strong> les utiliser dans tous les compartiments et toutes les<br />
opérations <strong>de</strong> la base, et d'exécuter leur fonctionnalité (sous forme <strong>de</strong><br />
métho<strong>de</strong>s <strong>de</strong> classe ou d'instance) aussi facilement que vous appelez une<br />
procédure stockée.<br />
Différence entre classes Java et procédures stockées<br />
Les classes Java sont différentes <strong>de</strong>s procédures stockées. Les procédures<br />
stockées sont écrites en SQL ; pour leur part, les classes Java reposent sur<br />
un langage beaucoup plus puissant et peuvent néanmoins être appelées<br />
<strong>de</strong>puis <strong>de</strong>s applications clientes <strong>de</strong> la même manière que les procédures<br />
stockées.<br />
Lorsqu'une classe Java est installée dans une base <strong>de</strong> données, elle est<br />
disponible en tant que domaine. Vous utilisez une classe Java dans les<br />
mêmes circonstances qu'un type <strong>de</strong> données SQL intégré : comme type <strong>de</strong><br />
colonne dans une table ou comme type <strong>de</strong> variable.<br />
59
FAQ concernant Java dans la base <strong>de</strong> données<br />
Accès aux données via Java<br />
60<br />
Par exemple, si une classe nommée Address a été installée dans une base <strong>de</strong><br />
données, la colonne Addr d'une table peut être <strong>de</strong> type Address. Cela<br />
implique que seuls les objets basés sur la classe Address peuvent être<br />
enregistrés comme valeurs <strong>de</strong> ligne dans cette colonne.<br />
$ Pour plus d'informations, reportez-vous à la section "Installation <strong>de</strong><br />
classes Java dans une base <strong>de</strong> données", page 101.<br />
L'interface JDBC est un standard <strong>de</strong> l'industrie spécifiquement développée<br />
pour l'accès aux systèmes <strong>de</strong> base <strong>de</strong> données. Les classes JDBC sont donc<br />
conçues pour permettre la connexion à une base <strong>de</strong> données, la <strong>de</strong>man<strong>de</strong> <strong>de</strong><br />
données via <strong>de</strong>s instructions SQL et le renvoi <strong>de</strong> jeux <strong>de</strong> résultats<br />
exploitables dans l'application cliente.<br />
Normalement, les classes JDBC sont utilisées dans une application cliente et<br />
les constructeurs <strong>de</strong> systèmes <strong>de</strong> base <strong>de</strong> données fournissent un pilote JDBC<br />
permettant aux classes JDBC d'établir une connexion.<br />
La connexion à <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> <strong>de</strong>puis une application cliente via<br />
JDBC est possible à l'ai<strong>de</strong> <strong>de</strong> jConnect ou d'une passerelle JDBC/ODBC.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> propose également un gestionnaire JDBC interne<br />
grâce auquel les classes Java installées dans une base <strong>de</strong> données peuvent<br />
utiliser les classes JDBC qui exécutent <strong>de</strong>s instructions SQL.<br />
$ Pour plus d'informations, reportez-vous à la section "Accès aux données<br />
via JDBC", page 139.<br />
Déplacement <strong>de</strong> classes du client vers le serveur<br />
Vous pouvez créer <strong>de</strong>s classes Java que vous déplacerez au besoin entre les<br />
niveaux d'une application d'entreprise. Une même classe Java peut ainsi être<br />
intégrée dans l'application cliente, à un niveau intermédiaire ou dans la base<br />
<strong>de</strong> données, c'est-à-dire à l'emplacement le plus approprié.<br />
Une classe contenant <strong>de</strong>s règles <strong>de</strong> gestion, <strong>de</strong>s données ou une combinaison<br />
<strong>de</strong>s <strong>de</strong>ux peut être déplacée vers n'importe quel niveau du système<br />
d'entreprise, y compris le serveur ; cette flexibilité permet une utilisation<br />
optimale <strong>de</strong>s ressources. Ainsi, les clients <strong>de</strong> l'entreprise peuvent développer<br />
leurs applications à l'ai<strong>de</strong> d'un langage <strong>de</strong> <strong>programmation</strong> unique, dans une<br />
architecture multiniveaux et en bénéficiant d'une flexibilité incomparable.
Création d'applications distribuées<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Vous pouvez créer une application dont certains éléments fonctionnent dans<br />
la base <strong>de</strong> données et certains autres sur la machine cliente. Vous pouvez<br />
transférer <strong>de</strong>s objets Java du serveur vers le client, tout comme vous<br />
transférez <strong>de</strong>s données SQL telles que <strong>de</strong>s chaînes <strong>de</strong> caractères et <strong>de</strong>s<br />
valeurs numériques.<br />
$ Pour plus d'informations, reportez-vous à la section "Création<br />
d'applications distribuées", page 171.<br />
Opérations impossibles avec Java dans la base <strong>de</strong> données<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est un environnement d'exécution <strong>de</strong>s classes<br />
Java, pas un environnement <strong>de</strong> développement Java.<br />
Vous ne pouvez donc pas exécuter les tâches suivantes dans la base <strong>de</strong><br />
données :<br />
♦ Editer <strong>de</strong>s fichiers source <strong>de</strong> classes (fichiers *.java).<br />
♦ Compiler <strong>de</strong>s fichiers source <strong>de</strong> classes (fichiers *.java).<br />
♦ Exécuter <strong>de</strong>s API Java non supportées, telles que <strong>de</strong>s classes visuelles et<br />
d'applet.<br />
♦ Exécuter <strong>de</strong>s métho<strong>de</strong>s Java qui requièrent l'exécution <strong>de</strong> métho<strong>de</strong>s<br />
natives. Toutes les classes installées dans la base <strong>de</strong> données doivent être<br />
Java à 100 %.<br />
Les classes Java utilisées dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> doivent être<br />
écrites et compilées à l'ai<strong>de</strong> d'un outil <strong>de</strong> développement d'applications Java,<br />
puis installées dans une base <strong>de</strong> données, pour y être utilisées, testées ou<br />
déboguées.<br />
61
Séminaire Java<br />
Séminaire Java<br />
Les classes Java<br />
Exemple<br />
62<br />
Cette section présente les concepts fondamentaux <strong>de</strong> Java. A l'issue <strong>de</strong> cette<br />
section, vous serez capable d'examiner du co<strong>de</strong> Java, par exemple une simple<br />
définition <strong>de</strong> classe ou l'appel d'une métho<strong>de</strong>, et <strong>de</strong> comprendre parfaitement<br />
<strong>de</strong> quoi il s'agit.<br />
Répertoire d'exemples Java<br />
Certaines classes présentées comme exemples dans ce document se<br />
trouvent dans le répertoire d'exemples Java Samples\ASA|Java du<br />
répertoire d'installation <strong>de</strong> SQL <strong>Anywhere</strong>.<br />
Chaque exemple <strong>de</strong> classe Java est constitué <strong>de</strong> <strong>de</strong>ux fichiers : la source<br />
Java et la classe compilée. Vous pouvez immédiatement installer dans une<br />
base <strong>de</strong> données la version compilée <strong>de</strong>s exemples <strong>de</strong> classe Java, sans<br />
aucune modification préalable.<br />
Une classe Java combine <strong>de</strong>s données et <strong>de</strong>s fonctionnalités, à savoir qu'elle<br />
contient <strong>de</strong>s informations et peut exécuter <strong>de</strong>s calculs. Pour bien appréhen<strong>de</strong>r<br />
le concept <strong>de</strong> classe, concevez-la comme une entité, une représentation<br />
abstraite <strong>de</strong> choses.<br />
Par exemple, vous pouvez créer une classe Invoice qui reproduit les factures<br />
papier utilisées tous les jours dans le commerce. Tout comme une facture<br />
papier comprend certaines informations (détail <strong>de</strong>s articles, débiteur, date<br />
d'émission, montant dû et échéance), une instance <strong>de</strong> la classe Invoice peut<br />
contenir ces mêmes informations. Les classes stockent les informations dans<br />
<strong>de</strong>s champs.<br />
Outre la <strong>de</strong>scription <strong>de</strong>s données, une classe peut effectuer <strong>de</strong>s calculs et <strong>de</strong>s<br />
opérations logiques. Par exemple, vous pouvez faire en sorte que la classe<br />
Invoice calcule le montant <strong>de</strong> la taxe due sur les articles et l'ajoute au soustotal<br />
pour donner un total final, sans intervention <strong>de</strong> l'utilisateur. Une telle<br />
classe pourrait même contrôler que la facture finale comprend bien toutes les<br />
informations essentielles, ou encore indiquer le dépassement <strong>de</strong> l'échéance<br />
ou les règlements partiels. Les calculs et autres opérations logiques sont<br />
réalisés par les métho<strong>de</strong>s <strong>de</strong> la classe.<br />
Le co<strong>de</strong> Java ci-<strong>de</strong>ssous déclare une classe nommée Invoice. Cette<br />
déclaration, qui est stockée dans un fichier nommé Invoice.java, peut ensuite<br />
être compilée en classe Java à l'ai<strong>de</strong> d'un compilateur Java.
Sous-classes Java<br />
Les objets Java<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Compilation <strong>de</strong>s classes Java<br />
La compilation d'une source <strong>de</strong> classe Java crée un nouveau fichier<br />
portant le même nom mais avec une autre extension. Ainsi, la compilation<br />
d'Invoice.java crée un fichier nommé Invoice.class qui peut alors être<br />
utilisé dans une application Java et exécuté par une machine virtuelle<br />
Java.<br />
L'outil Sun JDK pour la compilation <strong>de</strong>s déclarations <strong>de</strong> classes est<br />
javac.exe.<br />
public class Invoice {<br />
// Pour l’heure, cette classe ne sait rien et<br />
..// n'exécute rien<br />
}<br />
Le mot-clé class est suivi du nom <strong>de</strong> la classe. La syntaxe comprend une<br />
accola<strong>de</strong> ouverte et une accola<strong>de</strong> fermée. Tous les éléments déclarés entre les<br />
accola<strong>de</strong>s (champs ou métho<strong>de</strong>s) font partie <strong>de</strong> la classe.<br />
En fait, le co<strong>de</strong> Java est uniquement constitué <strong>de</strong> déclarations <strong>de</strong> classes.<br />
Même la procédure Java qu'un interpréteur Java exécute automatiquement<br />
pour créer et gérer d'autres objets (la métho<strong>de</strong> main qui marque souvent le<br />
début <strong>de</strong> votre application) est également placée au sein d'une déclaration <strong>de</strong><br />
classe.<br />
Vous pouvez définir <strong>de</strong>s sous-classes d'autres classes. Une classe qui est une<br />
sous-classe d'une autre classe peut utiliser les champs et les métho<strong>de</strong>s <strong>de</strong> la<br />
classe parent : on parle alors d'héritage. Vous pouvez définir <strong>de</strong>s champs et<br />
<strong>de</strong>s métho<strong>de</strong>s supplémentaires qui s'appliquent uniquement à la sous-classe<br />
et redéfinir la signification <strong>de</strong>s champs et métho<strong>de</strong>s hérités.<br />
Java est un langage à hiérarchie unique, ce qui signifie que toutes les classes<br />
créées ou utilisées héritent au final d'une seule classe. Ainsi, les classes <strong>de</strong><br />
niveau inférieur (situées plus haut dans la hiérarchie) doivent être présentes<br />
avant que les classes <strong>de</strong> niveau supérieur puissent être utilisées. Le jeu <strong>de</strong><br />
classes <strong>de</strong> base requis pour exécuter <strong>de</strong>s applications Java s'appelle l'API<br />
Java ou classes d'exécution Java.<br />
Une classe est un modèle qui définit les capacités d'un objet, tout comme le<br />
formulaire <strong>de</strong> facture indique les informations à mentionner.<br />
63
Séminaire Java<br />
Métho<strong>de</strong>s et<br />
champs<br />
Constructeurs <strong>de</strong> classe<br />
64<br />
Les classes ne contiennent pas d'informations spécifiques sur les objets. En<br />
réalité, votre application crée, ou instancie, <strong>de</strong>s objets, en s'appuyant sur la<br />
classe (modèle) et ce sont ces objets qui contiennent les données ou<br />
exécutent <strong>de</strong>s calculs. L'objet instancié est appelé instance <strong>de</strong> la classe.<br />
Ainsi, un objet Invoice est une instance <strong>de</strong> la classe Invoice. La classe définit<br />
les capacités <strong>de</strong> l'objet, mais l'objet est l'expression <strong>de</strong> la classe, qui confère à<br />
cette <strong>de</strong>rnière sa signification et son utilité.<br />
Dans l'exemple <strong>de</strong> la facture, le formulaire définit le cadre d'action <strong>de</strong> toutes<br />
les factures basées sur ce modèle. Il existe un seul formulaire, mais un<br />
nombre indéfini <strong>de</strong> factures possibles. Le formulaire impose une définition,<br />
mais ce sont les factures qui la concrétisent.<br />
De la même manière, c'est l'objet Invoice qui est créé, qui stocke <strong>de</strong>s<br />
informations, puis qui est lui-même stocké, extrait, modifié, mis à jour, etc.<br />
Tout comme vous pouvez créer <strong>de</strong> nombreuses factures différentes à partir<br />
d'un même modèle, vous pouvez générer <strong>de</strong> nombreux objets distincts à<br />
partir d'une même classe.<br />
Une métho<strong>de</strong> correspond à la partie d'une classe qui produit une action (une<br />
fonction qui exécute un calcul ou interagit avec d'autres objets) pour le<br />
compte <strong>de</strong> la classe. Les métho<strong>de</strong>s acceptent les arguments et peuvent<br />
renvoyer une valeur à la fonction d'appel. Si aucune valeur renvoyée n'est<br />
nécessaire, une métho<strong>de</strong> peut renvoyer void. Les classes peuvent comprendre<br />
un nombre illimité <strong>de</strong> métho<strong>de</strong>s.<br />
Un champ est la partie <strong>de</strong> la classe qui contient les informations. Lorsque<br />
vous créez un objet <strong>de</strong> type classe_Java, ses champs contiennent les valeurs<br />
uniques <strong>de</strong> cet objet.<br />
Vous créez un objet en appelant un constructeur <strong>de</strong> classe. Un constructeur<br />
est une métho<strong>de</strong> qui présente les propriétés suivantes :<br />
♦ Une métho<strong>de</strong> constructeur possè<strong>de</strong> le même nom que la classe mais pas<br />
<strong>de</strong> type <strong>de</strong> données déclarées. Par exemple, un constructeur simple pour<br />
la classe Product serait déclaré comme suit :<br />
Product () {<br />
...co<strong>de</strong> constructeur ici...<br />
}<br />
♦ Si vous ne spécifiez aucune métho<strong>de</strong> constructeur dans votre définition<br />
<strong>de</strong> classe, une métho<strong>de</strong> par défaut fournie par l'objet <strong>de</strong> base Java est<br />
utilisée.
Les champs<br />
Exemples<br />
Les métho<strong>de</strong>s<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
♦ Vous pouvez spécifier plusieurs constructeurs pour chaque classe, avec<br />
différents nombres et types d'arguments. Lorsqu'un constructeur est<br />
appelé, le constructeur qui porte le nombre et le type d'arguments<br />
appropriés est utilisé.<br />
Il existe <strong>de</strong>ux catégories <strong>de</strong> champs Java :<br />
♦ Champs d’instance Chaque objet possè<strong>de</strong> son propre jeu <strong>de</strong> champs<br />
d'instance, créés au même moment que l'objet. Ces champs contiennent<br />
<strong>de</strong>s informations spécifiques sur cette instance. Par exemple, le champ<br />
lineItem1Description <strong>de</strong> la classe Invoice contient la <strong>de</strong>scription d'un<br />
article dans une facture particulière. Vous ne pouvez accé<strong>de</strong>r aux<br />
champs d'instance que par une référence à un objet.<br />
♦ Champs <strong>de</strong> classe Un champ <strong>de</strong> classe contient <strong>de</strong>s informations<br />
indépendantes <strong>de</strong>s instances. Un champ <strong>de</strong> classe est créé lors du<br />
chargement initial <strong>de</strong> la classe et aucune autre instance n'est créée, quel<br />
que soit le nombre d'objets qui le seront. Vous accé<strong>de</strong>z aux champs <strong>de</strong><br />
classe par le nom <strong>de</strong> la classe ou par une référence à l'objet.<br />
Pour déclarer un champ dans une classe, indiquez son type, puis son nom<br />
suivi d'un point-virgule (;). Pour déclarer un champ <strong>de</strong> classe, utilisez le motclé<br />
Java static dans la déclaration. Vous déclarez les champs dans le corps <strong>de</strong><br />
la classe et non dans une métho<strong>de</strong> ; une variable déclarée dans une métho<strong>de</strong><br />
<strong>de</strong>vient partie intégrante <strong>de</strong> la métho<strong>de</strong>, non <strong>de</strong> la classe.<br />
La déclaration ci-après <strong>de</strong> la classe Invoice comporte quatre champs qui<br />
correspon<strong>de</strong>nt à <strong>de</strong>s informations relatives à <strong>de</strong>ux articles pris en compte<br />
dans une facture.<br />
public class Invoice {<br />
// Les champs d'une facture contiennent les données<br />
<strong>de</strong> la facture<br />
public String lineItem1Description;<br />
public int lineItem1Cost;<br />
}<br />
public String lineItem2Description;<br />
public int lineItem2Cost;<br />
Il existe <strong>de</strong>ux catégories <strong>de</strong> métho<strong>de</strong>s Java :<br />
65
Séminaire Java<br />
66<br />
♦ Métho<strong>de</strong>s d'instance Une métho<strong>de</strong> totalSum <strong>de</strong> la classe Invoice, qui<br />
calculerait et ajouterait le montant <strong>de</strong> la taxe, puis renverrait le total <strong>de</strong><br />
tous les coûts, ne se révélerait utile que si elle était appelée en même<br />
temps qu'un objet Invoice qui additionnerait le prix <strong>de</strong>s différents<br />
articles. En effet, le calcul ne peut être exécuté que sur un objet puisque<br />
c'est l'objet qui contient les lignes <strong>de</strong> coût relatives aux articles, et non la<br />
classe.<br />
♦ Métho<strong>de</strong>s <strong>de</strong> classe Ces métho<strong>de</strong>s (ou métho<strong>de</strong>s statiques) peuvent<br />
être appelées sans création préalable d'objet. Seuls les noms <strong>de</strong> la classe<br />
et <strong>de</strong> la métho<strong>de</strong> sont nécessaires pour appeler une métho<strong>de</strong> <strong>de</strong> classe.<br />
Tout comme les métho<strong>de</strong>s d'instance, les métho<strong>de</strong>s <strong>de</strong> classe acceptent<br />
les arguments et renvoient <strong>de</strong>s valeurs. En règle générale, les métho<strong>de</strong>s<br />
<strong>de</strong> classe exécutent une fonction d'utilitaire ou d'information liée à la<br />
fonctionnalité globale <strong>de</strong> la classe.<br />
Les métho<strong>de</strong>s <strong>de</strong> classe n'ont pas accès aux champs d'instance.<br />
Pour déclarer une métho<strong>de</strong>, indiquez le type <strong>de</strong> valeur qu'elle renvoie, son<br />
nom et les paramètres qu'elle accepte. Comme pour la déclaration <strong>de</strong> classe,<br />
le corps <strong>de</strong> la métho<strong>de</strong> (qui contient le co<strong>de</strong>) est placé entre accola<strong>de</strong>s.<br />
public class Invoice {<br />
}<br />
// Champs<br />
public String lineItem1Description;<br />
public double lineItem1Cost;<br />
public String lineItem2Description;<br />
public double lineItem2Cost;<br />
// Une métho<strong>de</strong><br />
public double totalSum() {<br />
double runningsum;<br />
}<br />
runningsum = lineItem1Cost + lineItem2Cost;<br />
runningsum = runningsum * 1.15;<br />
return runningsum;<br />
Une variable nommée runningsum est déclarée dans le corps <strong>de</strong> la métho<strong>de</strong><br />
totalSum. Elle a pour fonction <strong>de</strong> contenir la somme du premier et du<br />
second élément <strong>de</strong> coût. Ce sous-total est ensuite multiplié par 15 % (le taux<br />
<strong>de</strong> la taxe) pour donner le total.
Exemple<br />
Exemple<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
La variable locale (telle qu'elle est appelée dans le corps <strong>de</strong> la métho<strong>de</strong>) est<br />
ensuite renvoyée à la fonction d'appel. Lorsqu'elle est appelée, la métho<strong>de</strong><br />
totalSum renvoie la somme <strong>de</strong>s <strong>de</strong>ux champs d'articles, augmentée du<br />
montant <strong>de</strong> la taxe due sur ces articles.<br />
La métho<strong>de</strong> parseInt <strong>de</strong> la classe java.lang.Integer (fournie avec <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>) est un exemple <strong>de</strong> métho<strong>de</strong> <strong>de</strong> classe. Lorsque vous lui<br />
soumettez une chaîne en argument, la métho<strong>de</strong> parseInt renvoie la version<br />
<strong>de</strong> la chaîne en nombres entiers.<br />
Par exemple, pour la valeur <strong>de</strong> chaîne "1", la métho<strong>de</strong> parseInt renvoie 1 (la<br />
valeur en nombres entiers) sans créer au préalable d'instance <strong>de</strong> la classe<br />
java.lang.Integer, comme l'indique l'extrait <strong>de</strong> co<strong>de</strong> Java ci-<strong>de</strong>ssous.<br />
String num = "1";<br />
int i = java.lang.Integer.parseInt( num );<br />
La version suivante <strong>de</strong> la classe Invoice comprend une métho<strong>de</strong> d'instance et<br />
une métho<strong>de</strong> <strong>de</strong> classe. La métho<strong>de</strong> <strong>de</strong> classe nommée rateOfTaxation<br />
renvoie le taux appliqué par la classe pour calculer le total <strong>de</strong> la facture.<br />
Faire <strong>de</strong> la métho<strong>de</strong> rateOfTaxation une métho<strong>de</strong> <strong>de</strong> classe (plutôt qu'un<br />
champ ou une métho<strong>de</strong> d'instance) présente un avantage puisque les autres<br />
classes et procédures peuvent ensuite utiliser les valeurs qu'elle renvoie sans<br />
avoir à créer au préalable une instance <strong>de</strong> la classe. Seuls les noms <strong>de</strong> la<br />
classe et <strong>de</strong> la métho<strong>de</strong> sont nécessaires pour renvoyer le taux appliqué par<br />
cette classe.<br />
Le fait <strong>de</strong> définir rateofTaxation comme métho<strong>de</strong> à la place d'un champ<br />
permet au développeur d'applications <strong>de</strong> modifier le mo<strong>de</strong> <strong>de</strong> calcul du taux<br />
sans que cela ait d'inci<strong>de</strong>nce sur les objets, applications ou procédures qui<br />
utilisent ses valeurs <strong>de</strong> retour. Dans les versions d'Invoice que nous verrons<br />
par la suite, la valeur renvoyée par la métho<strong>de</strong> <strong>de</strong> classe rateOfTaxation<br />
sera basée sur un calcul bien plus compliqué sans inci<strong>de</strong>nce sur les autres<br />
métho<strong>de</strong>s utilisant cette valeur.<br />
public class Invoice {<br />
// Champs<br />
public String lineItem1Description;<br />
public double lineItem1Cost;<br />
public String lineItem2Description;<br />
public double lineItem2Cost;<br />
67
Séminaire Java<br />
68<br />
}<br />
// Métho<strong>de</strong> d'instance<br />
public double totalSum() {<br />
double runningsum;<br />
double taxfactor = 1 + Invoice.rateOfTaxation();<br />
runningsum = lineItem1Cost + lineItem2Cost;<br />
runningsum = runningsum * taxfactor;<br />
return runningsum;<br />
}<br />
// Métho<strong>de</strong> <strong>de</strong> classe<br />
public static double rateOfTaxation() {<br />
double rate;<br />
rate = .15;<br />
}<br />
return rate;<br />
Langages orientés objet et procéduraux<br />
Java est basé sur<br />
les classes<br />
Si vous êtes plus habitué aux langages procéduraux, tels que C ou les<br />
procédures stockées SQL, qu'aux langages orientés objet, vous trouverez<br />
dans cette section une présentation <strong>de</strong>s similitu<strong>de</strong>s et différences<br />
fondamentales entre ces <strong>de</strong>ux types <strong>de</strong> langages.<br />
Dans Java, la classe est la principale unité structurelle du co<strong>de</strong>.<br />
Une classe Java peut être comparée à un regroupement <strong>de</strong> procédures et <strong>de</strong><br />
variables car elles se rapportent toutes à une catégorie spécifique i<strong>de</strong>ntifiable.<br />
Toutefois, c'est le mo<strong>de</strong> d'utilisation <strong>de</strong>s classes qui distingue les langages<br />
orientés objet <strong>de</strong>s langages procéduraux. Lors <strong>de</strong> son exécution, une<br />
application écrite dans un langage procédural est généralement chargée une<br />
fois dans la mémoire, puis elle soumet un mo<strong>de</strong> prédéfini d'exécution à<br />
l'utilisateur.<br />
Dans les langages orientés objet tels que Java, une classe est utilisée comme<br />
un modèle : une définition <strong>de</strong> l'exécution potentielle du programme.<br />
Plusieurs copies d'une classe peuvent être créées et chargées<br />
dynamiquement, selon les besoins, chaque instance <strong>de</strong> la classe pouvant<br />
contenir ses propres données, valeurs et mo<strong>de</strong> d'exécution. Vous pouvez<br />
exécuter ou agir sur chaque classe chargée, indépendamment <strong>de</strong>s autres<br />
classes en mémoire.
Glossaire Java<br />
Packages<br />
Public et privé<br />
Constructeurs<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Une classe chargée en mémoire pour être exécutée est dite instanciée. Cette<br />
classe instanciée est alors appelée un objet. Il s'agit d'une application dérivée<br />
d'une classe et spécifiquement configurée, <strong>de</strong> sorte qu'elle comporte <strong>de</strong>s<br />
valeurs uniques ou que ses métho<strong>de</strong>s sont exécutées indépendamment <strong>de</strong>s<br />
autres instances <strong>de</strong> la classe.<br />
Les définitions proposées ici soulignent certains aspects <strong>de</strong>s classes Java.<br />
Elles ne visent en aucun cas à proposer une source complète <strong>de</strong><br />
connaissances sur le langage Java, mais elles peuvent être <strong>de</strong> quelque utilité<br />
dans l'utilisation <strong>de</strong>s classes Java dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
$ Pour plus d'informations sur le langage Java, reportez-vous à la<br />
documentation en ligne Thinking in Java, <strong>de</strong> Bruce Eckel, qui est fourni avec<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> dans le fichier Samples\ASA\Java\Tjava.pdf.<br />
Un package est un groupe <strong>de</strong> classes qui ont une catégorie ou un rôle<br />
communs. Un membre d'un package dispose <strong>de</strong> privilèges lui permettant<br />
d'accé<strong>de</strong>r aux métho<strong>de</strong>s et données d'autres membres du package, d'où la<br />
nécessité du modificateur d'accès protected.<br />
Un package est l'équivalent Java d'une bibliothèque. Il s'agit d'un ensemble<br />
<strong>de</strong> classes accessibles via l'instruction import. L'instruction Java suivante<br />
importe la bibliothèque d'utilitaires <strong>de</strong> l'API Java.<br />
import java.util.*<br />
D'ordinaire, les packages sont contenus dans <strong>de</strong>s fichiers JAR, qui ont<br />
l'extension .jar ou .zip.<br />
Un modificateur d'accès détermine la visibilité (mot-clé public, private ou<br />
protected précédant toute déclaration) d'un champ, d'une métho<strong>de</strong> ou d'une<br />
classe pour les autres objets Java.<br />
♦ Une classe, une métho<strong>de</strong> ou un champ public est visible partout.<br />
♦ Une classe, une métho<strong>de</strong> ou un champ private n'est visible que dans les<br />
métho<strong>de</strong>s définies au sein <strong>de</strong> cette classe.<br />
♦ Une métho<strong>de</strong> ou un champ protected est visible pour les métho<strong>de</strong>s<br />
définies au sein <strong>de</strong> cette classe, dans les sous-classes <strong>de</strong> la classe ou dans<br />
d'autres classes du même package.<br />
♦ La visibilité par défaut, ou package, signifie que la métho<strong>de</strong> ou le champ<br />
est visible dans la classe ou par d'autres classes du même package.<br />
Un constructeur est une métho<strong>de</strong> spéciale d'une classe Java qui est appelée<br />
lorsqu'une instance <strong>de</strong> la classe est créée.<br />
69
Séminaire Java<br />
Défragmentation<br />
<strong>de</strong> la mémoire<br />
Interfaces<br />
Traitement <strong>de</strong>s erreurs dans Java<br />
70<br />
Les classes peuvent définir leurs propres constructeurs, y compris <strong>de</strong>s<br />
constructeurs multiples et prioritaires. Ce sont les arguments utilisés dans la<br />
tentative <strong>de</strong> création d'un objet qui déterminent quel constructeur est<br />
employé. En effet, lorsque le type, le nombre et l'ordre <strong>de</strong>s arguments utilisés<br />
pour créer une instance <strong>de</strong> la classe correspon<strong>de</strong>nt à l'un <strong>de</strong>s constructeurs <strong>de</strong><br />
la classe, c'est celui-ci qui est retenu pour créer l'objet.<br />
Une défragmentation <strong>de</strong> la mémoire supprime automatiquement tout objet<br />
auquel ne mène aucune référence, à l'exception <strong>de</strong>s objets stockés en tant que<br />
valeurs dans une table.<br />
Il n'existe pas <strong>de</strong> métho<strong>de</strong> <strong>de</strong>structeur dans Java (comme c'est le cas dans<br />
C++). Les classes Java peuvent définir leur propre métho<strong>de</strong> finalize pour les<br />
opérations d'élimination lorsqu'un objet est supprimé durant une<br />
défragmentation <strong>de</strong> la mémoire.<br />
Les classes Java ne peuvent hériter que d'une seule autre classe. Java fait<br />
appel à <strong>de</strong>s interfaces plutôt qu'à l'héritage multiple. Une classe peut mettre<br />
en oeuvre plusieurs interfaces, chacune définissant un ensemble <strong>de</strong><br />
métho<strong>de</strong>s et <strong>de</strong> profils <strong>de</strong> métho<strong>de</strong>s qui doivent être mis en oeuvre par la<br />
classe pour que celle-ci puisse être compilée.<br />
Une interface définit les métho<strong>de</strong>s et champs statiques que la classe doit<br />
déclarer. La mise en oeuvre <strong>de</strong>s métho<strong>de</strong>s et champs déclarés dans une<br />
interface s'opère au sein <strong>de</strong> la classe qui utilise l'interface. L'interface définit<br />
ce que la classe doit déclarer, mais c'est la classe qui détermine le mo<strong>de</strong> <strong>de</strong><br />
mise en oeuvre.<br />
Le co<strong>de</strong> <strong>de</strong> traitement <strong>de</strong>s erreurs <strong>de</strong> Java est distinct du co<strong>de</strong> <strong>de</strong> traitement<br />
normal.<br />
Les erreurs génèrent un objet Exception représentant l'erreur. C'est ce qu'on<br />
appelle déclencher une exception. Toute exception déclenchée met fin au<br />
programme Java, à moins qu'elle ne soit détectée et gérée <strong>de</strong> la manière<br />
voulue à un certain niveau <strong>de</strong> l'application.<br />
Les classes <strong>de</strong> l'API Java, comme les classes créées par l'utilisateur, peuvent<br />
déclencher <strong>de</strong>s exceptions. En fait, les utilisateurs peuvent créer leurs propres<br />
classes d'exception, qui sont ensuite déclenchées par leurs classes<br />
personnalisées.<br />
En l'absence <strong>de</strong> routine <strong>de</strong> gestion <strong>de</strong>s exceptions dans le corps <strong>de</strong> la<br />
métho<strong>de</strong> où survient l'exception, la recherche d'une routine se poursuit<br />
jusqu'à la pile d'appels. Si la recherche atteint le sommet <strong>de</strong> la pile d'appels<br />
sans avoir trouvé <strong>de</strong> routine, c'est la routine par défaut <strong>de</strong> l'interpréteur Java<br />
exécutant l'application qui est appelée, et le programme est interrompu.
Types d’erreur<br />
dans Java<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, si une instruction SQL appelle une<br />
métho<strong>de</strong> Java et qu'une exception non gérée est déclenchée, alors une erreur<br />
SQL est générée.<br />
Toutes les erreurs survenant dans Java sont dérivées <strong>de</strong> <strong>de</strong>ux types <strong>de</strong> classes<br />
d'erreur : Exception et Error. En règle générale, les erreurs <strong>de</strong> type<br />
Exception sont gérées par le co<strong>de</strong> <strong>de</strong> gestion <strong>de</strong>s erreurs dans le corps <strong>de</strong> la<br />
métho<strong>de</strong>. Les erreurs <strong>de</strong> type Error concernent les erreurs internes et les<br />
erreurs d'épuisement <strong>de</strong>s ressources survenant dans le système d'exécution <strong>de</strong><br />
Java.<br />
Les erreurs <strong>de</strong> la classe Exception sont déclenchées et détectées. Le co<strong>de</strong> <strong>de</strong><br />
gestion <strong>de</strong>s exceptions se caractérise par <strong>de</strong>s blocs <strong>de</strong> co<strong>de</strong> try, catch et<br />
finally.<br />
Un bloc try exécute du co<strong>de</strong> susceptible <strong>de</strong> générer une erreur. Un bloc<br />
catch est un co<strong>de</strong> qui est exécuté si une erreur est générée pendant<br />
l'exécution d'un bloc try.<br />
Un bloc finally définit un bloc <strong>de</strong> co<strong>de</strong> qui est exécuté, qu'une erreur soit<br />
générée et détectée ou non. Il est généralement utilisé pour les opérations<br />
d'élimination et pour le co<strong>de</strong> qui ne peut en aucun cas être omis.<br />
Les erreurs <strong>de</strong> la classe Exception sont <strong>de</strong> <strong>de</strong>ux types : les exceptions<br />
d'exécution et les autres.<br />
Les erreurs générées par le système d'exécution sont <strong>de</strong>s exceptions<br />
implicites dans le sens où il n'est pas nécessaire <strong>de</strong> les gérer explicitement en<br />
tant qu'élément <strong>de</strong> chaque déclaration <strong>de</strong> classe ou <strong>de</strong> métho<strong>de</strong>.<br />
Par exemple, une exception <strong>de</strong> table hors limites peut survenir dès lors que<br />
vous utilisez une table, mais il n'est pas nécessaire que l'erreur figure dans la<br />
déclaration <strong>de</strong> la classe ou <strong>de</strong> la métho<strong>de</strong> qui utilise la table.<br />
Toutes les autres exceptions sont explicites. Si la métho<strong>de</strong> appelée peut<br />
déclencher une erreur, celle-ci doit être explicitement détectée par la classe<br />
utilisant la métho<strong>de</strong> <strong>de</strong> déclenchement d'exceptions, ou bien cette classe doit<br />
explicitement déclencher l'erreur elle-même en i<strong>de</strong>ntifiant, dans sa<br />
déclaration <strong>de</strong> classe, l'exception qu'elle est susceptible <strong>de</strong> générer. D'une<br />
façon générale, les exceptions explicites doivent être explicitement gérées.<br />
Une métho<strong>de</strong> doit déclarer toutes les erreurs explicites qu'elle déclenche, ou<br />
bien détecter toutes les erreurs explicites susceptibles d'être déclenchées.<br />
Les exceptions qui ne relèvent pas <strong>de</strong> l'exécution sont contrôlées au moment<br />
<strong>de</strong> la compilation. Le plus souvent, les exceptions d'exécution sont<br />
provoquées par <strong>de</strong>s erreurs <strong>de</strong> <strong>programmation</strong>. Java détecte bon nombre <strong>de</strong><br />
ces erreurs lors <strong>de</strong> la compilation, avant que le co<strong>de</strong> ne soit exécuté.<br />
71
Séminaire Java<br />
72<br />
Chaque métho<strong>de</strong> Java dispose d'une voie d'exécution <strong>de</strong> substitution, <strong>de</strong> sorte<br />
que toutes les métho<strong>de</strong>s Java sont intégralement exécutées, même si ce n'est<br />
pas toujours <strong>de</strong> la manière normale. Si le type d'erreur déclenché n'est pas<br />
détecté, il est passé à la métho<strong>de</strong> ou au bloc <strong>de</strong> co<strong>de</strong> suivant dans la pile.
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Environnement d'exécution pour Java dans la<br />
base <strong>de</strong> données<br />
Cette section décrit l'environnement d'exécution <strong>Sybase</strong> pour Java, ainsi que<br />
ce qui le distingue d'un environnement d'exécution Java standard.<br />
Versions <strong>de</strong> Java et JDBC supportées<br />
Classes d'exécution Java<br />
La machine virtuelle <strong>Sybase</strong> Java vous offre le choix entre les interfaces <strong>de</strong><br />
<strong>programmation</strong> JDK 1.1, JDK 1.2 et JDK 1.3. Les versions spécifiques<br />
fournies sont JDK 1.1.8 et 1.3.<br />
Entre les versions 1.0 et 1.1 du JDK, plusieurs nouvelles API ont été<br />
introduites. Par ailleurs, certaines sont désormais déconseillées et pourraient<br />
même ne plus être supportées dans les futures versions.<br />
Un fichier <strong>de</strong> classe Java qui utilise l'une <strong>de</strong> ces API génère un avertissement<br />
lorsqu'il est compilé, mais il est néanmoins exécuté sur une machine virtuelle<br />
Java répondant aux standards <strong>de</strong> la version 1.1, comme par exemple la<br />
machine virtuelle <strong>Sybase</strong>.<br />
Le pilote JDBC interne supporte la version 2 <strong>de</strong> JDBC.<br />
$ Pour plus d'informations sur les API JDK supportées, reportez-vous à la<br />
section "Packages Java supportés", page 83 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
$ Pour plus d'informations sur la création d'une base <strong>de</strong> données<br />
supportant Java, reportez-vous à la section "Configuration <strong>de</strong> la base <strong>de</strong><br />
données pour Java", page 95.<br />
Les classes d'exécution Java sont les classes <strong>de</strong> niveau inférieur qui sont<br />
installées pour une base <strong>de</strong> données au moment <strong>de</strong> sa création ou <strong>de</strong> sa<br />
configuration pour Java. Ces classes comprennent un sous-ensemble <strong>de</strong> l'API<br />
Java. Elles font partie du JDK (Java Development Kit) <strong>de</strong> Sun.<br />
Les classes d'exécution offrent une fonctionnalité <strong>de</strong> base à partir <strong>de</strong> laquelle<br />
<strong>de</strong>s applications peuvent être créées. Elles sont toujours disponibles pour les<br />
classes <strong>de</strong> la base <strong>de</strong> données.<br />
Vous pouvez incorporer les classes d'exécution Java dans <strong>de</strong>s classes créées<br />
par l'utilisateur. Elles peuvent soit hériter leur fonctionnalité soit l'utiliser au<br />
sein d'un calcul ou d'une opération dans une métho<strong>de</strong>.<br />
73
Environnement d'exécution pour Java dans la base <strong>de</strong> données<br />
Exemples<br />
Classes définies par l'utilisateur<br />
74<br />
Voici certaines classes d'API Java fournies avec les classes d'exécution Java :<br />
♦ Les types <strong>de</strong> données Java primitifs Tous les types <strong>de</strong> données<br />
primitifs (natifs) en Java ont une classe correspondante. Permettant non<br />
seulement <strong>de</strong> créer <strong>de</strong>s objets <strong>de</strong> ces types, ces classes offrent également<br />
une plus gran<strong>de</strong> fonctionnalité, qui se révèle souvent utile.<br />
Le type <strong>de</strong> données Java int a une classe correspondante :<br />
java.lang.Integer.<br />
♦ Le package utility Le package java.util.* contient un certain nombre <strong>de</strong><br />
classes très utiles, dont la fonctionnalité n'a pas d'équivalent dans les<br />
fonctions SQL disponibles dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Voici quelques-unes <strong>de</strong> ces classes :<br />
♦ Hashtable met en correspondance clés et valeurs.<br />
♦ StringTokenizer décompose une chaîne en mots.<br />
♦ Vector contient une table d'objets dimensionnable dynamiquement.<br />
♦ Stack comprend une pile d'objets <strong>de</strong> type <strong>de</strong>rnier entré, premier<br />
sorti (LIFO).<br />
♦ JDBC pour opérations SQL Le package java.SQL.* contient les<br />
classes dont les objets Java ont besoin pour extraire <strong>de</strong>s données <strong>de</strong> la<br />
base à l'ai<strong>de</strong> d'instructions SQL.<br />
Contrairement aux classes définies par l'utilisateur, les classes d'exécution ne<br />
sont pas stockées dans la base <strong>de</strong> données. Elles sont stockées dans <strong>de</strong>s<br />
fichiers du sous-répertoire java, se trouvant lui-même dans le répertoire<br />
d'installation d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Les classes définies par l'utilisateur sont installées dans une base <strong>de</strong> données<br />
à l'ai<strong>de</strong> <strong>de</strong> l'instruction INSTALL. Une fois installées, elles sont utilisables<br />
par d'autres classes <strong>de</strong> la base <strong>de</strong> données. Si elles sont publiques, elles sont<br />
accessibles à partir <strong>de</strong> SQL en tant que domaines.<br />
$ Pour plus d'informations sur l'installation <strong>de</strong> classes, reportez-vous à la<br />
section "Installation <strong>de</strong> classes Java dans une base <strong>de</strong> données", page 101.<br />
I<strong>de</strong>ntification <strong>de</strong>s métho<strong>de</strong>s et champs Java<br />
Le point dans SQL<br />
Dans les instructions SQL, le point (.) i<strong>de</strong>ntifie les colonnes <strong>de</strong>s tables,<br />
comme dans la requête suivante :
Le point dans Java<br />
Appel <strong>de</strong> métho<strong>de</strong>s<br />
Java <strong>de</strong>puis SQL<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
SELECT employee.emp_id<br />
FROM employee<br />
Le point indique également l'appartenance <strong>de</strong>s objets dans les noms d'objets<br />
qualifiés :<br />
SELECT emp_id<br />
FROM DBA.employee<br />
Dans Java, le point sert d'opérateur pour appeler les métho<strong>de</strong>s ou accé<strong>de</strong>r<br />
aux champs d'une classe ou d'un objet Java. Il sert aussi d'i<strong>de</strong>ntificateur <strong>de</strong>s<br />
noms <strong>de</strong> classes, comme dans le nom <strong>de</strong> classe intégralement qualifié<br />
java.util.Hashtable.<br />
Dans l'extrait <strong>de</strong> co<strong>de</strong> Java ci-après, le point est utilisé comme élément d'un<br />
i<strong>de</strong>ntificateur sur la première ligne <strong>de</strong> co<strong>de</strong>. Sur la secon<strong>de</strong> ligne, il sert<br />
d'opérateur.<br />
java.util.Random rnd = new java.util.Random();<br />
int i = rnd.nextInt();<br />
Dans SQL, l'opérateur point peut être remplacé par le double chevron (>>).<br />
L'opérateur point convient plus à Java mais peut donner lieu à <strong>de</strong>s ambiguïtés<br />
sur les noms SQL existants. Le double chevron (>>) est moins ambigu.<br />
>> dans SQL est différent <strong>de</strong> >> dans Java<br />
Dans les instructions SQL, l'opérateur double chevron convient ; seul<br />
l'opérateur point est utilisé dans Java. Dans une classe Java, le double<br />
chevron n'est pas un substitut <strong>de</strong> l'opérateur point et son rôle <strong>de</strong> décalage<br />
du bit <strong>de</strong> droite a une signification totalement différente.<br />
Par exemple, le batch suivant d'instructions SQL est vali<strong>de</strong> :<br />
CREATE VARIABLE rnd java.util.Random;<br />
SET rnd = NEW java.util.Random();<br />
SELECT rnd>>nextInt();<br />
Le résultat <strong>de</strong> l'instruction SELECT est un entier généré <strong>de</strong> manière aléatoire.<br />
Sur la base <strong>de</strong> la variable créée dans l'exemple <strong>de</strong> co<strong>de</strong> SQL précé<strong>de</strong>nt,<br />
l'instruction SQL suivante présente l'utilisation correcte d'une métho<strong>de</strong> <strong>de</strong><br />
classe :<br />
SELECT java.lang.Math>>abs( rnd>>nextInt() );<br />
75
Environnement d'exécution pour Java dans la base <strong>de</strong> données<br />
Java fait la distinction majuscules/minuscules<br />
Types <strong>de</strong> données<br />
Chaînes en Java et SQL<br />
76<br />
La syntaxe Java fonctionne précisément <strong>de</strong> la manière escomptée et la<br />
syntaxe SQL n'est en rien altérée par la présence <strong>de</strong> classes Java. Cela est<br />
vrai, même si une instruction SQL contient les <strong>de</strong>ux syntaxes, SQL et Java.<br />
Pour anodine qu'elle paraisse, cette information n'en a pas moins<br />
d'importantes implications.<br />
Java fait la distinction majuscules/minuscules. Ainsi, la classe Java FindOut<br />
est totalement différente <strong>de</strong> la classe Findout. SQL ne fait pas la distinction<br />
majuscules/minuscules en ce qui concerne les mots-clés et les i<strong>de</strong>ntificateurs.<br />
Cette distinction majuscules/minuscules que fait Java est préservée même<br />
lorsque Java est imbriqué dans une instruction SQL qui, elle, ne la fait pas.<br />
Les parties Java <strong>de</strong> l'instruction doivent donc respecter la distinction<br />
majuscules/minuscules, tandis que les autres parties peuvent être écrites<br />
indifféremment en majuscules ou en minuscules.<br />
Par exemple, l'instruction SQL suivante est exécutée normalement puisque la<br />
casse <strong>de</strong>s objets, classes et opérateurs Java est respectée, alors même que la<br />
casse du reste <strong>de</strong> l'instruction varie.<br />
SeLeCt java.lang.Math.random();<br />
Une classe Java employée comme type <strong>de</strong> données d'une colonne est utilisée<br />
comme un type <strong>de</strong> données SQL défini par l'utilisateur. Cela étant, elle fait<br />
quand même la distinction majuscules/minuscules. Cette convention évite<br />
toute confusion entre les classes Java distinguées par la casse uniquement.<br />
Dans Java, les littéraux <strong>de</strong> chaîne sont i<strong>de</strong>ntifiés par <strong>de</strong>s guillemets doubles,<br />
comme dans l'extrait <strong>de</strong> co<strong>de</strong> suivant :<br />
String str = "Ceci est une chaîne";<br />
En revanche, dans SQL, les chaînes sont marquées par <strong>de</strong>s guillemets<br />
simples (les guillemets doubles indiquant un i<strong>de</strong>ntificateur), comme dans<br />
l'instruction SQL suivante :<br />
INSERT INTO TABLE DBA.t1<br />
VALUES( ’Bonjour’ )<br />
Utilisez toujours <strong>de</strong>s guillemets doubles dans le co<strong>de</strong> source Java et <strong>de</strong>s<br />
guillemets simples dans les instructions SQL.<br />
Par exemple, les instructions SQL suivantes sont vali<strong>de</strong>s :<br />
CREATE VARIABLE str char(20);<br />
set str = new java.lang.String( ’Nouvel objet’ )
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Et l'extrait <strong>de</strong> co<strong>de</strong> Java suivant est vali<strong>de</strong> également, s'il est utilisé dans une<br />
classe Java :<br />
String str = new java.lang.String(<br />
"Nouvel objet" );<br />
Impression dans la ligne <strong>de</strong> comman<strong>de</strong><br />
Utilisation <strong>de</strong> la métho<strong>de</strong> main<br />
L'impression dans la sortie standard permet <strong>de</strong> contrôler rapi<strong>de</strong>ment les<br />
valeurs <strong>de</strong>s variables et les résultats d'exécution à différents points<br />
d'exécution du co<strong>de</strong>. Lorsque la métho<strong>de</strong> sur la secon<strong>de</strong> ligne <strong>de</strong> l'extrait<br />
suivant <strong>de</strong> co<strong>de</strong> Java arrive à exécution, l'argument <strong>de</strong> chaîne qu'elle accepte<br />
est imprimé dans la sortie standard :<br />
String str = "Bonjour à tous";<br />
System.out.println( str );<br />
Dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, la sortie standard se fait dans la fenêtre du<br />
serveur. L'exécution dans la base <strong>de</strong> données du co<strong>de</strong> Java ci-<strong>de</strong>ssus produit<br />
le même résultat que l'instruction SQL suivante :<br />
MESSAGE 'Bonjour à tous'<br />
Lorsqu'une classe contient une métho<strong>de</strong> main correspondant à la déclaration<br />
<strong>de</strong> métho<strong>de</strong> suivante, elle est automatiquement exécutée par la plupart <strong>de</strong>s<br />
environnements d'exécution Java, notamment l'interpréteur Java Sun.<br />
Normalement, cette métho<strong>de</strong> statique est exécutée uniquement si la classe est<br />
appelée par l'interpréteur Java.<br />
public static void main( String args[ ] ) { }<br />
Cette classe est utile pour tester la fonctionnalité <strong>de</strong>s objets Java ; vous êtes<br />
ainsi assuré que cette métho<strong>de</strong> sera la première appelée lors du démarrage du<br />
système d'exécution Java <strong>de</strong> Sun.<br />
Dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, le système d'exécution Java reste toujours<br />
accessible. La fonctionnalité <strong>de</strong>s objets et métho<strong>de</strong>s peut néanmoins être<br />
testée d'une manière dynamique et adaptée à l'ai<strong>de</strong> d'instructions SQL. A<br />
bien <strong>de</strong>s égards, cette métho<strong>de</strong> se révèle d'ailleurs beaucoup plus flexible.<br />
77
Environnement d'exécution pour Java dans la base <strong>de</strong> données<br />
Portée et durée<br />
78<br />
Les variables SQL ne durent que le temps <strong>de</strong> la connexion. Cette<br />
caractéristique, déjà présente dans les versions précé<strong>de</strong>ntes d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>, reste vraie, que la variable soit une classe Java ou un type <strong>de</strong><br />
données SQL natif.<br />
La durée <strong>de</strong>s classes Java est analogue à celle <strong>de</strong>s tables d'une base <strong>de</strong><br />
données. Dans une base <strong>de</strong> données, les tables existent jusqu'à leur<br />
suppression, qu'elles contiennent <strong>de</strong>s données ou non ou que les données<br />
aient été utilisées ou non. Les classes Java installées dans une base <strong>de</strong><br />
données fonctionnent <strong>de</strong> la même manière : elles sont disponibles tant<br />
qu'elles n'ont pas été explicitement supprimées avec une instruction<br />
REMOVE.<br />
$ Pour plus d'informations sur la suppression <strong>de</strong> classes, reportez-vous à<br />
la section "Instruction REMOVE", page 532 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
Une métho<strong>de</strong> <strong>de</strong> classe installée dans une classe Java peut être appelée à tout<br />
moment, à l'ai<strong>de</strong> d'une instruction SQL. L'instruction suivante peut être<br />
exécutée en n'importe quel point où les instructions SQL sont exécutables :<br />
Select java.lang.Math.abs(-342)<br />
Un objet Java est disponible sous <strong>de</strong>ux formes uniquement : en tant que<br />
valeur d'une variable ou comme valeur d'une table.<br />
Caractères d'échappement Java dans les instructions SQL<br />
En co<strong>de</strong> Java, vous pouvez utiliser <strong>de</strong>s caractères d'échappement pour insérer<br />
certains caractères spéciaux dans <strong>de</strong>s chaînes. L'exemple <strong>de</strong> co<strong>de</strong> ci-après<br />
insère une nouvelle ligne et une tabulation <strong>de</strong>vant une phrase contenant une<br />
apostrophe.<br />
String str = "\n\t\Ceci est le littéral <strong>de</strong> chaîne <strong>de</strong><br />
l\'objet.";<br />
Les caractères d'échappement Java sont autorisés dans <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> uniquement lorsqu'ils sont utilisés par les classes Java. En<br />
revanche, dans SQL, les règles applicables aux chaînes SQL doivent être<br />
observées.<br />
Par exemple, pour transmettre une valeur <strong>de</strong> chaîne à un champ à l'ai<strong>de</strong> d'une<br />
instruction SQL, vous pouvez utiliser l'instruction suivante, mais pas les<br />
caractères d'échappement Java.<br />
set obj.str = '\nCeci est le champ <strong>de</strong> chaîne <strong>de</strong><br />
l''objet';
Conflits <strong>de</strong> mots-clés<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
$ Pour plus d'informations sur les règles <strong>de</strong> gestion <strong>de</strong>s chaînes SQL,<br />
reportez-vous à la section "Chaînes", page 9 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
Des conflits peuvent survenir entre les mots-clés SQL et les noms <strong>de</strong>s classes<br />
Java, y compris les classes d'API. C'est le cas lorsque le nom d'une classe,<br />
par exemple la classe Date qui appartient au package java.util.*, est<br />
référencé. En effet, SQL réserve le mot Date pour l'utiliser comme mot-clé,<br />
alors qu'il est également le nom d'une classe Java.<br />
En cas d'ambiguïté, vous pouvez utiliser <strong>de</strong>s guillemets doubles pour<br />
indiquer que le mot en question n'est pas employé comme mot réservé SQL.<br />
Par exemple, l'instruction SQL suivante provoque une erreur car Date est un<br />
mot-clé dont l'usage est réservé dans SQL :<br />
Utilisation <strong>de</strong>s instructions import<br />
-- Cette instruction est incorrecte<br />
CREATE VARIABLE dt java.util.Date<br />
En revanche, les <strong>de</strong>ux instructions ci-après fonctionnent correctement car le<br />
mot Date est mis entre guillemets doubles :<br />
CREATE VARIABLE dt java.util."Date";<br />
SET dt = NEW java.util."Date"(1997, 11, 22, 16, 11, 01)<br />
La variable dt contient maintenant la date : 22 novembre 1997, 16:11.<br />
Dans une déclaration <strong>de</strong> classe Java, il n'est pas rare d'inclure une instruction<br />
import pour accé<strong>de</strong>r aux classes d'un autre package. Vous pouvez référencer<br />
<strong>de</strong>s classes importées en utilisant <strong>de</strong>s noms <strong>de</strong> classe non qualifiés.<br />
Par exemple, la classe Stack du package java.util peut être référencée <strong>de</strong><br />
<strong>de</strong>ux manières :<br />
♦ soit en utilisant explicitement le nom java.util.Stack ;<br />
♦ soit en utilisant le nom Stack et en ajoutant l'instruction import<br />
suivante :<br />
import java.util.*<br />
79
Environnement d'exécution pour Java dans la base <strong>de</strong> données<br />
Les classes<br />
situées plus haut<br />
dans la hiérarchie<br />
doivent être<br />
installées.<br />
80<br />
Toute classe référencée par une autre classe, soit explicitement à l'ai<strong>de</strong> d'un<br />
nom intégralement qualifié, soit implicitement via une instruction import,<br />
doit aussi être installée dans la base <strong>de</strong> données.<br />
L'instruction import fonctionne <strong>de</strong> la manière voulue dans les classes<br />
compilées. Cependant, dans l'environnement d'exécution <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>, il n'existe pas d'équivalent à l'instruction import. Tous les noms<br />
<strong>de</strong> classe utilisés dans les instructions SQL ou les procédures stockées<br />
doivent donc être intégralement qualifiés. Par exemple, pour créer une<br />
variable <strong>de</strong> type String, la classe est référencée à l'ai<strong>de</strong> du nom intégralement<br />
qualifié : java.lang.String.<br />
Utilisation <strong>de</strong> la variable CLASSPATH<br />
CLASSPATH<br />
ignorée à<br />
l'exécution<br />
Utilisation <strong>de</strong><br />
CLASSPATH pour<br />
installer <strong>de</strong>s<br />
classes<br />
La variable d'environnement CLASSPATH permet à l'environnement<br />
d'exécution Java <strong>de</strong> Sun et au compilateur Java Sun JDK <strong>de</strong> localiser les<br />
classes référencées dans le co<strong>de</strong> Java. Une variable CLASSPATH indique le<br />
lien entre le co<strong>de</strong> Java et le chemin d'accès au fichier ou l'URL <strong>de</strong>s classes<br />
référencées. Par exemple, import java.io.* permet <strong>de</strong> référencer toutes<br />
les classes du package java.io sans nom intégralement qualifié. Pour<br />
exploiter <strong>de</strong>s classes du package java.io, seul le nom <strong>de</strong> la classe est requis<br />
dans le co<strong>de</strong> Java suivant. La variable d'environnement classpath sur le<br />
système où doit être compilée la déclaration <strong>de</strong> classe Java doit indiquer<br />
l'emplacement du répertoire Java, racine du package java.io.<br />
La variable d'environnement CLASSPATH n'a pas d'inci<strong>de</strong>nce sur<br />
l'environnement d'exécution d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> pendant<br />
l'exécution <strong>de</strong>s opérations Java, car les classes sont stockées dans la base <strong>de</strong><br />
données et non dans <strong>de</strong>s fichiers ou <strong>de</strong>s archives externes.<br />
La variable classpath permet néanmoins <strong>de</strong> localiser un fichier pendant<br />
l'installation <strong>de</strong> classes. Par exemple, l'instruction suivante installe dans une<br />
base <strong>de</strong> données une classe Java créée par l'utilisateur en spécifiant<br />
uniquement le nom du fichier, sans son chemin. (Vous noterez que cette<br />
instruction ne comporte aucune opération Java.)<br />
INSTALL JAVA NEW<br />
FROM FILE ’Invoice.class’<br />
Si le fichier se trouve dans un répertoire ou un fichier .zip spécifié par la<br />
variable classpath, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> localise le fichier et installe la<br />
classe.
Champs publics<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Dans la <strong>programmation</strong> orientée objet, les champs <strong>de</strong> classe sont<br />
fréquemment définis comme étant privés et leurs valeurs sont accessibles<br />
uniquement via <strong>de</strong>s métho<strong>de</strong>s publiques.<br />
Bon nombre <strong>de</strong>s exemples <strong>de</strong> la présente documentation concernent <strong>de</strong>s<br />
champs publics, pour <strong>de</strong>s raisons <strong>de</strong> concision et <strong>de</strong> facilité <strong>de</strong> lecture. En<br />
outre, dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, les champs publics offrent <strong>de</strong><br />
meilleures performances que les métho<strong>de</strong>s publiques d'accès.<br />
Dans cette documentation, une classe Java créée par l'utilisateur pour être<br />
utilisée dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> présente, par convention, ses<br />
valeurs principales dans ses champs. Les métho<strong>de</strong>s, quant à elles,<br />
contiennent <strong>de</strong>s éléments <strong>de</strong> logique et d'automatisation du calcul<br />
susceptibles d'agir sur ces champs.<br />
81
Didacticiel : Java dans la base <strong>de</strong> données - Exercice pratique<br />
Didacticiel : Java dans la base <strong>de</strong> données -<br />
Exercice pratique<br />
Configuration<br />
requise<br />
Ressources<br />
82<br />
Ce didacticiel constitue une initiation en matière d'appel d'opérations Java<br />
sur <strong>de</strong>s classes et <strong>de</strong>s objets Java à l'ai<strong>de</strong> d'instructions SQL. Il explique<br />
comment installer une classe Java dans la base <strong>de</strong> données. Il explique<br />
également comment accé<strong>de</strong>r à la classe ainsi qu'à ses membres et ses<br />
métho<strong>de</strong>s à l'ai<strong>de</strong> d'instructions SQL. Ce didacticiel s'appuie sur la classe<br />
Invoice créée dans la section "Séminaire Java", page 62.<br />
Pour suivre ce didacticiel, le logiciel Java dans la base <strong>de</strong> données doit être<br />
installé. Le JDK (Java Development Kit) doit également être installé, y<br />
compris le compilateur Java (javac).<br />
Le co<strong>de</strong> source et les fichiers batch correspondant à cet exemple se trouvent<br />
dans le sous-répertoire Samples\ASA|InvoiceJava du répertoire<br />
SQL <strong>Anywhere</strong>.<br />
Création et compilation d'un exemple <strong>de</strong> classe Java<br />
La première étape consiste à écrire le co<strong>de</strong> Java et à le compiler. Cette<br />
opération est effectuée hors <strong>de</strong> la base <strong>de</strong> données.<br />
v Pour créer et compiler la classe :<br />
1 Créez le fichier Invoice.java contenant le co<strong>de</strong> suivant :
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
public class Invoice {<br />
}<br />
// Champs<br />
public String lineItem1Description;<br />
public double lineItem1Cost;<br />
public String lineItem2Description;<br />
public double lineItem2Cost;<br />
// Métho<strong>de</strong> d'instance<br />
public double totalSum() {<br />
double runningsum;<br />
double taxfactor = 1 + Invoice.rateOfTaxation();<br />
}<br />
runningsum = lineItem1Cost + lineItem2Cost;<br />
runningsum = runningsum * taxfactor;<br />
return runningsum;<br />
// Métho<strong>de</strong> <strong>de</strong> classe<br />
public static double rateOfTaxation() {<br />
double rate;<br />
rate = .15;<br />
}<br />
return rate;<br />
Le co<strong>de</strong> source <strong>de</strong> cette classe se trouve dans le fichier<br />
Samples\ASA|JavaInvoice\Invoice.java, accessible dans le répertoire<br />
SQL <strong>Anywhere</strong>.<br />
2 Compilez le fichier afin <strong>de</strong> générer le fichier Invoice.class.<br />
A partir d'une invite <strong>de</strong> comman<strong>de</strong> dans le même répertoire que celui du<br />
fichier Invoice.java, exécutez la comman<strong>de</strong> suivante :<br />
javac *.java<br />
Installation <strong>de</strong> l’exemple <strong>de</strong> classe Java<br />
La classe est compilée et peut à présent être installée dans la base <strong>de</strong><br />
données.<br />
Vous <strong>de</strong>vez installer les classes Java dans une base <strong>de</strong> données avant <strong>de</strong><br />
pouvoir les utiliser. Vous pouvez installer <strong>de</strong>s classes à partir <strong>de</strong><br />
<strong>Sybase</strong> Central ou d'Interactive SQL. Cette section fournit <strong>de</strong>s instructions<br />
pour les <strong>de</strong>ux mo<strong>de</strong>s d'installation. Choisissez la métho<strong>de</strong> qui vous convient<br />
le mieux.<br />
83
Didacticiel : Java dans la base <strong>de</strong> données - Exercice pratique<br />
Remarques<br />
84<br />
v Pour installer la classe dans la base <strong>de</strong> données exemple à partir <strong>de</strong><br />
<strong>Sybase</strong> Central :<br />
1 Démarrez <strong>Sybase</strong> Central et connectez-vous à la base <strong>de</strong> données<br />
exemple.<br />
2 Ouvrez le dossier Objets Java et double-cliquez sur Ajouter une classe<br />
Java. L'assistant <strong>de</strong> création d'une classe Java s'affiche.<br />
3 Cliquez sur Parcourir, puis recherchez Invoice.class dans le sousrépertoire<br />
Samples\ASA\JavaInvoice du répertoire d'installation <strong>de</strong><br />
SQL <strong>Anywhere</strong>.<br />
4 Cliquez sur Terminer pour quitter l'assistant.<br />
v Pour installer la classe dans la base <strong>de</strong> données exemple à partir<br />
d'Interactive SQL :<br />
1 Démarrez Interactive SQL et connectez-vous à la base <strong>de</strong> données<br />
exemple.<br />
2 Dans le volet Instructions SQL d'Interactive SQL, entrez la comman<strong>de</strong><br />
suivante :<br />
INSTALL JAVA NEW<br />
FROM FILE<br />
’chemin\\samples\\ASA\\JavaInvoice\\Invoice.class’<br />
chemin correspondant au répertoire SQL <strong>Anywhere</strong>.<br />
La classe est à présent installée dans la base <strong>de</strong> données exemple.<br />
♦ A ce sta<strong>de</strong>, aucune opération Java dans la base <strong>de</strong> données n'a encore eu<br />
lieu. La classe a été installée dans la base <strong>de</strong> données et est prête à servir<br />
<strong>de</strong> type <strong>de</strong> données pour une variable ou une colonne dans une table.<br />
♦ Les modifications apportées au fichier <strong>de</strong> la classe à partir <strong>de</strong> ce moment<br />
ne sont pas automatiquement répercutées dans la copie <strong>de</strong> la classe dans<br />
la base <strong>de</strong> données. Vous <strong>de</strong>vez réinstaller les classes pour que les<br />
modifications soient prises en compte.<br />
$ Pour plus d'informations sur l'installation <strong>de</strong> classes et la mise à jour<br />
d'une classe installée, reportez-vous à la section "Installation <strong>de</strong> classes Java<br />
dans une base <strong>de</strong> données", page 101.<br />
Création d'une variable SQL <strong>de</strong> type Invoice<br />
Cette section explique comment créer une variable SQL qui référence un<br />
objet Java <strong>de</strong> type Invoice.
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Distinction majuscules/minuscules<br />
Java faisant la distinction majuscules/minuscules, les parties en Java <strong>de</strong>s<br />
exemples donnés ci-après indiquent précisément la casse requise. La<br />
syntaxe SQL est donnée en majuscules.<br />
1 A partir d'Interactive SQL, exécutez l'instruction ci-après pour créer une<br />
variable SQL nommée Inv <strong>de</strong> type Invoice, Invoice étant la classe Java<br />
que vous avez installée dans la base <strong>de</strong> données.<br />
CREATE VARIABLE Inv Invoice<br />
Une fois créée, la variable ne peut accepter <strong>de</strong> valeur que si son type <strong>de</strong><br />
données et le type <strong>de</strong> données déclaré sont i<strong>de</strong>ntiques ou si la valeur est<br />
une sous-classe du type déclaré. Dans le cas présent, la variable Inv peut<br />
contenir uniquement une référence à un objet <strong>de</strong> type Invoice ou une<br />
sous-classe d'Invoice.<br />
Initialement, la variable Inv est NULL puisque aucune valeur ne lui a<br />
été transmise.<br />
2 Pour i<strong>de</strong>ntifier la valeur courante <strong>de</strong> la variable Inv, exécutez<br />
l'instruction suivante :<br />
select IfNull(Inv,<br />
'Pas <strong>de</strong> référence à un objet',<br />
'Variable not null : contient une référence à un<br />
objet')<br />
A ce sta<strong>de</strong>, la variable ne comporte aucune référence à un objet.<br />
3 Affectez une valeur à Inv.<br />
Vous <strong>de</strong>vez créer une instance <strong>de</strong> la classe Invoice à l'ai<strong>de</strong> du mot-clé<br />
NEW.<br />
SET Inv = NEW Invoice();<br />
La variable Inv comporte désormais une référence à un objet Java. Pour<br />
le vérifier, vous pouvez exécuter l'instruction à partir <strong>de</strong> l'étape 2.<br />
La variable Inv contient une référence à un objet Java <strong>de</strong> type Invoice.<br />
Avec cette référence, vous pouvez maintenant accé<strong>de</strong>r à tous les champs<br />
<strong>de</strong> l'objet et appeler ses métho<strong>de</strong>s.<br />
Accès aux champs et aux métho<strong>de</strong>s <strong>de</strong> l'objet Java<br />
Si une variable (ou la valeur d’une colonne dans une table) contient une<br />
référence à un objet Java, <strong>de</strong>s valeurs peuvent être transmises aux champs <strong>de</strong><br />
l'objet et ses métho<strong>de</strong>s peuvent être appelées.<br />
85
Didacticiel : Java dans la base <strong>de</strong> données - Exercice pratique<br />
Métho<strong>de</strong>s d'appel<br />
et champs qui<br />
référencent<br />
86<br />
Par exemple, la variable <strong>de</strong> type Invoice que vous avez créée dans la section<br />
précé<strong>de</strong>nte contient une référence à un objet Invoice et comporte quatre<br />
champs dont la valeur peut être définie via <strong>de</strong>s instructions SQL.<br />
v Pour accé<strong>de</strong>r aux champs <strong>de</strong> l'objet Invoice :<br />
1 A partir d’Interactive SQL, exécutez les instructions SQL ci-après afin<br />
<strong>de</strong> définir les valeurs <strong>de</strong>s champs <strong>de</strong> la variable Inv.<br />
SET Inv.lineItem1Description = ’Work boots’;<br />
SET Inv.lineItem1Cost = ’79.99’;<br />
SET Inv.lineItem2Description = ’Hay fork’;<br />
SET Inv.lineItem2Cost = ’37.49’;<br />
Chaque instruction SQL transmet une valeur à un champ dans<br />
l'objet Java référencé par Inv.<br />
2 Exécutez les instructions SELECT sur la variable. Chacune <strong>de</strong>s<br />
instructions SQL suivantes renvoie ainsi la valeur courante d'un champ<br />
<strong>de</strong> l'objet Java référencé par Inv.<br />
SELECT Inv.lineItem1Description;<br />
SELECT Inv.lineItem1Cost;<br />
SELECT Inv.lineItem2Description;<br />
SELECT Inv.lineItem2Cost;<br />
3 Utilisez un champ <strong>de</strong> la variable Inv dans une expression SQL.<br />
Exécutez l'instruction SQL suivante et assurez-vous d'avoir exécuté les<br />
instructions SQL mentionnées précé<strong>de</strong>mment.<br />
SELECT * FROM PRODUCT<br />
WHERE unit_price < Inv.lineItem2Cost;<br />
Disposant non seulement <strong>de</strong> champs publics, la classe Invoice comporte<br />
également une métho<strong>de</strong> d'instance que vous pouvez appeler.<br />
v Pour appeler les métho<strong>de</strong>s <strong>de</strong> l'objet Invoice :<br />
♦ A partir d’Interactive SQL, exécutez l'instruction SQL suivante qui<br />
appelle la métho<strong>de</strong> totalSum() <strong>de</strong> l'objet référencé par la variable Inv.<br />
Elle renvoie la somme <strong>de</strong>s <strong>de</strong>ux champs <strong>de</strong> coût augmentée du montant<br />
<strong>de</strong> la taxe perçue sur cette somme.<br />
SELECT Inv.totalSum();<br />
Les noms <strong>de</strong> métho<strong>de</strong> sont toujours suivis <strong>de</strong> parenthèses, même s'ils ne<br />
prennent pas d'argument. Les noms <strong>de</strong> champ ne sont pas suivis <strong>de</strong><br />
parenthèses.
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
La métho<strong>de</strong> totalSum() ne prend aucun argument, mais renvoie une valeur.<br />
Les parenthèses sont employées même si la métho<strong>de</strong> ne prend aucun<br />
argument dans la mesure où une opération Java est appelée.<br />
Pour Java dans la base <strong>de</strong> données, l'accès direct à un champ est plus rapi<strong>de</strong><br />
que l'appel d'une métho<strong>de</strong>. L'accès à un champ ne requiert pas l'appel <strong>de</strong> la<br />
machine virtuelle Java, alors que l'appel d'une métho<strong>de</strong> exige que la machine<br />
virtuelle exécute la métho<strong>de</strong>.<br />
Comme indiqué dans la définition <strong>de</strong> la classe Invoice donnée au début <strong>de</strong><br />
cette section, la métho<strong>de</strong> d'instance totalSum utilise la métho<strong>de</strong> <strong>de</strong> classe<br />
rateOfTaxation.<br />
Cette métho<strong>de</strong> est accessible directement <strong>de</strong>puis une instruction SQL.<br />
SELECT Invoice.rateOfTaxation();<br />
Vous noterez que c'est le nom <strong>de</strong> la classe qui est utilisé et pas le nom d'une<br />
variable contenant une référence à un objet Invoice. Cette approche est<br />
conforme à la manière dont Java gère les métho<strong>de</strong>s <strong>de</strong> classe, alors même<br />
qu'il s'agit ici d'une instruction SQL. Une métho<strong>de</strong> <strong>de</strong> classe peut être<br />
appelée même si aucun objet basé sur cette classe n'a été instancié.<br />
Ainsi, les métho<strong>de</strong>s <strong>de</strong> classe ne nécessitent pas d'instance <strong>de</strong> la classe pour<br />
opérer correctement, mais elles peuvent néanmoins être appelées sur un<br />
objet. L'instruction SQL suivante produit les mêmes résultats que celle<br />
précé<strong>de</strong>mment exécutée.<br />
SELECT Inv.rateOfTaxation();<br />
Enregistrement d’objets Java dans <strong>de</strong>s tables<br />
Lorsqu'une classe Java est installée dans une base <strong>de</strong> données, elle est<br />
disponible en tant que nouveau type <strong>de</strong> données. Les colonnes d'une table<br />
peuvent être du type classe_Java, qui correspond au nom d'une classe Java<br />
publique installée. Vous pouvez ensuite créer un objet Java et l'ajouter à une<br />
table en tant que valeur d'une colonne.<br />
v Pour utiliser la classe Invoice dans une table :<br />
1 Créez une table avec une colonne <strong>de</strong> type Invoice.<br />
A partir d'Interactive SQL, exécutez l'instruction SQL suivante :<br />
CREATE TABLE T1 (<br />
ID int,<br />
JCol Invoice<br />
);<br />
87
Didacticiel : Java dans la base <strong>de</strong> données - Exercice pratique<br />
88<br />
La colonne JCol accepte uniquement <strong>de</strong>s objets <strong>de</strong> type Invoice ou<br />
d’une <strong>de</strong> ses sous-classes.<br />
2 A l’ai<strong>de</strong> <strong>de</strong> la variable Inv qui contient une référence à un objet Java <strong>de</strong><br />
type Invoice, exécutez l'instruction SQL suivante pour ajouter une ligne<br />
à la table T1.<br />
INSERT INTO T1<br />
VALUES( 1, Inv );<br />
Une fois que vous avez ajouté un objet dans la table T1, vous pouvez<br />
exécuter <strong>de</strong>s instructions select qui appellent les champs et les métho<strong>de</strong>s<br />
<strong>de</strong>s objets <strong>de</strong> la table.<br />
3 Par exemple, l'instruction SQL suivante renvoie la valeur du champ<br />
lineItem1Description <strong>de</strong> tous les objets <strong>de</strong> la table T1 (à ce sta<strong>de</strong>, la<br />
table ne doit contenir qu'un seul objet).<br />
SELECT ID, JCol.lineItem1Description<br />
FROM T1;<br />
Vous pouvez exécuter <strong>de</strong>s instructions SELECT similaires qui appellent<br />
d'autres champs et métho<strong>de</strong>s <strong>de</strong> l'objet.<br />
4 La secon<strong>de</strong> métho<strong>de</strong> pour créer un objet Java et l'ajouter à une table fait<br />
appel à l'expression suivante, qui crée automatiquement un objet Java et<br />
renvoie une référence s'y rapportant.<br />
NEW Javaclassname()<br />
5 Cette expression peut être utilisée <strong>de</strong> plusieurs manières. Par exemple,<br />
exécutez l'instruction SQL suivante pour créer un objet Java et l'insérer<br />
dans la table T1 :<br />
INSERT INTO T1<br />
VALUES ( 2, NEW Invoice() );<br />
6 Exécutez l'instruction SQL suivante pour vérifier que ces <strong>de</strong>ux objets ont<br />
bien été enregistrés en tant que valeurs <strong>de</strong> la colonne JCol dans la table<br />
T1.<br />
select id, JCol.totalSum()<br />
FROM t1<br />
Le résultat <strong>de</strong> la colonne JCol (la <strong>de</strong>uxième ligne renvoyée par<br />
l'instruction ci-<strong>de</strong>ssus) doit être 0, parce que les champs <strong>de</strong> cet objet<br />
n'ont pas <strong>de</strong> valeur et que la métho<strong>de</strong> totalSum opère un calcul<br />
arithmétique sur ces champs.
Renvoi d'un objet à l'ai<strong>de</strong> d'une requête<br />
Chapitre 3 Présentation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Outre l'accès aux champs et aux métho<strong>de</strong>s, vous pouvez également récupérer<br />
un objet entier d'une table à l'ai<strong>de</strong> d'une requête.<br />
v Pour accé<strong>de</strong>r aux objets Invoice stockés dans une table :<br />
♦ A partir d’Interactive SQL, exécutez la série d'instructions ci-après pour<br />
créer une nouvelle variable et transmettre une valeur (elle ne peut<br />
contenir qu'une référence à un objet <strong>de</strong> type Invoice). La référence à un<br />
objet transmise à la variable a été générée à l'ai<strong>de</strong> <strong>de</strong> la table T1.<br />
CREATE VARIABLE Inv2 Invoice;<br />
set Inv2 = (select JCol from T1 where ID = 2);<br />
SET Inv2.lineItem1Description = ’Sweet feed’;<br />
SET Inv2.lineItem2Description = ’Drive belt’;<br />
La valeur <strong>de</strong>s champs lineItem1Description et lineItem2Description a<br />
été modifiée dans la variable Inv2, mais pas dans la table d'où provient<br />
la valeur <strong>de</strong> cette variable.<br />
Ce fonctionnement est cohérent avec le mo<strong>de</strong> <strong>de</strong> traitement courant <strong>de</strong>s<br />
variables SQL : la variable Inv comporte une référence à un objet Java.<br />
La valeur indiquée dans la table source <strong>de</strong> la référence <strong>de</strong> la variable<br />
n'est modifiée qu'après l'exécution d'une instruction UPDATE.<br />
89
Didacticiel : Java dans la base <strong>de</strong> données - Exercice pratique<br />
90
CHAPITRE 4<br />
Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Présentation<br />
Sommaire<br />
Avant <strong>de</strong><br />
commencer<br />
Ce chapitre explique comment ajouter <strong>de</strong>s classes et <strong>de</strong>s objets Java à la base<br />
<strong>de</strong> données, et comment utiliser ces objets dans une base <strong>de</strong> données<br />
relationnelle.<br />
Sujet Page<br />
Introduction 92<br />
Configuration <strong>de</strong> la base <strong>de</strong> données pour Java 95<br />
Installation <strong>de</strong> classes Java dans une base <strong>de</strong> données 101<br />
Création <strong>de</strong> colonnes d'objets Java 106<br />
Insertion, mise à jour et suppression d'objets Java 108<br />
Recherche d'objets Java 114<br />
Comparaison <strong>de</strong>s champs et <strong>de</strong>s objets Java 116<br />
Fonctionnalités spéciales <strong>de</strong>s classes Java dans la base <strong>de</strong> données 120<br />
Stockage <strong>de</strong>s objets Java 127<br />
Conception d'une base <strong>de</strong> données Java 130<br />
Utilisation <strong>de</strong> colonnes calculées avec les classes Java 134<br />
Configuration <strong>de</strong> la mémoire pour Java 137<br />
Pour utiliser les exemples fournis dans ce chapitre, commencez par exécuter<br />
le fichier Samples\ASA\Java\j<strong>de</strong>mo.sql du répertoire SQL <strong>Anywhere</strong>.<br />
$ Pour obtenir plus d'informations et <strong>de</strong>s instructions complètes, reportezvous<br />
aux exemples <strong>de</strong> la section "Installation <strong>de</strong>s exemples Java", page 92.<br />
91
Introduction<br />
Introduction<br />
Installation <strong>de</strong>s exemples Java<br />
92<br />
Ce chapitre explique comment accomplir <strong>de</strong>s tâches en utilisant Java dans la<br />
base <strong>de</strong> données, notamment :<br />
♦ Comment configurer une base <strong>de</strong> données pour Java Vous <strong>de</strong>vez<br />
accomplir plusieurs tâches pour préparer la base <strong>de</strong> données à<br />
l'utilisation <strong>de</strong> Java.<br />
♦ Installation <strong>de</strong> classes Java Vous <strong>de</strong>vez installer <strong>de</strong>s classes Java dans<br />
une base <strong>de</strong> données pour qu'elles soient disponibles sur le serveur.<br />
♦ Propriétés <strong>de</strong>s colonnes Java Cette section explique comment les<br />
colonnes contenant <strong>de</strong>s types <strong>de</strong> données <strong>de</strong> classe Java se placent dans<br />
un modèle relationnel.<br />
♦ Conception d'une base <strong>de</strong> données Java Cette section donne <strong>de</strong>s<br />
conseils pour créer <strong>de</strong>s bases <strong>de</strong> données utilisant <strong>de</strong>s classes Java.<br />
La plupart <strong>de</strong>s exemples figurant dans ce chapitre utilise un ensemble <strong>de</strong><br />
classes et <strong>de</strong> tables ajouté dans la base <strong>de</strong> données exemple. Les tables<br />
présentées contiennent les mêmes informations que celles figurant sous le<br />
même nom dans la base <strong>de</strong> données exemple mais l'ID utilisateur <strong>de</strong> leur<br />
propriétaire est jdba. Ces tables utilisent les types <strong>de</strong> données <strong>de</strong> classe Java<br />
plutôt que <strong>de</strong>s données relationnelles simples pour gérer les<br />
informations.Vous trouverez l'exemple dans le sous-répertoire<br />
Samples\ASA\Java du répertoire SQL <strong>Anywhere</strong>.<br />
Les tables exemple ont une vocation didactique uniquement<br />
Les tables exemple servent à illustrer les différentes fonctionnalités Java.<br />
Elles ne doivent pas être considérées comme une métho<strong>de</strong> à suivre pour<br />
reconcevoir la base <strong>de</strong> données. Vous <strong>de</strong>vez choisir les types <strong>de</strong> données<br />
et autres fonctionnalités Java en fonction <strong>de</strong> votre cas particulier<br />
L'installation <strong>de</strong>s exemples Java s'effectue en <strong>de</strong>ux étapes :<br />
1 Configurez la base <strong>de</strong> données exemple pour Java.<br />
2 Ajoutez les exemples <strong>de</strong> classes et <strong>de</strong> tables Java.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
v Pour configurer la base <strong>de</strong> données exemple pour Java :<br />
1 Démarrez Interactive SQL et connectez-vous à la base <strong>de</strong> données<br />
exemple.<br />
2 Dans le volet Instructions SQL d'Interactive SQL, entrez l'instruction<br />
suivante :<br />
ALTER DATABASE UPGRADE JAVA JDK ’1.3’<br />
3 Arrêtez Interactive SQL et la base <strong>de</strong> données exemple.<br />
Vous <strong>de</strong>vez arrêter la base <strong>de</strong> données asa<strong>de</strong>mo.db avant <strong>de</strong> pouvoir<br />
utiliser les fonctionnalités Java.<br />
v Pour ajouter <strong>de</strong>s tables et <strong>de</strong>s classes Java dans la base <strong>de</strong><br />
données exemple :<br />
1 Démarrez Interactive SQL et connectez-vous à la base <strong>de</strong> données<br />
exemple.<br />
2 Dans le volet Instructions SQL d'Interactive SQL, entrez l'instruction<br />
suivante :<br />
READ "chemin\\Samples\\ASA\\Java\\j<strong>de</strong>mo.sql"<br />
chemin correspondant au répertoire SQL <strong>Anywhere</strong>. Cette opération<br />
exécute les instructions du fichier <strong>de</strong> comman<strong>de</strong>s j<strong>de</strong>mo.sql. Cette<br />
exécution peut prendre un certain temps.<br />
Vous pouvez visualiser le script Samples\ASA\Java\j<strong>de</strong>mo.sql à l'ai<strong>de</strong> d'un<br />
éditeur <strong>de</strong> texte. Le script exécute les tâches suivantes :<br />
1 Installation <strong>de</strong> la classe JDBCExamples.<br />
2 Création <strong>de</strong> l'ID utilisateur JDBA auquel sont associés le mot <strong>de</strong> passe<br />
SQL et les droits DBA, et affectation <strong>de</strong> l'ID JDBA à l'utilisateur courant.<br />
3 Installation du fichier JAR asa<strong>de</strong>mo.jar. Ce fichier contient les<br />
définitions <strong>de</strong> classe utilisées dans les tables.<br />
4 Création, sous l'ID utilisateur JDBA, <strong>de</strong>s tables suivantes :<br />
♦ product<br />
♦ contact<br />
♦ customer<br />
♦ employee<br />
♦ sales_or<strong>de</strong>r<br />
♦ sales_or<strong>de</strong>r_items<br />
93
Introduction<br />
94<br />
Le tout forme un sous-ensemble <strong>de</strong>s tables <strong>de</strong> la base <strong>de</strong> données<br />
exemple.<br />
5 Insertion dans les tables Java <strong>de</strong>s données <strong>de</strong>s tables standard portant le<br />
même nom. Cette étape fait appel aux instructions INSERT à partir <strong>de</strong><br />
SELECT. Elle peut prendre un certain temps.<br />
6 Création d'in<strong>de</strong>x et <strong>de</strong> clés étrangères pour ajouter au schéma <strong>de</strong>s<br />
contraintes d'intégrité.<br />
Gestion <strong>de</strong> l'environnement d'exécution pour Java<br />
Tâches <strong>de</strong> gestion<br />
pour Java<br />
Outils <strong>de</strong> gestion<br />
pour Java<br />
L'environnement d'exécution <strong>de</strong> Java est le suivant :<br />
♦ La machine virtuelle Java (JVM) <strong>de</strong> <strong>Sybase</strong> Exécutée sur le serveur <strong>de</strong><br />
la base <strong>de</strong> données, la JVM interprète et exécute les fichiers <strong>de</strong> classe<br />
Java compilés.<br />
♦ Les classes Java d'exécution Lorsque vous créez une base <strong>de</strong><br />
données, un ensemble <strong>de</strong> classes Java <strong>de</strong>vient disponible pour la base.<br />
Les applications Java dans la base <strong>de</strong> données ont besoin <strong>de</strong> ces classes<br />
d'exécution pour fonctionner correctement.<br />
Pour fournir un environnement d'exécution à Java, exécutez les tâches<br />
suivantes :<br />
♦ Configuration <strong>de</strong> la base <strong>de</strong> données pour Java Cette tâche consiste à<br />
garantir la disponibilité <strong>de</strong>s classes intégrées et la mise au niveau <strong>de</strong> la<br />
base <strong>de</strong> données aux normes <strong>de</strong> la version 8.<br />
$ Pour plus d'informations, reportez-vous à la section "Configuration<br />
<strong>de</strong> la base <strong>de</strong> données pour Java", page 95.<br />
♦ Installation <strong>de</strong>s classes nécessaires aux utilisateurs Cette tâche<br />
consiste à s'assurer que les classes qui ne sont pas <strong>de</strong>s classes<br />
d'exécution sont installées et à jour.<br />
$ Pour plus d'informations, reportez-vous à la section "Installation <strong>de</strong><br />
classes Java dans une base <strong>de</strong> données", page 101.<br />
♦ Configuration du serveur Configurez le serveur <strong>de</strong> façon à disposer <strong>de</strong><br />
suffisamment <strong>de</strong> mémoire pour exécuter les tâches Java.<br />
$ Pour plus d'informations, reportez-vous à la section "Configuration<br />
<strong>de</strong> la mémoire pour Java", page 137.<br />
Toutes ces tâches peuvent être exécutées à partir <strong>de</strong> <strong>Sybase</strong> Central ou<br />
d'Interactive SQL.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Configuration <strong>de</strong> la base <strong>de</strong> données pour Java<br />
Contre-indications<br />
L'environnement d'exécution d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> pour Java doit<br />
comporter une JVM ainsi que les classes d'exécution Java <strong>de</strong> <strong>Sybase</strong>. Vous<br />
<strong>de</strong>vez configurer une base <strong>de</strong> données pour Java afin <strong>de</strong> pouvoir utiliser les<br />
classes d'exécution Java.<br />
Java dans la base <strong>de</strong> données est un composant <strong>de</strong> SQL <strong>Anywhere</strong> Studio<br />
faisant l'objet d'une licence séparée.<br />
Les nouvelles bases <strong>de</strong> données sont par défaut non configurées<br />
pour Java<br />
Lorsque vous créez une base <strong>de</strong> données avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>,<br />
la base n'est, par défaut, pas configurée pour Java.<br />
Java est un langage à hiérarchie unique, ce qui signifie que toutes les classes<br />
créées ou utilisées ne peuvent hériter que d'une classe (et une seule). Ainsi,<br />
les classes <strong>de</strong> niveau inférieur (situées plus haut dans la hiérarchie) doivent<br />
être présentes pour que les classes <strong>de</strong> niveau supérieur puissent être utilisées.<br />
Le jeu <strong>de</strong> classes <strong>de</strong> base requis pour exécuter <strong>de</strong>s applications Java s'appelle<br />
API Java ou classes d'exécution Java.<br />
La configuration d'une base <strong>de</strong> données pour Java crée <strong>de</strong> nombreuses<br />
entrées supplémentaires dans les tables système. Par conséquent, la base <strong>de</strong><br />
données occupe davantage d'espace et son exécution requiert environ 200 ko<br />
<strong>de</strong> mémoire supplémentaire, même si vous n'utilisez pas les fonctionnalités<br />
Java.<br />
Si vous n'envisagez pas d'utiliser Java prochainement et que votre<br />
environnement d'exécution est limité en mémoire, il est préférable <strong>de</strong> ne pas<br />
effectuer la configuration pour Java.<br />
Les classes d'exécution Java <strong>de</strong> <strong>Sybase</strong><br />
Les classes d'exécution Java <strong>de</strong> <strong>Sybase</strong> sont stockées sur le disque et non<br />
dans la base <strong>de</strong> données, comme les autres classes. Les classes d'exécution<br />
Java <strong>de</strong> <strong>Sybase</strong> sont stockées dans les suivants fichiers. Ces fichiers se<br />
trouvent dans le sous-répertoire Java du répertoire SQL <strong>Anywhere</strong> :<br />
♦ 1.1\classes.zip Sous licence Sun Microsystems, ce fichier contient un<br />
sous-ensemble <strong>de</strong>s classes d'exécution Java <strong>de</strong> Sun Microsystem pour<br />
JDK 1.1.8.<br />
95
Configuration <strong>de</strong> la base <strong>de</strong> données pour Java<br />
Les fichiers JAR<br />
Packages installés<br />
96<br />
♦ 1.3\rt.jar Sous licence Sun Microsystems, ce fichier contient un sousensemble<br />
<strong>de</strong>s classes d'exécution Java <strong>de</strong> Sun Microsystems pour<br />
JDK 1.3.<br />
♦ asajdbc.zip Ce fichier contient les classes du gestionnaire JDBC interne<br />
<strong>de</strong> <strong>Sybase</strong> pour JDK 1.1.<br />
♦ asajrt12.zip Ce fichier contient les classes du gestionnaire JDBC interne<br />
<strong>de</strong> <strong>Sybase</strong> pour JDK 1.2 et JDK 1.3.<br />
Lorsque vous configurez une base <strong>de</strong> données pour Java, vous mettez aussi à<br />
jour les tables système avec la liste <strong>de</strong>s classes disponibles dans les fichiers<br />
système JAR. Cela vous permet <strong>de</strong> parcourir la hiérarchie <strong>de</strong>s classes <strong>de</strong>puis<br />
<strong>Sybase</strong> Central bien que les classes ne se trouvent pas dans la base <strong>de</strong><br />
données.<br />
Les noms <strong>de</strong>s classes d'exécution sont enregistrés dans la base <strong>de</strong> données,<br />
dans les fichiers JAR suivants :<br />
♦ ASAJRT Les noms <strong>de</strong>s classes issus du fichier asajdbc.zip sont stockés<br />
ici.<br />
♦ ASAJDBCDRV Les noms <strong>de</strong>s classes issus du fichier jdbcdrv.zip sont<br />
stockés ici.<br />
♦ ASASystem Les noms <strong>de</strong>s classes issus du fichier classes.zip sont<br />
stockés ici.<br />
Ces classes d'exécution incluent les packages suivants :<br />
♦ java Ces packages sont les classes d'exécution Java <strong>de</strong> Sun<br />
Microsystems supportées.<br />
$ Pour une liste complète <strong>de</strong>s API Java reconnues, reportez-vous à la<br />
section "Packages Java supportés", page 83 du document ASA Manuel<br />
<strong>de</strong> référence SQL.<br />
♦ com.sybase Ces packages fournissent le support JDBC côté serveur.<br />
♦ sun Ces packages sont fournis par Sun Microsystems.<br />
♦ sybase.sql Ces packages font partie du support JDBC côté serveur <strong>de</strong><br />
<strong>Sybase</strong>.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Avertissement : Ne pas installer <strong>de</strong> classes provenant d’une autre<br />
version du JDK <strong>de</strong> Sun<br />
Certaines classes du kit JDK <strong>de</strong> Sun portent le même nom que les classes<br />
d'exécution Java <strong>de</strong> <strong>Sybase</strong> qui doivent être installées dans une base <strong>de</strong><br />
données pour exécuter <strong>de</strong>s opérations Java.<br />
Ne remplacez pas le fichier classes.zip qui se trouve dans <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>. L'utilisation d'une autre version <strong>de</strong> ces classes peut entraîner<br />
<strong>de</strong>s problèmes <strong>de</strong> compatibilité avec la machine virtuelle Java <strong>de</strong> <strong>Sybase</strong>.<br />
Pour configurer une base <strong>de</strong> données pour Java, utilisez uniquement les<br />
données dans cette section.<br />
Métho<strong>de</strong>s <strong>de</strong> configuration pour Java<br />
Création <strong>de</strong>s bases<br />
<strong>de</strong> données<br />
Mise à niveau <strong>de</strong>s<br />
bases <strong>de</strong> données<br />
Les bases <strong>de</strong> données peuvent être configurées pour Java lors <strong>de</strong> leur<br />
création, <strong>de</strong> leur mise à niveau ou à tout autre moment par une opération<br />
distincte.<br />
Il y a plusieurs façons <strong>de</strong> créer une base <strong>de</strong> données configurée pour Java :<br />
♦ A l'ai<strong>de</strong> <strong>de</strong> l'instruction CREATE DATABASE.<br />
$ Pour la syntaxe à utiliser, reportez-vous à la section "Instruction<br />
CREATE DATABASE", page 289 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
♦ A l’ai<strong>de</strong> <strong>de</strong> l’utilitaire dbinit.<br />
$ Pour plus d'informations, reportez-vous à la section "Création<br />
d'une base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> l'utilitaire dbinit", page 502 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
♦ A l'ai<strong>de</strong> <strong>de</strong> <strong>Sybase</strong> Central.<br />
$ Pour plus d'informations, reportez-vous à la section "Création<br />
d'une base <strong>de</strong> données", page 29 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur<br />
SQL.<br />
Il existe différentes métho<strong>de</strong>s pour mettre à niveau une base <strong>de</strong> données<br />
configurée pour Java en la faisant évoluer <strong>de</strong> la version 5 à la version 8,<br />
comme suit :<br />
♦ A l'ai<strong>de</strong> <strong>de</strong> l'instruction ALTER DATABASE.<br />
$ Pour la syntaxe à utiliser, reportez-vous à la section "Instruction<br />
ALTER DATABASE", page 216 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
97
Configuration <strong>de</strong> la base <strong>de</strong> données pour Java<br />
98<br />
♦ A l'ai<strong>de</strong> <strong>de</strong> l'utilitaire <strong>de</strong> mise à niveau dbupgrad.exe.<br />
$ Pour plus d'informations, reportez-vous à la section "Mise à niveau<br />
d'une base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> l'utilitaire dbupgrad", page 569 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
♦ <strong>Sybase</strong> Central.<br />
$ Pour plus <strong>de</strong> détails reportez-vous à "Mise à niveau d'une base <strong>de</strong><br />
données à l'ai<strong>de</strong> <strong>de</strong> l'utilitaire dbupgrad", page 569 du document ASA<br />
<strong>Gui<strong>de</strong></strong> d’administration.<br />
Si vous choisissez <strong>de</strong> ne pas installer Java dans la base <strong>de</strong> données, toutes les<br />
opérations <strong>de</strong> base <strong>de</strong> données qui ne font pas appel à <strong>de</strong>s opérations Java<br />
seront entièrement exploitables et fonctionneront normalement.<br />
Nouvelles bases <strong>de</strong> données et Java<br />
Options CREATE<br />
DATABASE<br />
Utilitaire <strong>de</strong><br />
création <strong>de</strong> la base<br />
<strong>de</strong> données<br />
Par défaut, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> n'installe pas les classes d'exécution<br />
Java <strong>de</strong> <strong>Sybase</strong> chaque fois que vous créez une base <strong>de</strong> données. Toutefois,<br />
l'installation <strong>de</strong> ce composant sous licence séparée est facultative et contrôlée<br />
par la métho<strong>de</strong> que vous utilisez pour créer la base <strong>de</strong> données.<br />
L'instruction SQL CREATE DATABASE possè<strong>de</strong> une option appelée<br />
JAVA. Pour configurer une base <strong>de</strong> données pour Java, affectez à l'option la<br />
valeur ON. Pour désactiver Java, affectez-lui la valeur OFF. Par défaut, cette<br />
option est définie avec la valeur OFF.<br />
Par exemple, l'instruction suivante crée le fichier <strong>de</strong> base <strong>de</strong> données pour<br />
Java temp.db :<br />
CREATE DATABASE ’c:\\sybase\\asa8\\temp’ JAVA ON<br />
L'instruction suivante crée le fichier <strong>de</strong> base <strong>de</strong> données temp2.db, qui ne<br />
supporte pas Java.<br />
CREATE DATABASE ’c:\\sybase\\asa8\\temp2’<br />
Vous pouvez créer <strong>de</strong>s bases <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> création <strong>de</strong> bases <strong>de</strong><br />
données dbinit.exe. Cet utilitaire comporte <strong>de</strong>s options qui permettent <strong>de</strong><br />
contrôler l'installation <strong>de</strong>s classes d'exécution Java dans la base <strong>de</strong> données.<br />
Par défaut, ces classes sont ne sont pas installées.<br />
Vous pouvez également utiliser ces options lorsque vous créez une base <strong>de</strong><br />
données à l'ai<strong>de</strong> <strong>de</strong> <strong>Sybase</strong> Central.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Mise à niveau <strong>de</strong>s bases <strong>de</strong> données et <strong>de</strong> Java<br />
Utilitaire <strong>de</strong> mise à<br />
niveau <strong>de</strong>s bases<br />
<strong>de</strong> données<br />
Vous pouvez mettre à niveau <strong>de</strong>s bases <strong>de</strong> données existantes créées avec <strong>de</strong>s<br />
versions antérieures du logiciel à l'ai<strong>de</strong> <strong>de</strong> l'utilitaire <strong>de</strong> mise à niveau ou <strong>de</strong><br />
l'instruction ALTER DATABASE.<br />
La mise à niveau <strong>de</strong>s bases <strong>de</strong> données selon les normes<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> version 8 peut être effectuée à l'ai<strong>de</strong> <strong>de</strong><br />
l'utilitaire dbupgrad.exe. L'option –jr permet d'empêcher l'installation <strong>de</strong>s<br />
classes d'exécution Java <strong>de</strong> <strong>Sybase</strong>.<br />
$ Pour plus d'informations sur les conditions dans lesquelles Java dans la<br />
base <strong>de</strong> données est inclus dans une base <strong>de</strong> données mise à niveau, reportezvous<br />
à la section "Mise à niveau d'une base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> l'utilitaire<br />
dbupgrad", page 569 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Configuration <strong>de</strong> la base <strong>de</strong> données pour Java<br />
Si, au moment <strong>de</strong> sa création ou <strong>de</strong> sa mise à niveau, vous avez choisi <strong>de</strong> ne<br />
pas configurer la base <strong>de</strong> données pour Java, vous avez toujours la possibilité<br />
d'ajouter les classes Java ultérieurement, soit <strong>de</strong>puis <strong>Sybase</strong> Central, soit<br />
<strong>de</strong>puis Interactive SQL.<br />
v Pour ajouter <strong>de</strong>s classes d'exécution Java dans une base <strong>de</strong><br />
données à partir <strong>de</strong> <strong>Sybase</strong> Central :<br />
1 Connectez-vous à la base <strong>de</strong> données à partir <strong>de</strong> <strong>Sybase</strong> Central en tant<br />
qu'utilisateur détenant les droits DBA.<br />
2 Effectuez un clic droit sur la base <strong>de</strong> données, puis choisissez Mettre la<br />
base <strong>de</strong> données à niveau.<br />
3 Cliquez sur Suivant sur la page introductive <strong>de</strong> l'assistant.<br />
4 Dans la liste, sélectionnez la base <strong>de</strong> données que vous souhaitez mettre<br />
à niveau.<br />
5 Si vous le souhaitez, vous pouvez <strong>de</strong>man<strong>de</strong>r la création d'une copie <strong>de</strong><br />
sauvegar<strong>de</strong> <strong>de</strong> la base <strong>de</strong> données. Cliquez sur Suivant.<br />
6 Si vous le souhaitez, vous pouvez installer le support <strong>de</strong> métadonnées<br />
jConnect. Cliquez sur Suivant.<br />
7 Sélectionnez l'option Installer le support Java. Vous <strong>de</strong>vez choisir la<br />
version <strong>de</strong> JDK à installer. Les classes par défaut sont les classes JDK<br />
1.3. Pour les bases <strong>de</strong> données créées avec la version 7.x, les classes par<br />
défaut sont les classes JDK 1.1.8.<br />
99
Configuration <strong>de</strong> la base <strong>de</strong> données pour Java<br />
100<br />
8 Suivez la suite <strong>de</strong>s instructions affichées par l'assistant.<br />
v Pour ajouter <strong>de</strong>s classes d'exécution Java dans une base <strong>de</strong><br />
données à partir <strong>de</strong> SQL :<br />
1 Connectez-vous à la base <strong>de</strong> données à partir d'Interactive SQL en tant<br />
qu'utilisateur détenant les droits DBA.<br />
2 Exécutez l'instruction suivante :<br />
ALTER DATABASE UPGRADE JAVA ON<br />
$ Pour plus d'informations, reportez-vous à la section "Instruction<br />
ALTER DATABASE", page 216 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
3 Relancez la base <strong>de</strong> données afin que le support Java soit effectif.<br />
Configuration d'une base <strong>de</strong> données pour Java à l'ai<strong>de</strong> <strong>de</strong><br />
<strong>Sybase</strong> Central<br />
Vous pouvez utiliser <strong>Sybase</strong> Central pour créer <strong>de</strong>s bases <strong>de</strong> données à l'ai<strong>de</strong><br />
<strong>de</strong>s assistants. Durant l'opération <strong>de</strong> création ou <strong>de</strong> mise à niveau, l'assistant<br />
vous <strong>de</strong>man<strong>de</strong> si les classes d'exécution Java doivent être installées ou non.<br />
L'option par défaut configure la base <strong>de</strong> données pour Java.<br />
Dans <strong>Sybase</strong> Central, vous disposez <strong>de</strong> <strong>de</strong>ux métho<strong>de</strong>s pour créer ou mettre à<br />
niveau une base <strong>de</strong> données :<br />
♦ Création d'une base <strong>de</strong> données à partir du dossier Utilitaires.<br />
♦ Mise à niveau d'une base <strong>de</strong> données à partir du dossier Utilitaires afin<br />
<strong>de</strong> la mettre à niveau et la faire évoluer vers une version disposant <strong>de</strong><br />
fonctionnalités Java.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Installation <strong>de</strong> classes Java dans une base <strong>de</strong><br />
données<br />
Création d'une classe<br />
Vous <strong>de</strong>vez compiler la classe Java avant <strong>de</strong> l’installer dans une base <strong>de</strong><br />
données. L'installation peut se faire <strong>de</strong> plusieurs façons :<br />
♦ Par classe Vous installez chaque classe dans la base <strong>de</strong> données à partir<br />
du fichier <strong>de</strong> la classe compilée. Les fichiers <strong>de</strong> classe portent<br />
généralement l'extension .class.<br />
♦ Par fichier JAR Vous installez plusieurs classes à la fois par le biais<br />
d'un fichier JAR compacté ou non. Les fichiers JAR ont en général<br />
l'extension .jar ou .zip. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte tous les<br />
fichiers JAR compactés créés avec l'utilitaire JAR <strong>de</strong> Sun et certains<br />
autres formats <strong>de</strong> compression JAR.<br />
Cette section explique comment installer les classes Java une fois compilées.<br />
Vous <strong>de</strong>vez détenir les droits DBA pour installer une classe ou un<br />
fichier JAR.<br />
La procédure <strong>de</strong> création d'une classe se compose <strong>de</strong>s étapes ci-<strong>de</strong>ssous. Le<br />
détail <strong>de</strong> chaque étape peut varier selon qu'un outil <strong>de</strong> développement Java<br />
tel que <strong>Sybase</strong> PowerJ est utilisé ou non.<br />
v Pour créer une classe :<br />
1 Définissez une classe Ecrivez le co<strong>de</strong> Java qui définit votre classe. Si<br />
vous utilisez le kit SDK <strong>de</strong> Sun Java, vous travaillez dans un éditeur <strong>de</strong><br />
texte. Si vous utilisez un outil <strong>de</strong> développement <strong>de</strong> type <strong>Sybase</strong> PowerJ,<br />
suivez les instructions fournies par l'outil.<br />
Utilisez uniquement les classes supportées<br />
Si votre classe utilise <strong>de</strong>s classes d'exécution Java, vérifiez que ces<br />
classes figurent bien dans la liste <strong>de</strong>s classes supportées que vous<br />
trouverez à la section "Packages Java supportés", page 83 du<br />
document ASA Manuel <strong>de</strong> référence SQL.<br />
Les classes utilisateur doivent être 100 % Java. Les métho<strong>de</strong>s natives<br />
ne sont pas autorisées.<br />
101
Installation <strong>de</strong> classes Java dans une base <strong>de</strong> données<br />
Installation d’une classe<br />
102<br />
2 Nommez et sauvegar<strong>de</strong>z la classe définie Sauvegar<strong>de</strong>z votre<br />
déclaration <strong>de</strong> classe (co<strong>de</strong> Java) dans un fichier portant l'extension<br />
.java. Vous <strong>de</strong>vez donner au fichier exactement le même nom que la<br />
classe, en respectant les majuscules et minuscules.<br />
Par exemple, une classe appelée Utility doit être sauvegardée dans un<br />
fichier Utility.java.<br />
3 Compilez la classe Cette étape sert à convertir la déclaration <strong>de</strong> classe,<br />
qui contient du co<strong>de</strong> Java, en un nouveau fichier, séparé, contenant du<br />
co<strong>de</strong> octet. Ce nouveau fichier porte le même nom que le fichier en co<strong>de</strong><br />
Java mais avec l'extension .class. Une classe Java compilée peut être<br />
exécutée dans un environnement d'exécution Java, quelle que soit la<br />
plate-forme qui a servi à sa compilation ou le système d'exploitation<br />
utilisé.<br />
Le kit JDK <strong>de</strong> Sun contient un compilateur Java, Javac.exe.<br />
Uniquement les bases <strong>de</strong> données configurées pour Java<br />
N'importe quel fichier <strong>de</strong> classe compilé Java peut être installé dans<br />
une base <strong>de</strong> données. Toutefois, les opérations Java qui utilisent une<br />
classe installée ne peuvent s'exécuter que si la base <strong>de</strong> données a été<br />
configurée pour Java, comme indiqué dans la section "Configuration<br />
<strong>de</strong> la base <strong>de</strong> données pour Java", page 95.<br />
Pour que la classe Java que vous avez créée soit disponible dans la base <strong>de</strong><br />
données, vous <strong>de</strong>vez l'installer soit à partir <strong>de</strong> <strong>Sybase</strong> Central, soit à l'ai<strong>de</strong> <strong>de</strong><br />
l'instruction INSTALL <strong>de</strong>puis Interactive SQL ou une autre application.<br />
Vous <strong>de</strong>vez connaître le chemin d'accès à la classe et le nom <strong>de</strong> fichier<br />
correspondant.<br />
Vous <strong>de</strong>vez détenir les droits administrateur <strong>de</strong> la base <strong>de</strong> données (DBA)<br />
pour pouvoir installer une classe.<br />
v Pour installer une classe à partir <strong>de</strong> <strong>Sybase</strong> Central<br />
1 Connectez-vous à une base <strong>de</strong> données avec les droits DBA.<br />
2 Ouvrez le dossier Objets Java <strong>de</strong> la base <strong>de</strong> données.<br />
3 Double-cliquez sur Ajouter une classe Java.<br />
4 Suivez les instructions <strong>de</strong> l'assistant.
Installation d’un fichier JAR<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
v Pour installer une classe à partir <strong>de</strong> SQL :<br />
1 Connectez-vous à une base <strong>de</strong> données avec les droits DBA.<br />
2 Exécutez l'instruction suivante :<br />
INSTALL JAVA NEW<br />
FROM FILE ’chemin\\NomClasse.class’<br />
chemin correspondant au nom du répertoire contenant le fichier <strong>de</strong> classe<br />
et NomClasse.class correspondant au nom du fichier <strong>de</strong> classe.<br />
Deux barres obliques inversées (\\) sont nécessaires pour que la barre<br />
oblique inversée ne soit pas interprétée comme un caractère<br />
d'échappement.<br />
Par exemple, pour installer une classe dans le fichier Utility.class résidant<br />
dans le répertoire c:\source, vous <strong>de</strong>vez spécifier l'instruction suivante :<br />
INSTALL JAVA NEW<br />
FROM FILE ’c:\\source\\Utility.class’<br />
Si vous indiquez un chemin d'accès relatif, il doit se rapporter au<br />
répertoire <strong>de</strong> travail courant du serveur <strong>de</strong> base <strong>de</strong> données.<br />
$ Pour plus d'informations, reportez-vous aux sections "Instruction<br />
INSTALL", page 489 du document ASA Manuel <strong>de</strong> référence SQL et<br />
"Suppression d’objets Java, <strong>de</strong> classes et <strong>de</strong> fichiers JAR", page 112.<br />
Il est utile et courant <strong>de</strong> regrouper <strong>de</strong>s classes associées dans un package et<br />
<strong>de</strong> stocker le ou les package(s) créé(s) dans un fichier JAR. Pour plus<br />
d'informations sur les fichiers JAR et les packages, reportez-vous à la<br />
documentation en ligne annexe Thinking in Java, ou à tout autre ouvrage<br />
traitant <strong>de</strong> la <strong>programmation</strong> en Java.<br />
Pour installer un fichier JAR, suivez la même procédure que pour installer un<br />
fichier <strong>de</strong> classe. Un fichier JAR porte l'extension JAR ou ZIP. Chaque<br />
fichier JAR doit avoir un nom dans la base <strong>de</strong> données. Utilisez <strong>de</strong><br />
préférence le même nom que le fichier JAR sans l'extension. Par exemple, si<br />
vous installez le fichier JAR monjar.zip, donnez-lui le nom monjar.<br />
$ Pour plus d'informations, reportez-vous aux sections "Instruction<br />
INSTALL", page 489 du document ASA Manuel <strong>de</strong> référence SQL et<br />
"Suppression d’objets Java, <strong>de</strong> classes et <strong>de</strong> fichiers JAR", page 112.<br />
103
Installation <strong>de</strong> classes Java dans une base <strong>de</strong> données<br />
104<br />
v Pour installer un fichier JAR à partir <strong>de</strong> <strong>Sybase</strong> Central<br />
1 Connectez-vous à une base <strong>de</strong> données avec les droits DBA.<br />
2 Ouvrez le dossier Objets Java <strong>de</strong> la base <strong>de</strong> données.<br />
3 Double-cliquez sur Ajouter un fichier JAR.<br />
4 Suivez les instructions <strong>de</strong> l'assistant.<br />
v Pour installer un fichier JAR à partir <strong>de</strong> SQL :<br />
1 Connectez-vous à une base <strong>de</strong> données avec les droits DBA.<br />
2 Entrez la comman<strong>de</strong> suivante :<br />
INSTALL JAVA NEW<br />
JAR ’nomjar’<br />
FROM FILE ’chemin\\NomJar.jar’<br />
Mise à jour <strong>de</strong>s classes et <strong>de</strong>s fichiers JAR<br />
Les objets Java<br />
actuels et les<br />
classes mises à<br />
jour<br />
Prise en compte<br />
<strong>de</strong>s mises à jour<br />
Vous pouvez mettre à jour les classes et les fichiers JAR à l'ai<strong>de</strong> <strong>de</strong><br />
<strong>Sybase</strong> Central, <strong>de</strong> l'instruction INSTALL d'Interactive SQL ou d'autres<br />
applications clientes.<br />
Pour ce faire, vous <strong>de</strong>vez détenir les droits DBA et disposer d'une version<br />
plus récente du fichier JAR ou du fichier <strong>de</strong> classe compilé sur le disque.<br />
Plusieurs occurrences d'une classe Java peuvent rési<strong>de</strong>r dans la base <strong>de</strong><br />
données sous forme d'objets Java. C'est par exemple le cas lorsque <strong>de</strong>s<br />
valeurs dans une colonne utilisent cette classe comme type <strong>de</strong> données.<br />
Malgré la mise à jour <strong>de</strong> la classe, les anciennes valeurs restent disponibles,<br />
même si les champs et les métho<strong>de</strong>s stockés dans les tables sont<br />
incompatibles avec la nouvelle définition <strong>de</strong> classe.<br />
Cependant, les nouvelles lignes que vous insérez doivent être compatibles<br />
avec la nouvelle définition.<br />
La nouvelle définition n'est utilisée que par les connexions qui sont établies<br />
ou utilisent la classe pour la première fois après installation <strong>de</strong> la classe. Dès<br />
qu'une définition <strong>de</strong> classe est chargée par la machine virtuelle, elle est<br />
stockée en mémoire jusqu'à la fermeture <strong>de</strong> la connexion.<br />
Si, pendant la connexion en cours, vous avez fait appel à une classe Java ou à<br />
un objet associé à cette classe, vous <strong>de</strong>vez vous déconnecter puis vous<br />
reconnecter pour utiliser la nouvelle définition <strong>de</strong> classe.
Objets stockés et<br />
sérialisés<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
$ Pour comprendre pourquoi une nouvelle connexion est nécessaire pour<br />
la prise en compte <strong>de</strong>s mises à jour, il faut saisir le principe <strong>de</strong><br />
fonctionnement <strong>de</strong> la machine virtuelle. Pour plus d'informations, reportezvous<br />
à la section "Configuration <strong>de</strong> la mémoire pour Java", page 137.<br />
Si les objets Java peuvent utiliser la nouvelle définition <strong>de</strong> classe, c'est parce<br />
qu'ils ont été stockés <strong>de</strong> façon sérialisée. Le format <strong>de</strong> sérialisation utilisé a<br />
été spécialement conçu pour la base <strong>de</strong> données. Il ne s'agit pas du format<br />
développé par Sun Microsystems. Les opérations <strong>de</strong> sérialisation et <strong>de</strong><br />
désérialisation sont exécutées en interne par la machine virtuelle <strong>de</strong> <strong>Sybase</strong>,<br />
<strong>de</strong> sorte qu'aucun problème <strong>de</strong> compatibilité ne se pose.<br />
v Pour mettre à jour une classe ou un fichier JAR à partir <strong>de</strong><br />
<strong>Sybase</strong> Central :<br />
1 Connectez-vous à une base <strong>de</strong> données avec les droits DBA.<br />
2 Ouvrez le dossier Objets Java.<br />
3 Recherchez la classe ou le fichier JAR à mettre à jour.<br />
4 Cliquez avec le bouton droit <strong>de</strong> la souris sur la classe ou le fichier JAR<br />
et sélectionnez Mettre à jour dans le menu contextuel.<br />
5 Dans la boîte <strong>de</strong> dialogue qui s'affiche, spécifiez le nom et<br />
l'emplacement <strong>de</strong> la classe ou du fichier JAR à mettre à jour. Au besoin,<br />
cliquez sur le bouton Parcourir.<br />
Conseil<br />
Vous pouvez aussi mettre à jour une classe Java ou un fichier JAR en<br />
cliquant sur Mettre à niveau maintenant dans l'onglet Général <strong>de</strong> la feuille<br />
<strong>de</strong> propriétés correspondante.<br />
v Pour mettre à jour une classe ou un fichier JAR à partir <strong>de</strong> SQL :<br />
1 Connectez-vous à une base <strong>de</strong> données avec les droits DBA.<br />
2 Exécutez l'instruction suivante :<br />
INSTALL JAVA UPDATE<br />
[ JAR ’nomjar’ ]<br />
FROM FILE ’nomfichier’<br />
Si vous mettez à jour un fichier JAR, entrez son nom tel qu'il est connu<br />
dans la base <strong>de</strong> données.<br />
$ Pour plus d'informations, reportez-vous à la section "Instruction<br />
INSTALL", page 489 du document ASA Manuel <strong>de</strong> référence SQL.<br />
105
Création <strong>de</strong> colonnes d'objets Java<br />
Création <strong>de</strong> colonnes d'objets Java<br />
106<br />
Cette section explique comment les colonnes <strong>de</strong> types <strong>de</strong> données <strong>de</strong> classe<br />
Java se placent dans le cadre SQL standard.<br />
Création <strong>de</strong> colonnes <strong>de</strong> types <strong>de</strong> données Java<br />
Distinction<br />
majuscules/<br />
minuscules<br />
N'importe qu'elle classe Java installée peut être utilisée comme type <strong>de</strong><br />
données. Vous <strong>de</strong>vez utiliser le nom intégralement qualifié du type <strong>de</strong><br />
données.<br />
Par exemple, l'instruction CREATE TABLE ci-<strong>de</strong>ssous insère une colonne<br />
qui comporte <strong>de</strong>s colonnes <strong>de</strong> types <strong>de</strong> données Java asa<strong>de</strong>mo.Name et<br />
asa<strong>de</strong>mo.ContactInfo. Dans cet exemple, Name et ContactInfo sont <strong>de</strong>s<br />
classes à l'intérieur du package asa<strong>de</strong>mo.<br />
CREATE TABLE jdba.customer<br />
(<br />
id integer NOT NULL,<br />
company_name CHAR(35) NOT NULL,<br />
JName asa<strong>de</strong>mo.Name NOT NULL,<br />
JContactInfo asa<strong>de</strong>mo.ContactInfo NOT NULL,<br />
PRIMARY KEY (id)<br />
)<br />
Contrairement aux types <strong>de</strong> données SQL, les types Java font la distinction<br />
majuscules/minuscules. Vous <strong>de</strong>vez fournir le nom exact <strong>de</strong> chaque partie du<br />
type <strong>de</strong> données en respectant les minuscules et les majuscules.<br />
Valeurs par défaut et entrées NULL dans les colonnes Java<br />
Vous pouvez utiliser les valeurs proposées par défaut dans les colonnes Java<br />
et laisser <strong>de</strong>s entrées vi<strong>de</strong>s (valeur NULL).<br />
Colonnes Java et valeurs par défaut Toute fonction du type <strong>de</strong> données<br />
et toute valeur par défaut prédéfinie est acceptée comme valeur par défaut<br />
dans les colonnes. Vous pouvez utiliser n'importe quelle fonction du type <strong>de</strong><br />
données approprié (par exemple, <strong>de</strong> la même classe que la colonne) comme<br />
valeur par défaut pour les colonnes Java.<br />
Colonnes Java et valeur NULL Les colonnes Java acceptent la valeur<br />
NULL. Si aucune valeur par défaut n'a été définie dans une colonne <strong>de</strong> type<br />
Java et que la colonne accepte la valeur NULL, cette valeur est attribuée à la<br />
colonne.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Si une valeur Java n'a pas été définie, elle prend la valeur NULL. Cette<br />
valeur Java est mappée sur la SQL NULL et vous pouvez utiliser les critères<br />
<strong>de</strong> recherche IS NULL et IS NOT NULL. Supposons par exemple que la<br />
<strong>de</strong>scription <strong>de</strong> l'objet Java Product dans une colonne appelée JProd n'a pas<br />
été définie ; vous pouvez rechercher tous les produits <strong>de</strong> valeur non NULL<br />
correspondant à la <strong>de</strong>scription, comme suit :<br />
SELECT *<br />
FROM product<br />
WHERE JProd>><strong>de</strong>scription IS NULL<br />
107
Insertion, mise à jour et suppression d'objets Java<br />
Insertion, mise à jour et suppression d'objets<br />
Java<br />
Création <strong>de</strong> tables<br />
Java exemple<br />
Classe exemple<br />
108<br />
Cette section explique comment les instructions <strong>de</strong> manipulation <strong>de</strong>s<br />
données SQL standard s'appliquent aux colonnes Java.<br />
Chaque point décrit dans cette section est illustré à l'ai<strong>de</strong> d'un exemple<br />
concret qui utilise la table Product <strong>de</strong> la base <strong>de</strong> données exemple et la classe<br />
Product. Consultez au préalable le fichier<br />
Samples\ASA\Java\asa<strong>de</strong>mo\Product.java stocké dans le répertoire<br />
SQL <strong>Anywhere</strong>.<br />
Les exemples fournis dans cette section supposent que les tables Java ont<br />
déjà été ajoutées à la base <strong>de</strong> données exemple et qu'elles sont connectées à<br />
l'ID utilisateur jDBA doté du mot <strong>de</strong> passe SQL.<br />
$ Pour plus d'informations, reportez-vous à la section "Installation <strong>de</strong>s<br />
exemples Java", page 92.<br />
Cette section décrit la classe utilisée en exemple dans les rubriques qui<br />
suivent.<br />
La définition <strong>de</strong> la classe Product se trouve dans le fichier<br />
Samples\ASA\Java\asa<strong>de</strong>mo\Product.java, du répertoire SQL <strong>Anywhere</strong>.<br />
Une partie est reproduite ci-après :<br />
package asa<strong>de</strong>mo;<br />
public class Product implements java.io.Serializable {<br />
// champs publics<br />
public String name ;<br />
public String <strong>de</strong>scription ;<br />
public String size ;<br />
public String color;<br />
public int quantity ;<br />
public java.math.BigDecimal unit_price ;<br />
// Constructeur par défaut<br />
Product () {<br />
unit_price = new java.math.BigDecimal( 10.00 );<br />
name = "Unknown";<br />
size = "One size fits all";
Remarques<br />
Insertion d’objets Java<br />
}<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
// Constructeur utilisant tous les arguments<br />
disponibles<br />
Product ( String inColor,<br />
String inDescription,<br />
String inName,<br />
int inQuantity,<br />
String inSize,<br />
java.math.BigDecimal inUnit_price<br />
) {<br />
color = inColor;<br />
<strong>de</strong>scription = inDescription;<br />
name = inName;<br />
quantity = inQuantity;<br />
size = inSize;<br />
unit_price=inUnit_price;<br />
}<br />
public String toString() {<br />
return size + " " + name + ": " +<br />
unit_price.toString();<br />
}<br />
♦ La classe Product possè<strong>de</strong> plusieurs champs publics ; ceux-ci<br />
correspon<strong>de</strong>nt à certaines colonnes <strong>de</strong> la table DBA.Product qui doivent<br />
être rassemblées dans cette classe.<br />
♦ La métho<strong>de</strong> toString est fournie pour plus <strong>de</strong> convivialité. Lorsque vous<br />
insérez un nom d'objet dans une liste <strong>de</strong> sélection, la métho<strong>de</strong> toString<br />
s'exécute et la chaîne renvoyée s'affiche.<br />
♦ Certaines métho<strong>de</strong>s servent à définir et accé<strong>de</strong>r aux champs. Elles<br />
s'utilisent généralement en <strong>programmation</strong> orientée objet afin d'éviter<br />
l'accès direct aux champs. Pour <strong>de</strong>s raisons pratiques, les champs<br />
proposés en exemple sont publics.<br />
Lorsque vous ajoutez à l'ai<strong>de</strong> <strong>de</strong> l'instruction INSERT une ligne dans une<br />
table dotée d'une colonne Java, vous <strong>de</strong>vez insérer un objet Java dans la<br />
colonne Java.<br />
L'insertion d'un objet Java peut s'effectuer <strong>de</strong> <strong>de</strong>ux façons : avec SQL ou à<br />
partir d'autres classes Java exécutées dans la base <strong>de</strong> données, à l'ai<strong>de</strong> <strong>de</strong><br />
JDBC.<br />
109
Insertion, mise à jour et suppression d'objets Java<br />
Insertion d'un objet Java à partir <strong>de</strong> SQL<br />
Insertion d’un objet<br />
à l'ai<strong>de</strong> d'un<br />
constructeur<br />
Insertion d'un objet<br />
à partir <strong>de</strong> la<br />
variable SQL<br />
110<br />
Vous pouvez insérer un objet Java à l'ai<strong>de</strong> d'un constructeur ou utiliser <strong>de</strong>s<br />
variables SQL pour construire l'objet Java à insérer.<br />
Lorsque vous ajoutez une valeur dans une colonne portant un type <strong>de</strong><br />
données <strong>de</strong> classe Java, vous insérez un objet Java. Les champs du nouvel<br />
objet doivent convenir à n'importe quel champ public et les métho<strong>de</strong>s qui<br />
définissent <strong>de</strong>s champs privés doivent pouvoir être appelées.<br />
v Pour insérer un objet Java :<br />
♦ Insérez avec l'instruction INSERT une nouvelle instance <strong>de</strong> la classe<br />
Product dans la table product comme suit :<br />
INSERT<br />
INTO product ( ID, JProd )<br />
VALUES ( 702, NEW asa<strong>de</strong>mo.Product() )<br />
Appliquez cet exemple sur la base <strong>de</strong> données exemple avec l'ID<br />
utilisateur jdba, une fois que le script j<strong>de</strong>mo.sql a été exécuté.<br />
Le mot-clé NEW appelle le constructeur par défaut <strong>de</strong> la classe Product<br />
dans le package asa<strong>de</strong>mo.<br />
Vous pouvez également définir les valeurs <strong>de</strong> champ d'un objet dans une<br />
variable <strong>de</strong> la classe correspondante, au lieu d'utiliser le constructeur.<br />
v Pour insérer un objet Java avec <strong>de</strong>s variables SQL :<br />
1 Créez une variable SQL du type <strong>de</strong> classe Java :<br />
CREATE VARIABLE ProductVar asa<strong>de</strong>mo.Product<br />
2 Attribuez un nouvel objet à la variable, à l'ai<strong>de</strong> du constructeur <strong>de</strong><br />
classe :<br />
SET ProductVar = NEW asa<strong>de</strong>mo.Product()<br />
3 Attribuez les valeurs aux champs <strong>de</strong> l'objet :<br />
SET ProductVar>>color = ’Black’;<br />
SET ProductVar>><strong>de</strong>scription = ’Steel tipped boots’;<br />
SET ProductVar>>name = ’Work boots’;<br />
SET ProductVar>>quantity = 40;<br />
SET ProductVar>>size = ’Extra Large’;<br />
SET ProductVar>>unit_price = 79.99;<br />
4 Insérez la variable dans la table :<br />
INSERT<br />
INTO Product ( id, JProd )<br />
VALUES ( 800, ProductVar )
Insertion d’un objet avec Java<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
5 Vérifiez que la valeur a été insérée.<br />
SELECT *<br />
FROM product<br />
WHERE id=800<br />
6 Annulez les modifications apportées au cours <strong>de</strong> cet exercice.<br />
ROLLBACK<br />
Mise à jour <strong>de</strong>s objets Java<br />
Mise à jour <strong>de</strong><br />
l'objet entier<br />
Il est courant d'utiliser <strong>de</strong>s variables SQL dans les procédures stockées et<br />
dans d'autres utilisations <strong>de</strong> SQL pour construire une logique <strong>de</strong><br />
<strong>programmation</strong> au sein <strong>de</strong> la base <strong>de</strong> données. Java offre un moyen plus<br />
puissant d'accomplir cette tâche. Par exemple, vous pouvez utiliser <strong>de</strong>s<br />
classes Java côté serveur avec JBDC pour insérer <strong>de</strong>s objets dans les tables.<br />
Vous pouvez insérer un objet dans une table à l'ai<strong>de</strong> d'une instruction<br />
préparée JDBC.<br />
Une instruction préparée utilise <strong>de</strong>s marques <strong>de</strong> réservation pour les<br />
variables. Vous pouvez ensuite utiliser la métho<strong>de</strong> setObject <strong>de</strong> l'objet<br />
PreparedStatement.<br />
Vous pouvez utiliser <strong>de</strong>s instructions préparées pour insérer <strong>de</strong>s objets à<br />
partir <strong>de</strong> JDBC, côté client ou côté serveur.<br />
$ Pour plus d'informations sur l'utilisation <strong>de</strong>s instructions préparées,<br />
reportez vous à la section "Insertion et extraction d'objets", page 169.<br />
Vous pouvez mettre à jour la valeur d'une colonne Java <strong>de</strong> plusieurs façons :<br />
♦ en mettant à jour la totalité <strong>de</strong> l'objet,<br />
♦ en mettant à jour certains champs <strong>de</strong> l'objet.<br />
La procédure <strong>de</strong> mise à jour d'un objet est quasiment i<strong>de</strong>ntique à celle<br />
utilisée pour insérer les objets.<br />
♦ A partir <strong>de</strong> SQL, vous pouvez utiliser un constructeur pour mettre à jour<br />
l'objet complet : le constructeur crée alors un nouvel objet. Il suffit<br />
ensuite <strong>de</strong> mettre à jour les champs comme souhaité.<br />
♦ A partir <strong>de</strong> SQL, vous pouvez utiliser une variable SQL pour contenir<br />
l'objet, puis mettre à jour la ligne qui doit contenir la variable.<br />
♦ A partir <strong>de</strong> JDBC, utilisez une instruction préparée et la métho<strong>de</strong><br />
PreparedStatement.setObject.<br />
111
Insertion, mise à jour et suppression d'objets Java<br />
Mise à jour <strong>de</strong>s<br />
champs <strong>de</strong> l'objet<br />
Utilisation <strong>de</strong>s<br />
métho<strong>de</strong>s SET<br />
112<br />
Chaque champ d'un objet porte <strong>de</strong>s types <strong>de</strong> données correspondant à <strong>de</strong>s<br />
types <strong>de</strong> données SQL. Le mappage <strong>de</strong>s types SQL en Java se fait selon le<br />
principe décrit à la section "Conversions entre types <strong>de</strong> données Java et<br />
SQL", page 91 du document ASA Manuel <strong>de</strong> référence SQL.<br />
L’instruction UPDATE permet <strong>de</strong> faire une mise à jour par champ :<br />
UPDATE Product<br />
SET JProd.unit_price = 16.00<br />
WHERE ID = 302<br />
Dans la version initiale <strong>de</strong> Java dans la base <strong>de</strong> données, il fallait exécuter<br />
une fonction particulière (EVALUATE) pour effectuer <strong>de</strong>s mises à jour.<br />
Cette opération n'a plus lieu d'être.<br />
Pour mettre à jour un champ Java, le type <strong>de</strong> données Java du champ doit<br />
correspondre à un type SQL : l'expression à droite <strong>de</strong> la clause SET doit<br />
correspondre à ce type. Vous <strong>de</strong>vrez peut-être faire appel à la fonction CAST<br />
pour rechercher les types <strong>de</strong> données appropriés.<br />
$ Pour plus d'informations sur les mappages <strong>de</strong> types <strong>de</strong> données entre<br />
Java et SQL, reportez-vous à la section "Conversions entre types <strong>de</strong> données<br />
Java et SQL", page 91 du document ASA Manuel <strong>de</strong> référence SQL.<br />
En <strong>programmation</strong> Java, il est courant <strong>de</strong> ne pas accé<strong>de</strong>r directement aux<br />
champs, mais d'utiliser <strong>de</strong>s métho<strong>de</strong>s pour accé<strong>de</strong>r à la valeur et la définir.<br />
Généralement, ces métho<strong>de</strong>s renvoient void. Vous pouvez utiliser <strong>de</strong>s<br />
métho<strong>de</strong>s SET dans SQL pour mettre à jour une colonne :<br />
UPDATE jdba.Product<br />
SET JProd.setName( ’Tank Top’)<br />
WHERE id=302<br />
L'utilisation <strong>de</strong>s métho<strong>de</strong>s est moins rapi<strong>de</strong> que l'adressage direct <strong>de</strong>s champs<br />
car elle nécessite l'exécution <strong>de</strong> la machine virtuelle Java.<br />
$ Pour plus d'informations, reportez-vous à la section "Valeur renvoyée<br />
par les métho<strong>de</strong>s renvoyant void", page 122.<br />
Suppression d’objets Java, <strong>de</strong> classes et <strong>de</strong> fichiers JAR<br />
Les lignes contenant <strong>de</strong>s objets Java sont supprimées exactement comme<br />
d'autres lignes. La clause WHERE dans l'instruction DELETE peut contenir<br />
<strong>de</strong>s objets Java ou <strong>de</strong>s champs et <strong>de</strong>s métho<strong>de</strong>s.<br />
$ Pour plus d'informations, reportez-vous à la section "Instruction<br />
DELETE", page 410 du document ASA Manuel <strong>de</strong> référence SQL.<br />
Avec <strong>Sybase</strong> Central, vous pouvez aussi supprimer une classe Java complète<br />
ou un fichier JAR.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
v Pour supprimer une classe ou un fichier JAR à partir <strong>de</strong><br />
<strong>Sybase</strong> Central :<br />
1 Ouvrez le dossier Objets Java.<br />
2 Recherchez la classe ou le fichier JAR à supprimer.<br />
3 Cliquez avec le bouton droit <strong>de</strong> la souris sur la classe ou le fichier JAR<br />
et sélectionnez Supprimer dans le menu contextuel.<br />
$ Voir aussi<br />
♦ "Installation d'une classe", page 102<br />
♦ "Installation d'un fichier JAR", page 103<br />
113
Recherche d’objets Java<br />
Recherche d’objets Java<br />
Récupération <strong>de</strong> la<br />
totalité <strong>de</strong> l'objet<br />
Récupération <strong>de</strong>s<br />
champs <strong>de</strong> l'objet<br />
114<br />
Vous pouvez récupérer la valeur d'une colonne Java <strong>de</strong> plusieurs façons :<br />
♦ en récupérant la totalité <strong>de</strong> l'objet,<br />
♦ en récupérant certains champs <strong>de</strong> l'objet.<br />
Vous pouvez créer dans SQL une variable du type approprié et attribuer à<br />
cette variable une valeur qui figure dans l'objet. Cependant, c'est dans une<br />
application Java que vous aurez le plus besoin d'utiliser l'objet entier.<br />
Vous pouvez récupérer un objet dans une classe Java côté serveur en utilisant<br />
la métho<strong>de</strong> getObject <strong>de</strong> l'instruction ResultSet. Vous pouvez également<br />
récupérer un objet dans une application Java côté client.<br />
$ Pour plus d'informations sur la récupération d'objets à l'ai<strong>de</strong> <strong>de</strong> JDBC,<br />
reportez-vous à la section "Requêtes avec JDBC", page 166.<br />
Chaque champ d'un objet porte <strong>de</strong>s types <strong>de</strong> données correspondant à <strong>de</strong>s<br />
types <strong>de</strong> données SQL. Le mappage <strong>de</strong>s types SQL en Java se fait selon le<br />
principe décrit à la section "Conversions entre types <strong>de</strong> données Java et<br />
SQL", page 91 du document ASA Manuel <strong>de</strong> référence SQL.<br />
♦ Vous pouvez récupérer <strong>de</strong>s champs individuels en les incluant à la liste<br />
<strong>de</strong> sélection d'une requête, comme illustré dans l'exemple suivant :<br />
SELECT JProd>>unit_price<br />
FROM product<br />
WHERE ID = 400<br />
♦ Si vous utilisez <strong>de</strong>s métho<strong>de</strong>s pour définir et rechercher les valeurs <strong>de</strong><br />
vos champs, comme cela se fait souvent dans la <strong>programmation</strong> orientée<br />
objet, vous pouvez inclure une métho<strong>de</strong> getField à votre recherche :<br />
SELECT JProd>>getName()<br />
FROM Product<br />
WHERE ID = 401<br />
$ Pour plus d'informations sur l'utilisation <strong>de</strong>s objets avec la clause<br />
WHERE et sur la comparaison d'objets, reportez-vous à la section<br />
"Comparaison <strong>de</strong>s champs et <strong>de</strong>s objets Java", page 116.<br />
Conseil relatif aux performances<br />
L'obtention directe d'un champ est plus rapi<strong>de</strong> que l'appel d'une métho<strong>de</strong><br />
qui obtient le champ car les appels <strong>de</strong> métho<strong>de</strong> nécessitent la machine<br />
virtuelle Java.
Liste <strong>de</strong>s noms <strong>de</strong><br />
colonnes par<br />
SELECT<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Vous pouvez afficher le nom <strong>de</strong>s colonnes dans une liste <strong>de</strong> sélection, en<br />
tapant la requête suivante :<br />
SELECT JProd<br />
FROM jdba.product<br />
Cette requête renvoie la sérialisation Sun <strong>de</strong> l'objet à l'application cliente.<br />
Lorsque vous exécutez une requête qui récupère un objet dans<br />
Interactive SQL, elle affiche la valeur renvoyée par la métho<strong>de</strong> toString <strong>de</strong><br />
l'objet. Pour la classe Product, la métho<strong>de</strong> toString affiche, en une seule<br />
chaîne <strong>de</strong> caractères, la taille, le nom et le prix unitaire <strong>de</strong> l'objet. Le résultat<br />
<strong>de</strong> la requête est le suivant :<br />
JProd<br />
Small Tee Shirt: 9.00<br />
Medium Tee Shirt: 14.00<br />
One size fits all Tee Shirt: 14.00<br />
One size fits all Baseball Cap: 9.00<br />
One size fits all Baseball Cap: 10.00<br />
One size fits all Visor: 7.00<br />
One size fits all Visor: 7.00<br />
Large Sweatshirt: 24.00<br />
Large Sweatshirt: 24.00<br />
Medium Shorts: 15.00<br />
115
Comparaison <strong>de</strong>s champs et <strong>de</strong>s objets Java<br />
Comparaison <strong>de</strong>s champs et <strong>de</strong>s objets Java<br />
Types <strong>de</strong><br />
comparaison<br />
d’objets Java<br />
116<br />
Les classes Java publiques sont <strong>de</strong>s domaines définis <strong>de</strong> manière bien plus<br />
détaillée que les domaines SQL. C'est d'ailleurs pourquoi le comportement<br />
<strong>de</strong>s colonnes Java dans une base <strong>de</strong> données relationnelle est différent <strong>de</strong><br />
celui <strong>de</strong>s colonnes contenant <strong>de</strong>s types <strong>de</strong> données SQL traditionnelles.<br />
La métho<strong>de</strong> <strong>de</strong> comparaison <strong>de</strong>s objets influe notamment sur :<br />
♦ Les requêtes comportant une clause ORDER BY ou GROUP BY, un<br />
mot-clé DISTINCT ou une fonction agrégée.<br />
♦ Les instructions qui utilisent <strong>de</strong>s conditions d'égalité ou d'inégalité.<br />
♦ Les in<strong>de</strong>x et les colonnes uniques.<br />
♦ Les colonnes <strong>de</strong> clés primaires et étrangères.<br />
Le tri et l'agencement <strong>de</strong>s lignes d'une requête ou d'un in<strong>de</strong>x impliquent la<br />
comparaison <strong>de</strong>s valeurs <strong>de</strong> chaque ligne. Dans le cas d'une colonne Java,<br />
vous pouvez effectuer <strong>de</strong>s comparaisons en procédant comme suit :<br />
♦ Effectuer une comparaison sur un champ public Vous pouvez<br />
comparer un champ public <strong>de</strong> la même manière que vous comparez une<br />
ligne ordinaire. Par exemple, exécutez la requête suivante :<br />
SELECT name, JProd>>unit_price<br />
FROM Product<br />
ORDER BY JProd>>unit_price<br />
Vous pouvez utiliser ce type <strong>de</strong> comparaison dans les requêtes, mais pas<br />
dans les in<strong>de</strong>x ni dans les colonnes <strong>de</strong> clés.<br />
♦ Effectuer une comparaison à l'ai<strong>de</strong> <strong>de</strong> la métho<strong>de</strong> compareTo Les<br />
objets Java intégrant une métho<strong>de</strong> compareTo peuvent faire l'objet<br />
d'une comparaison. La classe Product, sur laquelle est basée la colonne<br />
JProd, intègre une métho<strong>de</strong> compareTo qui compare les objets basés<br />
sur le champ unit_price. Vous pouvez ainsi effectuer la requête<br />
suivante :<br />
SELECT name, JProd>>unit_price<br />
FROM Product<br />
ORDER BY JProd<br />
La comparaison requise par la clause ORDER BY est automatiquement<br />
effectuée sur la base <strong>de</strong> la métho<strong>de</strong> compareTo.
Comparaison d’objets Java<br />
Configuration<br />
requise par la<br />
métho<strong>de</strong><br />
compareTo<br />
Exemple<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Pour comparer <strong>de</strong>ux objets du même type, vous <strong>de</strong>vez appliquer une<br />
métho<strong>de</strong> compareTo.<br />
♦ Pour utiliser comme clés primaires, in<strong>de</strong>x ou colonnes uniques les<br />
colonnes <strong>de</strong> types <strong>de</strong> données Java, la classe <strong>de</strong> colonne doit mettre en<br />
oeuvre une métho<strong>de</strong> compareTo.<br />
♦ Pour utiliser les clauses ORDER BY, GROUP BY ou DISTINCT dans<br />
une requête, les valeurs <strong>de</strong> la colonne doivent faire l'objet d'une<br />
comparaison. La classe <strong>de</strong> colonne doit intégrer une métho<strong>de</strong><br />
compareTo pour que ces clauses puissent être reconnues.<br />
♦ Les fonctions incluant <strong>de</strong>s comparaisons, telles que MAX et MIN, ne<br />
peuvent être appliquées à une classe Java que si cette <strong>de</strong>rnière intègre<br />
une métho<strong>de</strong> compareTo.<br />
La métho<strong>de</strong> compareTo doit être associée aux propriétés suivantes :<br />
♦ Portée La métho<strong>de</strong> doit être visible <strong>de</strong> manière externe, c'est-à-dire qu'il<br />
doit s'agir d'une métho<strong>de</strong> public.<br />
♦ Arguments La métho<strong>de</strong> ne prend en compte qu'un argument, qui est un<br />
objet du type en cours. L'objet en cours est comparé à l'objet fourni. Par<br />
exemple, Product.compareTo est associé à l'argument suivant :<br />
compareTo( Product anotherProduct )<br />
Cette métho<strong>de</strong> compare l'objet anotherProduct, du type Product, à<br />
l'objet en cours.<br />
♦ Valeurs renvoyées La métho<strong>de</strong> compareTo doit renvoyer <strong>de</strong>s données<br />
<strong>de</strong> type int suivantes :<br />
♦ Entier négatif La valeur <strong>de</strong> l'objet en cours est inférieure à celle <strong>de</strong><br />
l'objet fourni. Pour <strong>de</strong>s raisons <strong>de</strong> compatibilité avec les métho<strong>de</strong>s<br />
compareTo <strong>de</strong>s classes Java <strong>de</strong> base, il est recomman<strong>de</strong> <strong>de</strong> renvoyer<br />
la valeur -1 dans ce cas.<br />
♦ Zéro La valeur <strong>de</strong> l'objet en cours est i<strong>de</strong>ntique à celle <strong>de</strong> l'objet<br />
fourni.<br />
♦ Entier positif La valeur <strong>de</strong> l'objet en cours est supérieure à celle <strong>de</strong><br />
l'objet fourni. Pour <strong>de</strong>s raisons <strong>de</strong> compatibilité avec les métho<strong>de</strong>s<br />
compareTo <strong>de</strong>s classes Java <strong>de</strong> base, il est recommandé <strong>de</strong> renvoyer<br />
la valeur 1 dans ce cas.<br />
La classe Product installée dans la base <strong>de</strong> données exemple avec les classes<br />
exemple intègre une métho<strong>de</strong> compareTo, comme illustré ci-après :<br />
public int compareTo( Product anotherProduct ) {<br />
117
Comparaison <strong>de</strong>s champs et <strong>de</strong>s objets Java<br />
Compatibilité <strong>de</strong><br />
toString et<br />
compareTo<br />
118<br />
// Compare d’abord les prix<br />
// puis toString()<br />
int lVal = unit_price.intValue();<br />
int rVal = anotherProduct.unit_price.intValue();<br />
if ( lVal > rVal ) {<br />
return 1;<br />
}<br />
else if (lVal < rVal ) {<br />
return -1;<br />
}<br />
else {<br />
return toString().compareTo(<br />
anotherProduct.toString() );{<br />
}<br />
}<br />
}<br />
Cette métho<strong>de</strong> compare le prix unitaire <strong>de</strong> chaque objet. Si tous les prix sont<br />
i<strong>de</strong>ntiques, la comparaison porte sur les noms (à l'ai<strong>de</strong> d'une comparaison <strong>de</strong><br />
chaîne Java, et non <strong>de</strong> chaîne <strong>de</strong> base <strong>de</strong> données). Deux objets sont<br />
considérés comme étant i<strong>de</strong>ntiques s'ils ont le même prix unitaire et le même<br />
nom.<br />
Si vous incluez une colonne Java dans liste <strong>de</strong> sélection d'une requête puis<br />
que vous l'exécutez dans Interactive SQL, la valeur <strong>de</strong> la métho<strong>de</strong> toString<br />
est renvoyée. La métho<strong>de</strong> compareTo est utilisée pour comparer <strong>de</strong>s<br />
colonnes. Si les métho<strong>de</strong>s toString et compareTo ne sont pas utilisées <strong>de</strong><br />
manière cohérente, vous risquez d'obtenir <strong>de</strong>s résultats surprenants. Une<br />
requête DISTINCT, par exemple, peut renvoyer <strong>de</strong>s lignes dupliquées.<br />
Supposons que la classe Product <strong>de</strong> la base <strong>de</strong> données exemple intègre une<br />
métho<strong>de</strong> toString, qui a renvoyé le nom du produit, et une métho<strong>de</strong><br />
compareTo basée sur le prix. Les valeurs renvoyées par la requête suivante,<br />
exécutée dans Interactive SQL, seraient dupliquées :<br />
SELECT DISTINCT JProd<br />
FROM product<br />
JProd<br />
Tee-shirt<br />
Tee-shirt<br />
Baseball Cap<br />
Visor<br />
Sweat-shirt<br />
Shorts
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Dans cet exemple, la valeur renvoyée est déterminée par toString. Le motclé<br />
DISTINCT élimine les valeurs dupliquées définies par compareTo. Le<br />
fait que ces <strong>de</strong>ux métho<strong>de</strong>s aient été mises en oeuvre <strong>de</strong> manière<br />
indépendante explique que les lignes renvoyées soient dupliquées.<br />
119
Fonctionnalités spéciales <strong>de</strong>s classes Java dans la base <strong>de</strong> données<br />
Fonctionnalités spéciales <strong>de</strong>s classes Java dans<br />
la base <strong>de</strong> données<br />
Classes supportées<br />
Appel <strong>de</strong> la métho<strong>de</strong> main<br />
120<br />
Cette section décrit les fonctionnalités <strong>de</strong>s classes Java utilisées dans la base<br />
<strong>de</strong> données.<br />
Vous ne pouvez pas utiliser toutes les classes du JDK. Les classes<br />
d'exécution Java utilisables dans le serveur <strong>de</strong> base <strong>de</strong> données appartiennent<br />
à un sous-ensemble <strong>de</strong> l'API Java.<br />
$ Pour plus d'informations sur les packages supportés, reportez-vous à la<br />
section "Packages Java supportés", page 83 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
En général, vous appelez <strong>de</strong>s applications Java (hors <strong>de</strong> la base) en exécutant<br />
la machine virtuelle Java sur une classe comportant une métho<strong>de</strong> main.<br />
Par exemple, la classe JDBCExamples stockée dans le fichier<br />
Samples\ASA\Java\JDBCExamples.java du répertoire SQL <strong>Anywhere</strong><br />
comporte une métho<strong>de</strong> main. Lorsque vous exécutez cette classe à partir <strong>de</strong><br />
la ligne <strong>de</strong> comman<strong>de</strong> à l'ai<strong>de</strong> d'une comman<strong>de</strong> du type ci-après, la métho<strong>de</strong><br />
main est exécutée :<br />
java JDBCExamples<br />
$ Pour plus d'informations sur l'exécution <strong>de</strong> la classe JDBCExamples,<br />
reportez-vous à la section "Etablissement <strong>de</strong> connexions JDBC", page 154.<br />
v Pour appeler la métho<strong>de</strong> main d'une classe à partir <strong>de</strong> SQL :<br />
1 Déclarez la métho<strong>de</strong> avec un tableau <strong>de</strong> chaînes faisant office<br />
d'argument :<br />
public static void main( java.lang.String[] args ){<br />
...<br />
}<br />
2 Appelez la métho<strong>de</strong> main à l'ai<strong>de</strong> <strong>de</strong> l'instruction CALL.<br />
Chaque élément du tableau <strong>de</strong> chaînes doit être <strong>de</strong> type CHAR ou<br />
VARCHAR, ou une chaîne littérale.
Exemple<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
La classe suivante contient une métho<strong>de</strong> main qui écrit les arguments dans<br />
l'ordre inverse :<br />
public class ReverseWrite {<br />
public static void main( String[] args ){<br />
int i:<br />
for( i = args.length; i > 0 ; i-- ){<br />
System.out.print( args[ i-1 ] );<br />
}<br />
}<br />
}<br />
Pour exécuter cette métho<strong>de</strong> à partir <strong>de</strong> SQL, procé<strong>de</strong>z comme suit :<br />
call ReverseWrite.main( ’ one’, ’ two’, ’three’ )<br />
La fenêtre du serveur <strong>de</strong> base <strong>de</strong> données affiche le résultat suivant :<br />
three two one<br />
Utilisation <strong>de</strong> threads dans les applications Java<br />
Sérialisation <strong>de</strong>s<br />
appels JDBC<br />
Erreur <strong>de</strong> procedure introuvable<br />
Grâce aux fonctionnalités du package java.lang.Thread, vous pouvez<br />
utiliser plusieurs threads dans une application Java. Chaque thread Java est<br />
un thread <strong>de</strong> moteur, dépendant du nombre <strong>de</strong> threads qu'autorise l'option du<br />
serveur <strong>de</strong> base <strong>de</strong> données -gn.<br />
Vous pouvez synchroniser, suspendre, reprendre, interrompre ou arrêter les<br />
threads <strong>de</strong>s applications Java.<br />
$ Pour plus d'informations sur les threads <strong>de</strong> serveur <strong>de</strong> base <strong>de</strong> données,<br />
reportez-vous à la section "Option <strong>de</strong> serveur -gn", page 153 du document<br />
ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Tous les appels en direction du gestionnaire JDBC côté serveur sont<br />
sérialisés, <strong>de</strong> sorte qu'à tout moment, un seul thread exécute activement<br />
JDBC.<br />
Si vous vous trompez dans le nombre d'arguments lors <strong>de</strong> l'appel d'une<br />
métho<strong>de</strong> Java ou que vous utilisez un type <strong>de</strong> données inapproprié, le serveur<br />
renvoie l'erreur La procedure est introuvable. Vous <strong>de</strong>vez alors vérifier le<br />
nombre et le type <strong>de</strong>s arguments.<br />
$ Pour plus d'informations sur la conversion <strong>de</strong>s types entre SQL et Java,<br />
reportez-vous à la section "Conversions entre types <strong>de</strong> données Java et SQL",<br />
page 91 du document ASA Manuel <strong>de</strong> référence SQL.<br />
121
Fonctionnalités spéciales <strong>de</strong>s classes Java dans la base <strong>de</strong> données<br />
Valeur renvoyée par les métho<strong>de</strong>s renvoyant void<br />
122<br />
Vous pouvez utiliser <strong>de</strong>s métho<strong>de</strong>s Java dans <strong>de</strong>s instructions SQL chaque<br />
fois que vous pouvez utiliser une expression. Vérifiez toutefois que le type<br />
<strong>de</strong> données renvoyées par la métho<strong>de</strong> Java correspond au type <strong>de</strong> données<br />
SQL approprié.<br />
$ Pour plus d'informations sur le mappage <strong>de</strong>s types <strong>de</strong> données entre<br />
Java et SQL, reportez-vous à la section "Conversions entre types <strong>de</strong> données<br />
Java et SQL", page 91 du document ASA Manuel <strong>de</strong> référence SQL.<br />
Lorsqu'une métho<strong>de</strong> renvoie une valeur <strong>de</strong> type void, la valeur this est<br />
renvoyée dans SQL, c'est-à-dire l'objet lui-même. Cette fonctionnalité<br />
n'affecte que les appels émanant <strong>de</strong> SQL, et non <strong>de</strong> Java.<br />
Elle se révèle particulièrement utile dans les instructions UPDATE, où les<br />
métho<strong>de</strong>s set renvoient généralement la valeur void. Vous pouvez utiliser<br />
l'instruction UPDATE suivante dans la base <strong>de</strong> données exemple :<br />
update jdba.product<br />
set JProd = JProd.setName(’Tank Top’)<br />
where id=302<br />
La métho<strong>de</strong> setName renvoie la valeur void et, par conséquent, renvoie<br />
l'objet Product à SQL.<br />
Renvoi <strong>de</strong> jeux <strong>de</strong> résultats à partir <strong>de</strong> métho<strong>de</strong>s Java<br />
Cette section explique comment écrire une métho<strong>de</strong> Java qui renvoie <strong>de</strong>s<br />
jeux <strong>de</strong> résultats. Vous <strong>de</strong>vez écrire une métho<strong>de</strong> Java qui renvoie un jeu <strong>de</strong><br />
résultats à l'environnement appelant et l'encapsuler dans une procédure<br />
stockée SQL déclarée comme EXTERNAL NAME <strong>de</strong> LANGUAGE JAVA.<br />
v Pour renvoyer <strong>de</strong>s jeux <strong>de</strong> résultats à partir <strong>de</strong> d'une métho<strong>de</strong> Java :<br />
1 Vérifiez que la métho<strong>de</strong> Java est déclarée publique et statique dans une<br />
classe publique.<br />
2 Pour chaque jeu <strong>de</strong> résultats que doit renvoyer la métho<strong>de</strong>, vérifiez que<br />
celle-ci contient un paramètre <strong>de</strong> type java.sql.ResultSet[]. Ces<br />
paramètres <strong>de</strong> jeux <strong>de</strong> résultats doivent se trouver à la fin <strong>de</strong> la liste <strong>de</strong>s<br />
paramètres.<br />
3 Dans la métho<strong>de</strong>, créez d'abord une instance <strong>de</strong> java.sql.ResultSet, puis<br />
affectez-la à un <strong>de</strong>s paramètres ResultSet[].
Exemple<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
4 Créez une procédure stockée SQL du type EXTERNAL NAME<br />
LANGUAGE JAVA. Ce type <strong>de</strong> procédure encapsule la métho<strong>de</strong> Java.<br />
Vous pouvez utiliser un curseur sur le jeu <strong>de</strong> résultats <strong>de</strong> la procédure<br />
SQL, exactement comme toute autre procédure qui renvoie <strong>de</strong>s jeux <strong>de</strong><br />
résultats.<br />
$ Pour plus informations sur la syntaxe <strong>de</strong>s procédures stockées qui<br />
encapsulent <strong>de</strong>s métho<strong>de</strong>s Java, reportez-vous à la section "Instruction<br />
CREATE PROCEDURE", page 321 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
La classe simple suivante est dotée d'une seule métho<strong>de</strong>, laquelle effectue<br />
une requête et transmet le jeu <strong>de</strong> résultats à l'environnement appelant.<br />
import java.sql.*;<br />
public class MyResultSet {<br />
public static void return_rset( ResultSet[] rset1 )<br />
throws SQLException {<br />
Connection conn = DriverManager.getConnection(<br />
"jdbc:<strong>de</strong>fault:connection" );<br />
Statement stmt = conn.createStatement();<br />
ResultSet rset =<br />
stmt.executeQuery (<br />
"SELECT CAST( JName.lastName " +<br />
"AS CHAR( 50 ) )" +<br />
"FROM jdba.contact " );<br />
rset1[0] = rset;<br />
}<br />
}<br />
Le jeu <strong>de</strong> résultats est présenté à SQL via une instruction CREATE<br />
PROCEDURE qui indique le nombre <strong>de</strong> jeux <strong>de</strong> résultats renvoyés à partir<br />
<strong>de</strong> la procédure et la signature <strong>de</strong> la métho<strong>de</strong> Java.<br />
Vous pouvez définir une instruction CREATE PROCEDURE indiquant un<br />
jeu <strong>de</strong> résultats, comme suit :<br />
CREATE PROCEDURE result_set()<br />
DYNAMIC RESULT SETS 1<br />
EXTERNAL NAME<br />
’MyResultSet.return_rset ([Ljava/sql/ResultSet;)V’<br />
LANGUAGE JAVA<br />
Vous pouvez ouvrir un curseur sur cette procédure comme sur n'importe<br />
quelle procédure ASA renvoyant <strong>de</strong>s jeux <strong>de</strong> résultats.<br />
La chaîne (Ljava/sql/ResultSet;)V est une signature <strong>de</strong> métho<strong>de</strong> Java, qui<br />
est une représentation compacte, sous forme <strong>de</strong> caractères, du nombre et du<br />
type <strong>de</strong>s paramètres et <strong>de</strong> la valeur renvoyée.<br />
123
Fonctionnalités spéciales <strong>de</strong>s classes Java dans la base <strong>de</strong> données<br />
124<br />
$ Pour plus d'informations sur les signatures <strong>de</strong>s métho<strong>de</strong>s Java, reportezvous<br />
à la section "Instruction CREATE PROCEDURE", page 321 du<br />
document ASA Manuel <strong>de</strong> référence SQL.<br />
Renvoi <strong>de</strong> valeurs <strong>de</strong> Java via <strong>de</strong>s procédures stockées<br />
Vous pouvez utiliser les procédures stockées créées à l'ai<strong>de</strong> du paramètre<br />
EXTERNAL NAME LANGUAGE JAVA pour encapsuler <strong>de</strong>s métho<strong>de</strong>s<br />
Java. Cette section explique comment écrire votre métho<strong>de</strong> Java pour qu'elle<br />
exploite les paramètres OUT ou INOUT dans la procédure stockée.<br />
Java ne supporte pas explicitement les paramètres INOUT ou OUT.<br />
Cependant, vous pouvez utiliser un tableau <strong>de</strong> ce paramètre. Par exemple,<br />
pour utiliser un paramètre OUT entier, créez un tableau d'un entier<br />
exactement, en procédant comme suit :<br />
public class TestClass {<br />
public static boolean testOut( int[] param ){<br />
param[0] = 123;<br />
return true;<br />
}<br />
}<br />
La procédure suivante utilise la métho<strong>de</strong> testOut :<br />
CREATE PROCEDURE sp_testOut ( OUT p INTEGER )<br />
EXTERNAL NAME ’TestClass/testOut ([I)Z’<br />
LANGUAGE JAVA<br />
La chaîne ([I)Z est une signature <strong>de</strong> métho<strong>de</strong> Java qui indique que la<br />
métho<strong>de</strong> ne comporte qu'un seul paramètre, qui est un tableau d'entiers, et<br />
renvoie une valeur booléenne. Vous <strong>de</strong>vez définir la métho<strong>de</strong> <strong>de</strong> telle<br />
manière que le paramètre OUT ou INOUT à utiliser soit un tableau <strong>de</strong> type<br />
Java correspondant au type <strong>de</strong> données SQL du paramètre OUT ou INOUT.<br />
$ Pour plus d'informations sur la syntaxe à utiliser ainsi que la signature<br />
<strong>de</strong> métho<strong>de</strong>, reportez-vous à la section "Instruction CREATE<br />
PROCEDURE", page 321 du document ASA Manuel <strong>de</strong> référence SQL.<br />
$ Pour plus d'informations, reportez-vous à la section "Conversions entre<br />
types <strong>de</strong> données Java et SQL", page 91 du document ASA Manuel <strong>de</strong><br />
référence SQL.
Gestion <strong>de</strong> la sécurité pour Java<br />
Le gestionnaire <strong>de</strong><br />
sécurité par défaut<br />
Contrôle <strong>de</strong>s E/S<br />
<strong>de</strong> fichiers Java à<br />
l'ai<strong>de</strong> du<br />
gestionnaire <strong>de</strong><br />
sécurité par défaut<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Java dispose <strong>de</strong> gestionnaires <strong>de</strong> sécurité qui permettent <strong>de</strong> contrôler l'accès<br />
<strong>de</strong>s utilisateurs à <strong>de</strong>s fonctionnalités d'application sensibles en termes <strong>de</strong><br />
sécurité, notamment l'accès aux fichiers et au réseau. <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> offre le support suivant pour les gestionnaires <strong>de</strong> sécurité Java<br />
dans la base <strong>de</strong> données :<br />
♦ <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est doté d'un gestionnaire <strong>de</strong> sécurité par<br />
défaut.<br />
♦ Vous pouvez intégrer votre propre gestionnaire <strong>de</strong> sécurité.<br />
$ Pour plus d'informations, reportez-vous à la section "Mise en<br />
oeuvre <strong>de</strong> votre propre gestionnaire <strong>de</strong> sécurité", page 126.<br />
Le gestionnaire <strong>de</strong> sécurité par défaut est la classe<br />
com.sybase.asa.jrt.SAGenericSecurityManager. Il exécute les tâches<br />
suivantes :<br />
1 Vérification <strong>de</strong> la valeur <strong>de</strong> l'option <strong>de</strong> base <strong>de</strong> données<br />
JAVA_INPUT_OUTPUT.<br />
2 Vérification du serveur <strong>de</strong> base <strong>de</strong> données pour voir s'il a été démarré<br />
en mo<strong>de</strong> <strong>de</strong> sécurité C2 à l'ai<strong>de</strong> <strong>de</strong> l'option du serveur <strong>de</strong> base <strong>de</strong><br />
données -sc.<br />
3 Interdiction d'utilisation <strong>de</strong>s fonctionnalités d'E/S <strong>de</strong> fichiers Java si la<br />
propriété <strong>de</strong> connexion est définie avec la valeur OFF.<br />
4 Interdiction d'accès aux packages java.net si le serveur <strong>de</strong> base <strong>de</strong><br />
données fonctionne avec le mo<strong>de</strong> <strong>de</strong> sécurité C2.<br />
5 Lorsque le gestionnaire <strong>de</strong> sécurité empêche un utilisateur d'accé<strong>de</strong>r à<br />
une fonctionnalité, il renvoie java.lang.SecurityException.<br />
$ Pour plus d'informations, reportez-vous aux sections "Option<br />
JAVA_INPUT_OUTPUT", page 629 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration et "Option <strong>de</strong> serveur -sc", page 162 du document ASA<br />
<strong>Gui<strong>de</strong></strong> d’administration.<br />
Le contrôle <strong>de</strong>s E/S <strong>de</strong> fichiers Java est effectué par l'intermédiaire <strong>de</strong><br />
l'option <strong>de</strong> base <strong>de</strong> données JAVA_INPUT_OUTPUT. Par défaut, cette<br />
option est définie avec la valeur OFF, rendant ainsi les E/S <strong>de</strong> fichier<br />
impossibles.<br />
v Pour autoriser l'accès aux fichiers à l'ai<strong>de</strong> du gestionnaire <strong>de</strong><br />
sécurité par défaut :<br />
♦ Affectez à l'option JAVA_INPUT_OUTPUT la valeur ON :<br />
SET OPTION JAVA_INPUT_OUTOUT=’ON’<br />
125
Fonctionnalités spéciales <strong>de</strong>s classes Java dans la base <strong>de</strong> données<br />
Mise en oeuvre <strong>de</strong> votre propre gestionnaire <strong>de</strong> sécurité<br />
Exemple<br />
126<br />
Pour mettre en oeuvre votre propre gestionnaire <strong>de</strong> sécurité, vous <strong>de</strong>vez<br />
exécuter plusieurs étapes.<br />
v Pour définir votre propre gestionnaire <strong>de</strong> sécurité :<br />
1 Mettez en oeuvre une classe qui étend java.lang.SecurityManager.<br />
La classe SecurityManager comporte plusieurs métho<strong>de</strong>s qui permettent<br />
<strong>de</strong> vérifier si une action particulière est autorisée. Si l'action est<br />
autorisée, la métho<strong>de</strong> renvoie une valeur en mo<strong>de</strong> non détaillé. Si la<br />
métho<strong>de</strong> renvoie une valeur, une exception SecurityException est<br />
déclenchée.<br />
Vous <strong>de</strong>vez remplacer les métho<strong>de</strong>s qui régissent les actions que vous<br />
souhaitez autoriser par <strong>de</strong>s métho<strong>de</strong>s qui renvoient une valeur en mo<strong>de</strong><br />
non détaillé. Cette opération peut être effectuée en mettant en oeuvre la<br />
métho<strong>de</strong> public void.<br />
2 Affectez votre gestionnaire <strong>de</strong> sécurité aux utilisateurs appropriés.<br />
Pour affecter <strong>de</strong>s gestionnaires <strong>de</strong> sécurité à un utilisateur, utilisez les<br />
procédures stockées système add_user_security_manager,<br />
update_user_security_manager et <strong>de</strong>lete_user_security_manager. Par<br />
exemple, pour affecter la classe MonGestionnaireSécurité en tant que<br />
gestionnaire <strong>de</strong> sécurité pour un utilisateur, exécutez la comman<strong>de</strong><br />
suivante :<br />
call dbo.add_user_security_manager(<br />
nom_utilisateur, 'MonGestionnaireSécurité', NULL )<br />
La classe suivante autorise la lecture <strong>de</strong> fichiers mais interdit l'écriture :<br />
public class MonGestionnaireSécurité extends<br />
SecurityManager<br />
{ public void checkRead(FileDescriptor) {}<br />
public void checkRead(String) {}<br />
public void checkRead(String, Object) {}<br />
}<br />
Les métho<strong>de</strong>s SecurityManager.checkWrite ne sont pas remplacées et<br />
empêchent toute opération d'écriture sur les fichiers. Les métho<strong>de</strong>s<br />
checkRead renvoient une valeur, en mo<strong>de</strong> non détaillé, autorisant ainsi<br />
l'action.
Stockage <strong>de</strong>s objets Java<br />
Remarques<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Les valeurs Java sont stockées <strong>de</strong> façon sérialisée. Cela signifie que chaque<br />
ligne inclut les informations suivantes :<br />
♦ un i<strong>de</strong>ntificateur <strong>de</strong> version,<br />
♦ un i<strong>de</strong>ntificateur <strong>de</strong> la classe (ou <strong>de</strong> la sous-classe) enregistrée,<br />
♦ les valeurs <strong>de</strong> champs non statiques et non transitoires <strong>de</strong> la classe,<br />
♦ <strong>de</strong>s informations sur l'overhead.<br />
La définition <strong>de</strong> classe n’est pas enregistrée pour chaque ligne.<br />
L'i<strong>de</strong>ntificateur fournit une référence <strong>de</strong> définition <strong>de</strong> classe unique.<br />
Vous pouvez utiliser <strong>de</strong>s objets Java sans connaître précisément leur<br />
fonctionnement, mais leur mo<strong>de</strong> <strong>de</strong> stockage a une inci<strong>de</strong>nce sur les<br />
performances. C'est pourquoi nous vous donnons les quelques informations<br />
qui suivent.<br />
♦ Espace disque L'overhead par ligne varie entre 10 et 15 octets. Si la<br />
classe intègre une seule variable, le stockage requis par l'overhead peut<br />
être i<strong>de</strong>ntique à celui requis par la variable. En revanche, si la classe<br />
intègre plusieurs variables, l'overhead est négligeable.<br />
♦ Performances Chaque fois qu'une valeur Java est insérée ou mise à<br />
jour, elle doit être sérialisée par la machine virtuelle Java. De même,<br />
chaque fois qu'une valeur Java est utilisée dans une requête, elle doit être<br />
désérialisée par la machine virtuelle. Cela risque d'affecter<br />
considérablement les performances.<br />
Pour éviter cela, utilisez <strong>de</strong>s colonnes calculées.<br />
♦ In<strong>de</strong>x L'utilisation d'in<strong>de</strong>x sur <strong>de</strong>s colonnes Java n'est pas très sélective<br />
et n'offre pas les avantages associés aux in<strong>de</strong>x appliqués à <strong>de</strong>s données<br />
SQL simples.<br />
♦ Sérialisation Si une classe comprend une métho<strong>de</strong> readObject ou<br />
writeObject, celles-ci sont appelées lors <strong>de</strong> la sérialisation ou<br />
désérialisation <strong>de</strong> l'instance. L'utilisation d'une métho<strong>de</strong> readObject ou<br />
writeObject peut influer sur les performances, car là encore la machine<br />
virtuelle Java est appelée.<br />
127
Stockage <strong>de</strong>s objets Java<br />
Objets Java et versions <strong>de</strong> classe<br />
Accès aux lignes<br />
lors <strong>de</strong> la mise à<br />
jour d'une classe<br />
Objets<br />
inaccessibles<br />
128<br />
Les objets Java enregistrés dans la base <strong>de</strong> données sont persistant, c'est-àdire<br />
qu'ils existent même si aucun co<strong>de</strong> n'est exécuté. Vous pouvez ainsi<br />
effectuer les actions suivantes :<br />
1 Installer une classe.<br />
2 Créer une table en utilisant cette classe comme type <strong>de</strong> données pour une<br />
colonne.<br />
3 Insérer <strong>de</strong>s lignes dans la table.<br />
4 Installer une nouvelle version <strong>de</strong> la classe.<br />
Mais comment utiliser les lignes existantes dans la nouvelle version <strong>de</strong> la<br />
classe ?<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> offre <strong>de</strong>s fonctionnalités <strong>de</strong> gestion <strong>de</strong> version <strong>de</strong><br />
classe qui assurent la compatibilité entre les nouvelles et les anciennes<br />
classes. Les règles d'accès aux anciennes valeurs sont les suivantes :<br />
♦ Si l'ancienne version <strong>de</strong> la classe comportait un champ sérialisable, mais<br />
que la nouvelle version n'en comporte aucun ou en comporte un non<br />
sérialisable, ce champ est ignoré.<br />
♦ Si la nouvelle version <strong>de</strong> la classe comporte un champ sérialisable, mais<br />
que l'ancienne version n'en comportait aucun ou en comportait un non<br />
sérialisable, ce champ est réinitialisé à sa valeur par défaut. La valeur<br />
par défaut est NULL (0) pour les types primitifs, FALSE pour les<br />
valeurs booléennes et NULL pour les références d'objets.<br />
♦ Si l'ancienne version incluait une superclasse, mais que la nouvelle n'en<br />
inclut aucune, les données <strong>de</strong> celle-ci sont ignorées.<br />
♦ Si la nouvelle version inclut une superclasse, mais que l'ancienne n'en<br />
comportait aucune, les données <strong>de</strong> celle-ci sont réinitialisées à leurs<br />
valeurs par défaut.<br />
♦ Si le type <strong>de</strong> champ sérialisable est différent d'une version à l'autre, ce<br />
champ est réinitialisé sur les paramètres par défaut. Les conversions <strong>de</strong><br />
types ne sont pas supportées, conformément à la sérialisation Sun<br />
Microsystems.<br />
Un objet sérialisé est inaccessible si sa classe ou n'importe laquelle <strong>de</strong> ses<br />
superclasses a été supprimée <strong>de</strong> la base <strong>de</strong> données, quel que soit le moment<br />
<strong>de</strong> cette suppression. Ce comportement est conforme à la sérialisation Sun<br />
Microsystems.
Déplacement<br />
d'objets entre<br />
bases <strong>de</strong> données<br />
Utilisation <strong>de</strong> la<br />
nouvelle classe<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Le transfert d'objets d'une base <strong>de</strong> données à une autre est possible, même si<br />
les versions <strong>de</strong> classe diffèrent. Le transfert entre bases <strong>de</strong> données suit les<br />
règles suivantes :<br />
♦ Les objets sont répliqués dans une base <strong>de</strong> données distante.<br />
♦ Une table d'objets est déchargée puis rechargée dans une autre base.<br />
♦ Un fichier journal contenant les objets est converti puis appliqué à une<br />
autre base.<br />
La première fois qu'une classe est utilisée, chaque machine virtuelle <strong>de</strong> la<br />
connexion charge sa définition.<br />
Lorsque vous installez (INSTALL) une classe, la machine virtuelle <strong>de</strong> la<br />
connexion est automatiquement redémarrée. De ce fait, vous avez<br />
immédiatement accès à la nouvelle classe.<br />
Pour les autres connexions, la nouvelle classe est chargée lorsque la machine<br />
virtuelle accè<strong>de</strong> à la classe pour la première fois. Si celle-ci est déjà chargée<br />
par une machine virtuelle, la nouvelle classe n'apparaît pour la connexion<br />
correspondante que lorsque la machine virtuelle est redémarrée (par<br />
exemple, à l'ai<strong>de</strong> d'un STOP JAVA et START JAVA).<br />
129
Conception d'une base <strong>de</strong> données Java<br />
Conception d'une base <strong>de</strong> données Java<br />
130<br />
La conception <strong>de</strong>s bases <strong>de</strong> données relationnelles fait l'objet d'une multitu<strong>de</strong><br />
d'informations théoriques et pratiques. Pour plus d'informations sur la<br />
modélisation Entité/Relation et d'autres approches, consultez la<br />
documentation d'introduction au sujet (reportez-vous à la section<br />
"Conception d'une base <strong>de</strong> données", page 3 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong><br />
l’utilisateur SQL) ou <strong>de</strong>s manuels plus avancés.<br />
Aucun corpus comparable, théorique et pratique à la fois, sur le<br />
développement <strong>de</strong>s bases <strong>de</strong> données relationnelles orientées objet n'existe,<br />
et il en est <strong>de</strong> même pour les bases relationnelles orientées Java. Nous nous<br />
contenterons donc ici <strong>de</strong> proposer <strong>de</strong>s suggestions d'utilisation <strong>de</strong> Java dans<br />
le but d'optimiser l'utilisation <strong>de</strong>s bases <strong>de</strong> données relationnelles.<br />
Entités et attributs dans un schéma relationnel et orienté objet<br />
Dans la conception <strong>de</strong> bases <strong>de</strong> données relationnelles, chaque table décrit<br />
une entité. Ainsi, la base <strong>de</strong> données exemple comporte les tables Employee,<br />
Customer, Sales_or<strong>de</strong>r et Department. Les attributs <strong>de</strong> ces entités constituent<br />
les colonnes <strong>de</strong> ces tables : adresse <strong>de</strong>s employés, numéro d'i<strong>de</strong>ntification <strong>de</strong>s<br />
clients, date <strong>de</strong>s bons <strong>de</strong> comman<strong>de</strong>, etc. Chaque ligne <strong>de</strong> la table peut être<br />
considérée comme une instance distincte <strong>de</strong> l'entité : employé, bon <strong>de</strong><br />
comman<strong>de</strong> ou département spécifique.<br />
Dans la <strong>programmation</strong> orientée objet, chaque classe décrit une entité, les<br />
métho<strong>de</strong>s et les champs <strong>de</strong> cette classe décrivant les attributs <strong>de</strong> l'entité.<br />
Chaque instance <strong>de</strong> la classe (chaque objet) conserve une instance distincte<br />
<strong>de</strong> l'entité.<br />
Il peut sembler moins naturel, <strong>de</strong> ce fait, que les colonnes relationnelles<br />
soient basées sur les classes Java. Une correspondance plus naturelle semble<br />
associer la table et la classe.<br />
Entités et attributs dans la pratique<br />
La distinction entre entité et attribut paraît simple, mais la pratique montre<br />
qu'elle n'est pas toujours aussi évi<strong>de</strong>nte.<br />
♦ Une adresse peut être considérée comme l'attribut d'un client. Or, une<br />
adresse est également une entité, qui possè<strong>de</strong> ses propres attributs<br />
comme la rue, la ville, etc.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
♦ De même, un prix peut être considéré comme l'attribut d'un produit.<br />
Toutefois, c'est également une entité qui comprend les attributs montant<br />
et monnaie.<br />
L'utilité <strong>de</strong> la base <strong>de</strong> données relationnelle objet provient justement du fait<br />
qu'il existe <strong>de</strong>ux manières d'exprimer <strong>de</strong>s entités. Vous pouvez, d'une part,<br />
exprimer <strong>de</strong>s entités en tant que tables et, d'autre part, en tant que classes<br />
d'une table. La section suivante illustre ce propos.<br />
Restrictions associées aux bases <strong>de</strong> données relationnelles<br />
Prenons, par exemple, le cas d’une compagnie d’assurance qui souhaite faire<br />
le suivi <strong>de</strong> ses clients. Un client pouvant être considéré comme une entité, il<br />
serait logique <strong>de</strong> ne créer qu'une seule table qui regrouperait tous les clients<br />
<strong>de</strong> la société.<br />
Toutefois, la clientèle <strong>de</strong>s compagnies d'assurance est variée : assurés,<br />
bénéficiaires ou responsables du paiement <strong>de</strong>s primes. Pour chacun d'entre<br />
eux, la compagnie d'assurance a besoin d'informations spécifiques. Par<br />
exemple, l'adresse suffit pour les bénéficiaires. Par contre, il est utile <strong>de</strong><br />
connaître les antécé<strong>de</strong>nts médicaux <strong>de</strong>s assurés. Enfin, <strong>de</strong>s informations<br />
financières peuvent être requises pour le client payant les primes.<br />
Aussi, faut-il mieux gérer séparément ces différents types <strong>de</strong> clients et les<br />
considérer comme <strong>de</strong>s entités distinctes ou considérer le type <strong>de</strong> client<br />
comme un attribut du client ? Les <strong>de</strong>ux solutions ont leurs limites :<br />
♦ Le fait <strong>de</strong> créer <strong>de</strong>s tables distinctes pour chaque type <strong>de</strong> client risque <strong>de</strong><br />
générer une base <strong>de</strong> données très complexe et d'imposer <strong>de</strong>s requêtes<br />
multitables si tous les clients sont concernés.<br />
♦ Mais, d'un autre côté, si vous n'utilisez qu'une seule table, il est difficile<br />
<strong>de</strong> contrôler l'exactitu<strong>de</strong> <strong>de</strong>s informations pour chaque client. En effet,<br />
certaines colonnes n'étant requises que pour certains clients, autoriser<br />
<strong>de</strong>s valeurs NULL permet l'entrée correcte <strong>de</strong>s données, mais ne l'assure<br />
pas. Il n'existe donc aucun moyen simple, dans la base <strong>de</strong> données, <strong>de</strong><br />
limiter le comportement par défaut à un attribut d'une nouvelle entrée.<br />
Utilisation <strong>de</strong>s classes pour pallier les restrictions <strong>de</strong>s bases <strong>de</strong><br />
données relationnelles<br />
Vous pouvez choisir <strong>de</strong> n’utiliser qu’une table <strong>de</strong> clients et <strong>de</strong> n’utiliser que<br />
certaines colonnes avec les classes Java pour pallier les restrictions associées<br />
aux bases <strong>de</strong> données relationnelles.<br />
131
Conception d'une base <strong>de</strong> données Java<br />
132<br />
Supposons, par exemple, que <strong>de</strong>s informations différentes sur les contacts<br />
soient requises pour les assurés et les bénéficiaires. Une approche possible<br />
est <strong>de</strong> définir une colonne fondée sur une classe ContactInformation.<br />
Définissez ensuite les sous-classes Hol<strong>de</strong>rContactInformation et<br />
BeneficiaryContactInformation <strong>de</strong> la classe ContactInformation. Les<br />
nouveaux clients étant entrés par type, vous êtes ainsi certain que les<br />
informations correctes sont spécifiées.<br />
Niveaux d'abstraction <strong>de</strong>s données relationnelles<br />
Les données d'une base <strong>de</strong> données relationnelle peuvent être regroupées en<br />
fonction <strong>de</strong> leur objet. Quelles sont les données appartenant à la classe Java<br />
et quelles sont celles qui sont le mieux adaptées aux colonnes <strong>de</strong> types <strong>de</strong><br />
données simples ?<br />
♦ Colonne d'intégrité référentielle Les colonnes <strong>de</strong> clés primaires et<br />
étrangères incluent généralement <strong>de</strong>s numéros d'i<strong>de</strong>ntification. Ces<br />
numéros peuvent être appelés données référentielles car leur principal<br />
objectif est <strong>de</strong> définir la structure <strong>de</strong> la base <strong>de</strong> données et la relation<br />
entre les tables.<br />
En général, les données référentielles n'appartiennent pas aux classes<br />
Java. Il est recommandé d'utiliser <strong>de</strong>s entiers et autres types <strong>de</strong> données<br />
simples. Toutefois il est possible <strong>de</strong> transformer une colonne <strong>de</strong> classe<br />
Java en une colonne <strong>de</strong> clé primaire.<br />
♦ Données in<strong>de</strong>xées Les colonnes généralement in<strong>de</strong>xées peuvent ne pas<br />
faire partie d'une classe Java. Toutefois, la séparation entre les données<br />
in<strong>de</strong>xées et les données non in<strong>de</strong>xées est mal définie.<br />
Grâce aux colonnes calculées, vous pouvez in<strong>de</strong>xer <strong>de</strong> manière sélective<br />
un champ Java ou une métho<strong>de</strong> (ou, plutôt, d'autres expressions). Si<br />
vous définissez une colonne <strong>de</strong> classe Java, puis que vous choisissez<br />
d'in<strong>de</strong>xer un champ ou une métho<strong>de</strong> <strong>de</strong> cette colonne, utilisez <strong>de</strong>s<br />
colonnes calculées pour créer une nouvelle colonne à partir <strong>de</strong> ce champ<br />
ou <strong>de</strong> cette métho<strong>de</strong>.<br />
$ Pour plus d'informations, reportez-vous à la section "Utilisation <strong>de</strong><br />
colonnes calculées avec les classes Java", page 134.<br />
♦ Données <strong>de</strong>scriptives Les données <strong>de</strong>s colonnes sont souvent <strong>de</strong>s<br />
données <strong>de</strong>scriptives. Utilisées à <strong>de</strong>s fins d'intégrité référentielle, elles<br />
sont rarement in<strong>de</strong>xées, mais souvent utilisées dans les requêtes. Pour<br />
une table d'employés, elles peuvent contenir <strong>de</strong>s informations telles que<br />
la date d'embauche, l'adresse, <strong>de</strong>s informations sur les primes, le salaire,<br />
etc. Il est souvent intéressant <strong>de</strong> combiner ces données dans un plus petit<br />
nombre <strong>de</strong> colonnes <strong>de</strong> type <strong>de</strong> données <strong>de</strong> classe Java.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Les classes permettent l'abstraction à un niveau compris entre la colonne<br />
relationnelle simple et la table relationnelle.<br />
133
Utilisation <strong>de</strong> colonnes calculées avec les classes Java<br />
Utilisation <strong>de</strong> colonnes calculées avec les<br />
classes Java<br />
Utilisation <strong>de</strong>s<br />
colonnes calculées<br />
134<br />
La fonction <strong>de</strong> colonnes calculées simplifie la conception d'une base <strong>de</strong><br />
données Java, facilite l'utilisation <strong>de</strong>s fonctions Java dans les bases <strong>de</strong><br />
données existantes et améliore les performances <strong>de</strong>s types <strong>de</strong> données Java.<br />
Les valeurs d'une colonne calculée proviennent d'autres colonnes. Vous ne<br />
pouvez pas insérer (INSERT) ni mettre à jour (UPDATE) les valeurs <strong>de</strong> ces<br />
colonnes. Toutefois, toute tentative <strong>de</strong> mise à jour d'une colonne calculée<br />
déclenche les triggers associés à cette colonne.<br />
Définition <strong>de</strong>s colonnes calculées<br />
Création <strong>de</strong> tables<br />
avec <strong>de</strong>s colonnes<br />
calculées<br />
Ajout <strong>de</strong> colonnes<br />
calculées dans <strong>de</strong>s<br />
tables<br />
Utilisées avec les classes Java, les colonnes calculées permettent :<br />
♦ D’exploiter une colonne Java Si vous créez une colonne à l'ai<strong>de</strong> d'un<br />
type <strong>de</strong> données <strong>de</strong> classe Java, utilisez les colonnes calculées pour<br />
in<strong>de</strong>xer l'un <strong>de</strong>s champs <strong>de</strong> la classe. Vous pouvez ajouter une colonne<br />
calculée comportant la valeur d'un champ et in<strong>de</strong>xer ce <strong>de</strong>rnier.<br />
♦ D’ajouter une colonne Java dans une table relationnelle Pour utiliser<br />
certaines fonctions <strong>de</strong>s classes Java en modifiant le moins possible une<br />
base <strong>de</strong> données existante, ajoutez une colonne Java calculée, dont les<br />
valeurs seront extraites <strong>de</strong>s autres colonnes <strong>de</strong> la table.<br />
Les colonnes calculées sont déclarées dans l'instruction CREATE TABLE ou<br />
ALTER TABLE.<br />
L'instruction CREATE TABLE suivante permet <strong>de</strong> créer la table product<br />
dans les tables exemple Java.<br />
CREATE TABLE product<br />
(<br />
id INTEGER NOT NULL,<br />
JProd asa<strong>de</strong>mo.Product NOT NULL,<br />
name CHAR(15) COMPUTE ( JProd>>name ),<br />
PRIMARY KEY ("id")<br />
)<br />
L'instruction suivante permet d'ajouter dans la table product une nouvelle<br />
colonne calculée :<br />
ALTER TABLE product<br />
ADD inventory_Value INTEGER<br />
COMPUTE ( JProd.quantity * JProd.unit_price )
Modification <strong>de</strong><br />
l’expression pour<br />
les colonnes<br />
calculées<br />
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Vous pouvez changer l'expression utilisée dans une colonne calculée, à l'ai<strong>de</strong><br />
<strong>de</strong> l'instruction ALTER TABLE. L'instruction suivante change l'expression<br />
sur laquelle s'appuie une colonne calculée :<br />
ALTER TABLE nom_table<br />
ALTER nom_colonne SET COMPUTE ( expression )<br />
La colonne est recalculée lors <strong>de</strong> l'exécution <strong>de</strong> l'instruction. Si la nouvelle<br />
expression n'est pas correcte, l'instruction ALTER TABLE échoue.<br />
L'instruction suivante rétablit une colonne calculée dans son état <strong>de</strong> colonne<br />
normale.<br />
ALTER TABLE nom_table<br />
ALTER nom_colonne DROP COMPUTE<br />
Lorsque cette instruction est exécutée, les valeurs <strong>de</strong> la colonne ne sont pas<br />
modifiées.<br />
Insertion et mise à jour <strong>de</strong> colonnes calculées<br />
Les colonnes calculées ont une inci<strong>de</strong>nce sur les instructions INSERT et<br />
UPDATE vali<strong>de</strong>s. La table jdba.product dans les tables exemple Java<br />
possè<strong>de</strong> une colonne calculée (name) que nous utiliserons pour cet exemple.<br />
La définition <strong>de</strong> la table se présente comme suit :<br />
CREATE TABLE "jdba"."product"<br />
(<br />
"id" INTEGER NOT NULL,<br />
"JProd" asa<strong>de</strong>mo.Product NOT NULL,<br />
"name" CHAR(15) COMPUTE( JProd.name ),<br />
PRIMARY KEY ("id")<br />
)<br />
♦ Pas d'insertions ni <strong>de</strong> mises à jour directes Vous ne pouvez pas<br />
insérer directement une valeur dans une colonne calculée. L'instruction<br />
suivante échoue et renvoie l'erreur Une colonne d’insertion existe en<br />
double :<br />
-- Instruction incorrecte<br />
INSERT INTO PRODUCT (id, name)<br />
VALUES( 3006, 'instruction insert erronée' )<br />
De même, une instruction UPDATE ne peut pas mettre à jour<br />
directement une colonne calculée.<br />
♦ Liste <strong>de</strong>s noms <strong>de</strong> colonne Vous <strong>de</strong>vez toujours spécifier les noms <strong>de</strong><br />
colonne dans les instructions INSERT appliquées à <strong>de</strong>s tables<br />
comportant <strong>de</strong>s colonnes calculées. L'instruction suivante échoue avec<br />
une erreur Le nombre <strong>de</strong> valeurs spécifiées pour INSERT est erroné :<br />
135
Utilisation <strong>de</strong> colonnes calculées avec les classes Java<br />
136<br />
-- Instruction incorrecte<br />
INSERT INTO PRODUCT<br />
VALUES( 3007,new asa<strong>de</strong>mo.Product() )<br />
Vous <strong>de</strong>vez plutôt indiquer la liste <strong>de</strong>s colonnes, comme suit :<br />
INSERT INTO PRODUCT( id, JProd )<br />
VALUES( 3007,new asa<strong>de</strong>mo.Product() )<br />
♦ Triggers Vous pouvez définir <strong>de</strong>s triggers sur une colonne calculée :<br />
toute instruction INSERT ou UPDATE portant sur la colonne<br />
déclenchera le trigger.<br />
A quel moment les colonnes calculées sont recalculées<br />
Les colonnes calculées sont recalculées dans les cas suivants :<br />
♦ Une colonne est supprimée, ajoutée ou renommée.<br />
♦ La table est renommée.<br />
♦ Le type <strong>de</strong> données ou la clause COMPUTE d'une colonne est<br />
modifié(e).<br />
♦ Une ligne est insérée.<br />
♦ Une ligne est mise à jour.<br />
Les colonnes calculées ne sont pas recalculées sur requête. Si vous utilisez<br />
une expression conditionnée par l'heure ou par l'état <strong>de</strong> la base <strong>de</strong> données, la<br />
colonne calculée peut renvoyer un résultat incorrect.
Chapitre 4 Utilisation <strong>de</strong> Java dans la base <strong>de</strong> données<br />
Configuration <strong>de</strong> la mémoire pour Java<br />
Configuration<br />
requise par base<br />
<strong>de</strong> données et par<br />
connexion<br />
Utilisation <strong>de</strong> la mémoire<br />
Cette section décrit comment configurer la mémoire pour exécuter Java dans<br />
la base <strong>de</strong> données et configurer <strong>de</strong> manière appropriée votre serveur.<br />
La mémoire virtuelle Java requiert une quantité <strong>de</strong> mémoire cache<br />
importante.<br />
$ Pour plus d'informations sur l'optimisation du cache, reportez-vous à la<br />
section "Utilisation du cache pour améliorer les performances", page 162 du<br />
document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL.<br />
La mémoire requise par la machine virtuelle Java est allouée par base <strong>de</strong><br />
données et par connexion.<br />
♦ Les conditions par base <strong>de</strong> données ne sont pas transférables : elles ne<br />
peuvent pas être paginées vers le disque. Elles doivent donc tenir dans le<br />
cache du serveur. Ce type <strong>de</strong> mémoire est réservé aux bases <strong>de</strong> données,<br />
et non au serveur. Pour estimer le cache requis, additionnez la mémoire<br />
requise pour chaque base <strong>de</strong> données exécutée sur le serveur.<br />
♦ En revanche, la mémoire requise par connexion est transférable, mais<br />
uniquement en tant qu'unité. Elle peut entièrement rési<strong>de</strong>r dans le cache<br />
ou dans un fichier temporaire.<br />
La mémoire requise par Java dans les bases <strong>de</strong> données est utilisée <strong>de</strong><br />
différentes manières :<br />
♦ Lorsque vous utilisez Java pour la première fois sur un serveur actif, la<br />
machine virtuelle est chargée dans la mémoire et requiert près <strong>de</strong> 1,5 Mo<br />
<strong>de</strong> mémoire. La mémoire utilisée ici fait partie <strong>de</strong> celle réservée à<br />
l'ensemble <strong>de</strong> la base. Une machine virtuelle est chargée pour chaque<br />
base <strong>de</strong> données exploitant Java.<br />
♦ Une nouvelle instance <strong>de</strong> la machine virtuelle est chargée pour chaque<br />
connexion utilisant Java. La nouvelle instance requiert près <strong>de</strong> 200 ko<br />
par connexion.<br />
♦ Chaque définition <strong>de</strong> classe utilisée dans une application Java est<br />
chargée en mémoire. Ce chargement s'opère dans la mémoire <strong>de</strong> la base<br />
<strong>de</strong> données : aucune instance distincte n'est requise pour les connexions<br />
individuelles.<br />
137
Configuration <strong>de</strong> la mémoire pour Java<br />
Gestion <strong>de</strong> la<br />
mémoire<br />
Démarrage et arrêt<br />
<strong>de</strong> la machine<br />
virtuelle<br />
138<br />
♦ Toutes les connexions requièrent un ensemble <strong>de</strong> variables Java<br />
opérationnelles et <strong>de</strong> l'espace dans les piles d'applications (notamment<br />
pour les arguments <strong>de</strong> métho<strong>de</strong>, etc.).<br />
Pour gérer la mémoire, utilisez l'une <strong>de</strong>s métho<strong>de</strong>s suivantes :<br />
♦ Définissez la taille du cache total Vous <strong>de</strong>vez définir un cache<br />
suffisamment grand pour remplir les conditions requises par la mémoire<br />
non transférable.<br />
La taille du cache est définie au démarrage du serveur, à l'ai<strong>de</strong> <strong>de</strong><br />
l'option <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> -c.<br />
Le plus souvent, un cache <strong>de</strong> 8 Mo est suffisant.<br />
♦ Définissez la taille du namespace Il s’agit <strong>de</strong> la taille maximale, en<br />
octets, <strong>de</strong> l'allocation <strong>de</strong> mémoire par base <strong>de</strong> données.<br />
Pour la définir, utilisez l'option JAVA_NAMESPACE_SIZE. Cette<br />
option est globale et ne peut être définie que par un utilisateur détenant<br />
les droits DBA.<br />
♦ Définissez la taille <strong>de</strong>s segments <strong>de</strong> mémoire L’option<br />
JAVA_HEAP_SIZE définit la taille maximale, en octets, <strong>de</strong> la mémoire<br />
par connexion.<br />
Vous pouvez la définir pour chaque connexion mais, dans ce cas, vous<br />
<strong>de</strong>vez détenir les droits DBA car cette option modifie la mémoire<br />
disponible pour les autres utilisateurs.<br />
Vous pouvez non seulement configurer la mémoire pour Java, mais aussi<br />
décharger la machine virtuelle lorsque vous n'utilisez pas Java, à l'ai<strong>de</strong> <strong>de</strong><br />
l'instruction STOP JAVA. Seul un utilisateur détenant les droits DBA peut<br />
exécuter cette instruction. Sa syntaxe est la suivante :<br />
STOP JAVA<br />
La machine virtuelle est chargée chaque fois qu'une opération Java est<br />
exécutée. Pour la charger explicitement en vue <strong>de</strong> l'exécution d'opération<br />
Java, entrez l'instruction suivante :<br />
START JAVA
CHAPITRE 5<br />
Accès aux données via JDBC<br />
Présentation<br />
Sommaire<br />
Ce chapitre décrit comment accé<strong>de</strong>r aux données via JDBC.<br />
JDBC peut être utilisé aussi bien à partir <strong>de</strong>s applications clientes que <strong>de</strong>puis<br />
la base <strong>de</strong> données. En matière d'intégration <strong>de</strong> la logique <strong>de</strong> <strong>programmation</strong><br />
dans la base <strong>de</strong> données, les classes Java utilisant JDBC remplacent<br />
avantageusement les procédures stockées SQL.<br />
Sujet Page<br />
Présentation <strong>de</strong> JBDC 140<br />
Utilisation du gestionnaire JDBC jConnect 147<br />
Utilisation <strong>de</strong> la passerelle JDBC-ODBC 152<br />
Etablissement <strong>de</strong> connexions JDBC 154<br />
Utilisation <strong>de</strong> JDBC pour accé<strong>de</strong>r aux données 162<br />
Création d'applications distribuées 171<br />
139
Présentation <strong>de</strong> JBDC<br />
Présentation <strong>de</strong> JBDC<br />
JDBC et <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong><br />
Ressources JDBC<br />
140<br />
JDBC offre une interface SQL aux applications Java. Pour accé<strong>de</strong>r à <strong>de</strong>s<br />
données relationnelles à partir <strong>de</strong> Java, vous utilisez <strong>de</strong>s appels JDBC.<br />
Ce chapitre n'a pas l'ambition d'être un gui<strong>de</strong> complet <strong>de</strong> l'interface <strong>de</strong> la base<br />
<strong>de</strong> données JDBC. Il se contente <strong>de</strong> proposer quelques exemples simples<br />
pour présenter JDBC et montrer comment l'utiliser sur le client et au sein <strong>de</strong><br />
la base <strong>de</strong> données.<br />
$ Les exemples illustrent les caractéristiques spécifiques <strong>de</strong> l'utilisation<br />
<strong>de</strong> JDBC dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Pour plus d'informations sur la<br />
<strong>programmation</strong> JDBC, reportez-vous à un manuel <strong>de</strong> <strong>programmation</strong> JDBC.<br />
Vous pouvez utiliser JDBC avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> dans les<br />
conditions suivantes :<br />
♦ JDBC sur le client Les applications clientes Java peuvent effectuer <strong>de</strong>s<br />
appels JDBC sur <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. La connexion est établie<br />
par le biais d'un pilote JDBC. SQL <strong>Anywhere</strong> Studio fournit <strong>de</strong>ux<br />
pilotes JDBC: le pilote jConnect pour les applications Java pures et une<br />
passerelle JDBC-ODBC.<br />
Dans ce chapitre, l'expression application cliente concerne à la fois les<br />
applications exécutées sur la machine d'un utilisateur et la logique<br />
exécutée sur un serveur applicatif <strong>de</strong> niveau intermédiaire.<br />
♦ JDBC dans la base <strong>de</strong> données Les classes Java installées dans une<br />
base <strong>de</strong> données peuvent effectuer <strong>de</strong>s appels JDBC pour accé<strong>de</strong>r aux<br />
données d'une base et les modifier par le biais d'un gestionnaire JDBC<br />
interne.<br />
♦ Logiciel requis Pour utiliser le gestionnaire jConnect <strong>de</strong> <strong>Sybase</strong>,<br />
TCP/IP est nécessaire.<br />
Selon votre installation <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, vous disposez peutêtre<br />
déjà du gestionnaire jConnect <strong>de</strong> <strong>Sybase</strong>.<br />
$ Pour plus d'informations sur le gestionnaire jConnect et son<br />
emplacement, reportez-vous à la section "Fichiers du gestionnaire<br />
jConnect", page 147.<br />
♦ Exemples <strong>de</strong> co<strong>de</strong> source Vous trouverez le co<strong>de</strong> source<br />
correspondant aux exemples <strong>de</strong> ce chapitre dans le fichier<br />
Samples\ASA\Java\JDBCExamples.java du répertoire SQL <strong>Anywhere</strong>.<br />
$ Pour plus d'informations sur l'installation <strong>de</strong>s exemples Java, y<br />
compris la classe JDBCExamples, reportez-vous à la section<br />
"Installation <strong>de</strong>s exemples Java", page 92.
Choix d’un pilote JDBC<br />
Structure du programme JDBC<br />
Chapitre 5 Accès aux données via JDBC<br />
Deux pilotes JDBC sont fournis pour <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>:<br />
♦ jConnect Il s’agit d’un pilote 100% pur Java . Il communique avec<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> en utilisant le protocole client/serveur TDS.<br />
♦ passerelle JDBC-ODBC Ce pilote communique avec <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> en utilisant le protocole client/serveur Command Sequence.<br />
Son comportement est conforme à ODBC, embed<strong>de</strong>d SQL, et autres<br />
applications OLE DB.<br />
Lorsque vous choisissez le pilote à utiliser, pensez à prendre en considération<br />
les facteurs suivants:<br />
♦ Fonctions Les <strong>de</strong>ux pilotes sont conformes à JDK 2. La passerelle<br />
JDBC-ODBC fournit <strong>de</strong>s curseurs avec défilement complet, qui ne sont<br />
pas disponibles dans jConnect.<br />
♦ Java pur Le pilote jConnect est une solution Java pure. La passerelle<br />
JDBC-ODBC requiert le pilote ODBC d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
ODBC et n'est pas une solution Java pure.<br />
♦ Performances La passerelle JDBC-ODBC garantit dans la plupart <strong>de</strong>s<br />
cas <strong>de</strong> meilleures performances que le pilote jConnect.<br />
♦ Compatibilité Le protocole TDS, utilisé par le pilote jConnect, est<br />
partagé avec <strong>Adaptive</strong> <strong>Server</strong> Enterprise. Certains aspects du<br />
comportement du pilote dépen<strong>de</strong>nt <strong>de</strong> ce protocole, et sont configurés<br />
pour être compatibles avec <strong>Adaptive</strong> <strong>Server</strong> Enterprise.<br />
Les <strong>de</strong>ux pilotes sont disponibles pour Windows 95/98/Me et Windows<br />
NT/2000/XP, ainsi que pour les systèmes d'exploitation UNIX et Linux<br />
supportés. Ils ne sont disponibles ni pour NetWare, ni pour Windows CE.<br />
La séquence d'événements ci-après est typique d'une application JDBC :<br />
1 Création d'un objet Connection L'appel d'une métho<strong>de</strong> <strong>de</strong> classe<br />
getConnection <strong>de</strong> la classe DriverManager crée un objet Connection<br />
et établit une connexion avec une base <strong>de</strong> données.<br />
2 Génération d'un objet Statement L’objet Connection génère un objet<br />
Statement.<br />
141
Présentation <strong>de</strong> JBDC<br />
142<br />
3 Transmission d’une instruction SQL Une instruction SQL exécutée<br />
dans l'environnement <strong>de</strong> la base <strong>de</strong> données est transmise à l'objet<br />
Statement. Si l'instruction est une requête, l'action renvoie un objet<br />
ResultSet .<br />
L'objet ResultSet, qui contient les données renvoyées après exécution <strong>de</strong><br />
l'instruction SQL, présente celles-ci ligne par ligne (selon un<br />
fonctionnement comparable à celui du curseur).<br />
4 Bouclage sur les lignes du jeu <strong>de</strong> résultats La métho<strong>de</strong> next <strong>de</strong><br />
l'objet ResultSet exécute <strong>de</strong>ux actions :<br />
♦ Avance d'une ligne la ligne courante (celle présentée via l'objet<br />
ResultSet ).<br />
♦ Renvoie une valeur booléenne (vrai/faux) indiquant la présence, ou<br />
non, d'une ligne suivante.<br />
5 Récupération <strong>de</strong>s valeurs <strong>de</strong> chaque ligne Les valeurs <strong>de</strong> chaque<br />
colonne <strong>de</strong> l’objet ResultSet sont récupérées, par i<strong>de</strong>ntification du nom<br />
ou <strong>de</strong> la position <strong>de</strong> la colonne. La métho<strong>de</strong> getDate permet ainsi<br />
d'obtenir la valeur d'une colonne <strong>de</strong> la ligne en cours.<br />
Les objets Java peuvent utiliser les objets JDBC pour interagir avec une base<br />
<strong>de</strong> données et obtenir ainsi <strong>de</strong>s données qu'ils peuvent ensuite manipuler ou<br />
utiliser dans d'autres requêtes.<br />
Fonctionnalités JDBC dans la base <strong>de</strong> données<br />
La version <strong>de</strong> JDBC que vous utilisez à partir <strong>de</strong> Java dans la base <strong>de</strong><br />
données est déterminée par la version du JDK pour lequel la base <strong>de</strong> données<br />
est configurée.<br />
♦ Si votre base <strong>de</strong> données est initialisée avec JDK 1.2 ou JDK 1.3, vous<br />
pouvez utiliser l'API JDBC 2.0.<br />
$ Pour plus d'informations sur la mise à niveau d'une base <strong>de</strong><br />
données vers JDK 1.2 ou JDK 1.3, reportez-vous à la section<br />
"Instruction ALTER DATABASE", page 216 du document ASA Manuel<br />
<strong>de</strong> référence SQL ou "Mise à niveau d'une base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong><br />
l'utilitaire dbupgrad", page 569 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
♦ Si votre base <strong>de</strong> données est initialisée avec JDK 1.1, vous pouvez<br />
utiliser les fonctionnalités <strong>de</strong> JDBC 1.2. Le gestionnaire JDBC interne<br />
pour JDK 1.1 (asajdbc) fournit aux applications Java côté serveur<br />
certaines fonctionnalités <strong>de</strong> JDBC 2.0 mais il n'offre pas un support total<br />
<strong>de</strong> JDBC 2.0.
Chapitre 5 Accès aux données via JDBC<br />
$ Pour plus d'informations, reportez-vous à la section "Utilisation <strong>de</strong>s<br />
fonctionnalités JDBC 2.0 à partir <strong>de</strong> bases <strong>de</strong> données JDK 1.1",<br />
page 143.<br />
Utilisation <strong>de</strong>s fonctionnalités JDBC 2.0 à partir <strong>de</strong> bases <strong>de</strong> données JDK 1.1<br />
Cette section explique comment accé<strong>de</strong>r aux fonctionnalités JDBC 2.0 à<br />
partir <strong>de</strong> bases <strong>de</strong> données initialisées avec le support JDK 1.1. Le plus<br />
souvent, la meilleure solution consiste à mettre à niveau Java dans la base <strong>de</strong><br />
données vers la version 1.3.<br />
Pour les bases <strong>de</strong> données initialisées avec le support JDK 1.1, le package<br />
sybase.sql.ASA contient <strong>de</strong>s fonctionnalités qui font partie <strong>de</strong> JDBC 2.0.<br />
Pour utiliser ces fonctionnalités JDBC 2.0, vous <strong>de</strong>vez convertir vos<br />
objets JDBC en classes correspondantes du package sybase.sql.ASA, au lieu<br />
du package java.sql. Les classes qui sont déclarées dans java.sql sont<br />
limitées aux fonctionnalités <strong>de</strong> JDBC 1.2.<br />
Les classes du package sybase.sql.ASA sont les suivantes :<br />
Classe JDBC Classe <strong>de</strong> gestionnaire interne <strong>Sybase</strong><br />
java.sql.Connection sybase.sql.ASA.SAConnection<br />
java.sql.Statement sybase.sql.ASA.SAStatement<br />
java.sql.PreparedStatement sybase.sql.ASA.SAPreparedStatement<br />
java.sql.CallableStatement sybase.sql.ASA.SACallableStatement<br />
java.sql.ResultSetMetaData sybase.sql.ASA.SAResultSetMetaData<br />
java.sql.ResultSet sybase.sql.SAResultSet<br />
java.sql.DatabaseMetaData sybase.sql.SADatabaseMetaData<br />
La fonction suivante offre un objet ResultSetMetaData pour une instruction<br />
préparée sans qu'un objet ResultSet ou l'exécution d'une instruction soit<br />
nécessaire. Cette fonction ne fait pas partie du standard JDBC 1.2.<br />
ResultSetMetaData<br />
sybase.sql.ASA.SAPreparedStatement.<strong>de</strong>scribe()<br />
Le co<strong>de</strong> suivant permet <strong>de</strong> lire la ligne précé<strong>de</strong>nte dans un jeu <strong>de</strong> résultats ;<br />
cette fonctionnalité n'est pas supportée dans JDBC 1.2.<br />
import java.sql.*;<br />
import sybase.sql.asa.*;<br />
ResultSet rs;<br />
// co<strong>de</strong> supplémentaire ici<br />
( ( sybase.sql.asa.SAResultSet)rs ).previous();<br />
143
Présentation <strong>de</strong> JBDC<br />
Restrictions<br />
concernant<br />
JDBC 2.0<br />
144<br />
Les classes suivantes font partie <strong>de</strong> l’interface basique <strong>de</strong> JDBC 2.0, mais ne<br />
sont pas disponibles dans le package sybase.sql.ASA :<br />
♦ java.sql.Blob<br />
♦ java.sql.Clob<br />
♦ java.sql.Ref<br />
♦ java.sql.Struct<br />
♦ java.sql.Array<br />
♦ java.sql.Map<br />
Les fonctions basiques JDBC 2.0 suivantes ne sont pas disponibles dans le<br />
package sybase.sql.ASA :
Classe dans<br />
sybase.sql.ASA<br />
Chapitre 5 Accès aux données via JDBC<br />
Fonctions manquantes<br />
SAConnection java.util.Map getTypeMap()<br />
void setTypeMap( java.util.Map map )<br />
SAPreparedStatement void setRef( int pidx, java.sql.Ref r )<br />
void setBlob( int pidx, java.sql.Blob b )<br />
void setClob( int pidx, java.sql.Clob c )<br />
void setArray( int pidx, java.sql.Array a )<br />
SACallableStatement Object getObject( pidx, java.util.Map map )<br />
java.sql.Ref getRef( int pidx )<br />
java.sql.Blob getBlob( int pidx )<br />
java.sql.Clob getClob( int pidx )<br />
java.sql.Array getArray( int pidx )<br />
SAResultSet Object getObject( int cidx, java.util.Map map )<br />
java.sql.Ref getRef( int cidx )<br />
java.sql.Blob getBlob( int cidx )<br />
java.sql.Clob getClob( int cidx )<br />
java.sql.Array getArray( int cidx )<br />
Object getObject( String cName, java.util.Map map )<br />
java.sql.Ref getRef( String cName )<br />
java.sql.Blob getBlob( String cName )<br />
java.sql.Clob getClob( String cName )<br />
java.sql.Array getArray( String cName )<br />
Différences entre les connexions JDBC côté client et côté serveur<br />
La distinction entre JDBC sur le client et JDBC dans le serveur <strong>de</strong> base <strong>de</strong><br />
données porte sur la manière dont s'établissent les connexions avec<br />
l'environnement <strong>de</strong> la base.<br />
145
Présentation <strong>de</strong> JBDC<br />
146<br />
♦ Côté client Pour JDBC côté client, l'établissement d'une connexion<br />
requiert le gestionnaire JDBC jConnect <strong>de</strong> <strong>Sybase</strong> ou la passerelle<br />
JDBC-ODBC d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Le passage <strong>de</strong>s arguments à<br />
la métho<strong>de</strong> DriverManager.getConnection établit la connexion. Du<br />
point <strong>de</strong> vue <strong>de</strong> l'application cliente, l'environnement <strong>de</strong> base <strong>de</strong> données<br />
est une application externe.<br />
♦ Côté serveur Lorsque JDBC est utilisé à partir du serveur <strong>de</strong> base <strong>de</strong><br />
données, une connexion existe déjà. Une valeur <strong>de</strong><br />
jdbc:<strong>de</strong>fault:connection est transmise à<br />
DriverManager.getConnection qui autorise alors l'application JDBC à<br />
travailler via la connexion utilisateur en cours. Rapi<strong>de</strong> et efficace, cette<br />
opération est également sûre puisque l'application cliente a déjà rempli<br />
les conditions <strong>de</strong> sécurité <strong>de</strong> la base <strong>de</strong> données pour établir la<br />
connexion. L'ID utilisateur et le mot <strong>de</strong> passe ont déjà été fournis et il<br />
n'est pas nécessaire <strong>de</strong> recommencer l'opération. Le gestionnaire JDBC<br />
interne peut se connecter uniquement à la base <strong>de</strong> données <strong>de</strong> la<br />
connexion courante.<br />
Vous pouvez écrire <strong>de</strong>s classes JDBC <strong>de</strong> sorte qu'elles puissent être<br />
exécutées à la fois sur le client et sur le serveur : pour ce faire, utilisez une<br />
seule instruction conditionnelle pour la construction <strong>de</strong> l'URL. Une<br />
connexion externe requiert le nom <strong>de</strong> la machine et le numéro <strong>de</strong> port, tandis<br />
que la connexion interne requiert jdbc:<strong>de</strong>fault:connection.
Chapitre 5 Accès aux données via JDBC<br />
Utilisation du gestionnaire JDBC jConnect<br />
Pour utiliser JDBC <strong>de</strong>puis une application cliente ou une applet, vous <strong>de</strong>vez<br />
vous connecter à <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> via le gestionnaire JDBC<br />
jConnect.<br />
jConnect est fourni avec SQL <strong>Anywhere</strong> Studio. Si vous avez reçu<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> en tant qu'élément d'un autre package, vous ne<br />
disposerez pas nécessairement <strong>de</strong> jConnect. Or, pour utiliser JDBC <strong>de</strong>puis<br />
<strong>de</strong>s applications clientes, il vous faut jConnect. En revanche, vous pouvez<br />
utiliser JDBC dans la base <strong>de</strong> données sans jConnect.<br />
Fichiers du gestionnaire jConnect<br />
Définition <strong>de</strong> la<br />
variable<br />
CLASSPATH pour<br />
jConnect<br />
Le gestionnaire JDBC jConnect est installé dans un ensemble <strong>de</strong> sousrépertoires<br />
du répertoire <strong>Sybase</strong>\Shared. Deux versions <strong>de</strong> jConnect sont<br />
fournies :<br />
♦ jConnect 4.5 Cette version est utilisée pour le développement<br />
d'applications JDK 1.1. jConnect 4.5 est installé dans le répertoire<br />
<strong>Sybase</strong>\Shared\jConnect-4_5.<br />
jConnect 4.5 est fourni sous la forme d'un ensemble <strong>de</strong> classes.<br />
♦ jConnect 5.5 Cette version est utilisée pour le développement<br />
d'applications JDK version 1.2 ou ultérieure. jConnect 5.5 est installé<br />
dans le répertoire <strong>Sybase</strong>\Shared\jConnect-5_5.<br />
jConnect 5.5 est fourni sous la forme d'un fichier JAR nommé<br />
jconn2.jar.<br />
Les exemples <strong>de</strong> ce chapitre reposent sur l'utilisation <strong>de</strong> jConnect 5.5. Les<br />
utilisateurs <strong>de</strong> jConnect 4.5 doivent effectuer les adaptations appropriées.<br />
Pour que votre application utilise jConnect, les classes jConnect doivent<br />
figurer dans la variable d'environnement CLASSPATH lors <strong>de</strong> la<br />
compilation et <strong>de</strong> l'exécution afin que le compilateur et l'environnement<br />
d'exécution Java puissent localiser les fichiers requis.<br />
La comman<strong>de</strong> suivante ajoute le gestionnaire jConnect 5.5 dans une variable<br />
d'environnement CLASSPATH existante, où chemin correspond au<br />
répertoire <strong>Sybase</strong>\Shared.<br />
set classpath=%classpath%;chemin\jConnect-5_5\classes\jconn2.jar<br />
La comman<strong>de</strong> suivante ajoute le gestionnaire jConnect 4.5 dans une variable<br />
d'environnement CLASSPATH existante :<br />
set classpath=%classpath%;chemin\jConnect-4_5\classes<br />
147
Utilisation du gestionnaire JDBC jConnect<br />
Importation <strong>de</strong>s<br />
classes jConnect<br />
148<br />
Les classes <strong>de</strong> jConnect sont toutes dans le package com.sybase.<br />
Si vous utilisez jConnect 5.5, votre application doit accé<strong>de</strong>r aux classes dans<br />
com.sybase.jdbc2.jdbc. Vous <strong>de</strong>vez importer ces classes au début <strong>de</strong> chaque<br />
fichier source :<br />
import com.sybase.jdbc2.jdbc.*<br />
Si vous utilisez jConnect 4.5, les classes se trouvent dans com.sybase.jdbc.<br />
Vous <strong>de</strong>vez les importer au début <strong>de</strong> chaque fichier source :<br />
import com.sybase. jdbc.*<br />
Installation <strong>de</strong>s objets système jConnect dans une base <strong>de</strong><br />
données<br />
Si vous envisagez d'accé<strong>de</strong>r aux informations <strong>de</strong> la table système<br />
(métadonnées <strong>de</strong> la base) via jConnect, ajoutez tout d'abord les objets<br />
système jConnect à la base.<br />
Par défaut, les objets système jConnect sont ajoutés dans toutes les bases <strong>de</strong><br />
données nouvelles. Vous pouvez ajouter les objets jConnect dans la base <strong>de</strong><br />
données au moment <strong>de</strong> sa création, <strong>de</strong> sa mise à niveau ou ultérieurement.<br />
Vous pouvez installer les objets système jConnect <strong>de</strong>puis <strong>Sybase</strong> Central ou<br />
par le biais d'Interactive SQL.<br />
v Pour ajouter <strong>de</strong>s objets système jConnect dans une base <strong>de</strong><br />
données à partir <strong>de</strong> <strong>Sybase</strong> Central :<br />
1 Connectez-vous à la base sous l'ID d'un utilisateur détenant les droits<br />
DBA.<br />
2 Dans le volet gauche <strong>de</strong> <strong>Sybase</strong> Central, cliquez avec le bouton droit sur<br />
l'icône <strong>de</strong> la base <strong>de</strong> données et choisissez Installer le support <strong>de</strong><br />
métadonnées jConnect dans le menu contextuel.<br />
v Pour ajouter <strong>de</strong>s objets système jConnect dans une base <strong>de</strong><br />
données à partir d'Interactive SQL :<br />
♦ Connectez-vous à la base <strong>de</strong>puis Interactive SQL sous l'ID d'un<br />
utilisateur détenant les droits DBA, puis entrez la comman<strong>de</strong> suivante<br />
dans le volet Instructions SQL :<br />
read chemin\scripts\jcatalog.sql<br />
chemin correspondant au répertoire SQL <strong>Anywhere</strong>.
Chapitre 5 Accès aux données via JDBC<br />
Conseil<br />
Vous pouvez également utiliser une invite <strong>de</strong> comman<strong>de</strong>s pour ajouter les<br />
objets système jConnect dans une base <strong>de</strong> données. A l'invite <strong>de</strong><br />
comman<strong>de</strong>s, tapez :<br />
dbisql -c "uid=utilisateur;pwd=mdp"<br />
chemin\scripts\jcatalog.sql<br />
où utilisateur et mdp i<strong>de</strong>ntifient un utilisateur détenant les droits DBA et<br />
chemin, le répertoire SQL <strong>Anywhere</strong>.<br />
Chargement du gestionnaire jConnect<br />
Pour pouvoir utiliser jConnect dans votre application, vous <strong>de</strong>vez charger le<br />
gestionnaire en entrant l'instruction suivante :<br />
Class.forName("com.sybase.jdbc2.jdbc.SybDriver").newInstance();<br />
Fourniture d’une URL au serveur<br />
Le fait d'utiliser la métho<strong>de</strong> newInstance simplifie les choses dans certains<br />
navigateurs.<br />
Pour vous connecter à une base <strong>de</strong> données via jConnect, vous <strong>de</strong>vez fournir<br />
l'URL (Universal Resource Locator) <strong>de</strong> la base. La section "Connexion à<br />
partir d'une application JDBC cliente avec jConnect", page 154 donne une<br />
exemple :<br />
StringBuffer temp = new StringBuffer();<br />
// Utilise gestionnaire jConnect...<br />
temp.append("jdbc:sybase:Tds:");<br />
// pour connexion sur nom machine indiqué...<br />
temp.append(_coninfo);<br />
// sur numéro <strong>de</strong> port par défaut pour ASA...<br />
temp.append(":2638");<br />
// puis connexion.<br />
System.out.println(temp.toString());<br />
conn = DriverManager.getConnection(temp.toString() ,<br />
_props );<br />
L'URL est composée <strong>de</strong> la manière suivante :<br />
jdbc:sybase:Tds:machine-name:port-number<br />
Les différents composants sont les suivants :<br />
♦ jdbc:sybase:Tds Le gestionnaire JDBC jConnect <strong>de</strong> <strong>Sybase</strong>, qui utilise<br />
le protocole d'application TDS.<br />
149
Utilisation du gestionnaire JDBC jConnect<br />
150<br />
♦ machine-name Le nom ou l’adresse IP <strong>de</strong> la machine sur laquelle le<br />
serveur est exécuté. Pour une connexion entre homologues, vous pouvez<br />
utiliser localhost, qui désigne la machine courante.<br />
♦ port number Le numéro du port sur lequel le serveur <strong>de</strong> la base <strong>de</strong><br />
données est en réception. Le numéro <strong>de</strong> port affecté à<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est le 2638. Si rien ne s'y oppose<br />
spécifiquement, utilisez ce numéro.<br />
La chaîne <strong>de</strong> connexion ne doit pas comporter plus <strong>de</strong> 253 caractères.<br />
Spécification d'une base <strong>de</strong> données sur un serveur<br />
Une ou plusieurs base <strong>de</strong> données peuvent être simultanément chargées sur<br />
un serveur <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. L'URL, telle qu'indiquée plus haut,<br />
spécifie un serveur, et non une base <strong>de</strong> données. La tentative <strong>de</strong> connexion<br />
est effectuée vers la base <strong>de</strong> données par défaut sur le serveur.<br />
Vous pouvez spécifier une base <strong>de</strong> données particulière en indiquant une<br />
forme étendue <strong>de</strong> l'URL, selon l'une <strong>de</strong>s métho<strong>de</strong>s ci-après.<br />
Utilisation du<br />
paramètre<br />
ServiceName<br />
Utilisation du<br />
paramètre<br />
RemotePWD<br />
jdbc:sybase:Tds:machine-name:port-number?ServiceName=DBN<br />
Le point d'interrogation suivi d'une série d'affectations est un moyen standard<br />
<strong>de</strong> fournir <strong>de</strong>s arguments à une URL. La casse <strong>de</strong> servicename n'est pas<br />
significative, mais il ne doit pas avoir d'espace <strong>de</strong> part et d'autre du signe =.<br />
Le paramètre DBN est le nom <strong>de</strong> la base <strong>de</strong> données.<br />
La métho<strong>de</strong> la plus courante pour fournir <strong>de</strong>s paramètres <strong>de</strong> connexion<br />
complémentaires tels que le nom <strong>de</strong> la base <strong>de</strong> données ou un fichier <strong>de</strong> base<br />
<strong>de</strong> données est d'utiliser le champ RemotePWD. Pour définir RemotePWD<br />
comme champ Properties, utilisez la métho<strong>de</strong> setRemotePassword().<br />
L'exemple <strong>de</strong> co<strong>de</strong> ci-<strong>de</strong>ssous montre comment utiliser le champ.<br />
sybDrvr = (SybDriver)Class.forName(<br />
"com.sybase.jdbc2.jdbc.SybDriver" ).newInstance();<br />
props = new Properties();<br />
props.put( "User", "DBA" );<br />
props.put( "Password", "SQL" );<br />
sybDrvr.setRemotePassword(<br />
null, "dbf=asa<strong>de</strong>mo.db", props );<br />
Connection con = DriverManager.getConnection(<br />
"jdbc:sybase:Tds:localhost", props );<br />
Via le paramètre <strong>de</strong> fichier <strong>de</strong> base <strong>de</strong> données DBF, vous pouvez lancer une<br />
base <strong>de</strong> données sur un serveur par le biais <strong>de</strong> jConnect.. Par défaut, la base<br />
est lancée avec autostop=YES. Si vous spécifiez un DBF ou DBN <strong>de</strong><br />
utility_db, la base <strong>de</strong> données utility est automatiquement lancée.
Chapitre 5 Accès aux données via JDBC<br />
$ Pour plus d'informations, reportez-vous à la section "Utilisation <strong>de</strong> la<br />
base <strong>de</strong> données utility", page 241 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Définition <strong>de</strong>s options <strong>de</strong> base <strong>de</strong> données pour les connexions jConnect<br />
Lorsqu'une application se connecte à une base <strong>de</strong> données en utilisant le<br />
pilote jConnect, il fait appel à <strong>de</strong>ux procédures stockées:<br />
1 sp_tsql_environment définit certaines options <strong>de</strong> base <strong>de</strong> données pour<br />
assurer la compatibilité avec le comportement d'<strong>Adaptive</strong> <strong>Server</strong><br />
Enterprise.<br />
2 Puis la procédure spt_mda est appelée, qui définit d'autres options, dont<br />
la procédure spt_mda, qui détermine le paramètrage <strong>de</strong><br />
QUOTED_IDENTIFIER. Il est nécessaire <strong>de</strong> modifier la procédure<br />
spt_mda pour modifier le comportement par défaut.<br />
151
Utilisation <strong>de</strong> la passerelle JDBC-ODBC<br />
Utilisation <strong>de</strong> la passerelle JDBC-ODBC<br />
Fichiers requis<br />
Etablissement<br />
d’une connexion<br />
152<br />
La passerelle JDBC-ODBC fournit un pilote JDBC qui, comparé au pilote<br />
JDBC jConnect Java pur, offre certains avantages en termes <strong>de</strong> fonctions et<br />
<strong>de</strong> performances, mais qui n'est pas une solution Java pure.<br />
$ Pour obtenir <strong>de</strong>s informations sur le choix du pilote JDBC à utiliser,<br />
reportez-vous à la rubrique "Choix d'un pilote JDBC", page 141.<br />
Le composant Java <strong>de</strong> la passerelle JDBC-ODBC est inclus dans le fichier<br />
jodbc.jar, installé dans le sous-répertoire Java du répertoire d'installation <strong>de</strong><br />
SQL <strong>Anywhere</strong>. Pour Windows, le composant natif est dbjodbc8.dll, dans le<br />
sous-répertoire win32 du répertoire d'installation <strong>de</strong> SQL <strong>Anywhere</strong>. Pour<br />
UNIX et Linux, le composant natif est dbjodbc8.so. Ce composant doit se<br />
trouver dans le chemin d'accès système. Lorsque <strong>de</strong>s applications utilisant ce<br />
pilote sont déployées, vous <strong>de</strong>vez également déployer les fichiers du pilote<br />
ODBC.<br />
Le co<strong>de</strong> suivant illustre la façon d'établir une connexion en utilisant la<br />
passerelle JDBC-ODBC:<br />
String driver, url;<br />
Connection conn;<br />
driver="ianywhere.ml.jdbcodbc.IDriver";<br />
url = "jdbc:odbc:dsn=ASA 8.0 Sample";<br />
Class.forName( driver );<br />
conn = DriverManager.getConnection( url );<br />
Il y a différents points à noter concernant ce co<strong>de</strong>:<br />
♦ Etant donné que les classes sont chargées à l'ai<strong>de</strong> <strong>de</strong> Class.forName, il<br />
n'est pas nécessaire que le package contenant la passerelle JDBC-ODBC<br />
soit importé en suivant les instructions import.<br />
♦ jodbc.jar doit se trouver dans le chemin d'accès aux classes lorsque vous<br />
lancez l'application.<br />
♦ L'URL contient jdbc:odbc:, suivi d'une chaîne <strong>de</strong> connexion ODBC<br />
standard. La chaîne <strong>de</strong> connexion est en général une source <strong>de</strong> données<br />
ODBC, mais vous pouvez également utiliser <strong>de</strong>s paramètres <strong>de</strong><br />
connexion explicitement séparés par <strong>de</strong>s points-virgules en complément<br />
ou à la place <strong>de</strong> la source <strong>de</strong> données. Pour plus d'informations sur les<br />
paramètres pouvant être utilisés dans une chaîne <strong>de</strong> connexion, reportezvous<br />
à la rubrique "Paramètres <strong>de</strong> connexion", page 75 du document<br />
ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Si vous n'utilisez pas <strong>de</strong> source <strong>de</strong> données, il est nécessaire <strong>de</strong> spécifier<br />
le pilote ODBC à utiliser en incluant le paramètre du pilote dans votre<br />
chaîne <strong>de</strong> connexion:
Jeux <strong>de</strong> caractères<br />
Chapitre 5 Accès aux données via JDBC<br />
url = "jdbc:odbc:";<br />
url += "driver=<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> 8.0;...";<br />
Sous UNIX, la passerelle JDBC-ODBC n’utilise pas d’appels ou <strong>de</strong> liaisons<br />
unico<strong>de</strong> ODBC, et n'effectue pas <strong>de</strong> conversions <strong>de</strong> caractères. L'envoi <strong>de</strong><br />
données non ASCII par le biais <strong>de</strong> la passerelle a pour effet <strong>de</strong> détruire les<br />
données.<br />
Sous Windows, la passerelle JDBC-ODBC utilise les appels et les liaisons<br />
unico<strong>de</strong> ODBC pour convertir entre eux les jeux <strong>de</strong> caractères.<br />
153
Etablissement <strong>de</strong> connexions JDBC<br />
Etablissement <strong>de</strong> connexions JDBC<br />
154<br />
Cette section présente les classes permettant d'établir une connexion JDBC à<br />
une base <strong>de</strong> données <strong>de</strong>puis une application Java. Dans les exemples sont<br />
utilisés soit jConnect (côté client), soit Java dans la base <strong>de</strong> données (côté<br />
serveur). Pour <strong>de</strong>s informations sur l'établissement <strong>de</strong> connexions par le biais<br />
<strong>de</strong> la passerelle JDBC-ODBC, reportez-vous à la rubrique "Utilisation <strong>de</strong> la<br />
passerelle JDBC-ODBC", page 152.<br />
Connexion à partir d'une application JDBC cliente avec jConnect<br />
Co<strong>de</strong> <strong>de</strong> l’exemple <strong>de</strong> connexion externe<br />
Pour accé<strong>de</strong>r aux tables système d'une base <strong>de</strong> données (c'est-à-dire à ses<br />
métadonnées) <strong>de</strong>puis une application JDBC, vous <strong>de</strong>vez au préalable ajouter<br />
un jeu d'objets système JConnect à votre base. Les classes du gestionnaire<br />
JDBC interne et jConnect partagent les procédures stockées pour le support<br />
<strong>de</strong>s métadonnées. Ces procédures sont installées dans toutes les bases par<br />
défaut. L'option –i <strong>de</strong> dbinit empêche cette installation.<br />
$ Pour plus d'informations sur l'ajout d'objets système jConnect dans une<br />
base <strong>de</strong> données, reportez-vous à la section "Utilisation du gestionnaire<br />
JDBC jConnect", page 147.<br />
L'application Java suivante est une application complète <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong>, qui établit une connexion à une base <strong>de</strong> données active, imprime<br />
un ensemble d'informations sur votre ligne <strong>de</strong> comman<strong>de</strong>, puis interrompt<br />
son exécution.<br />
Avant toute chose, une application JDBC doit établir une connexion pour<br />
pouvoir travailler sur les données d'une base.<br />
$ L'exemple ci-après présente une connexion externe (une connexion<br />
client/serveur classique). Pour plus d'informations sur la création d'une<br />
connexion interne à partir <strong>de</strong> classes Java exécutées au sein du serveur <strong>de</strong><br />
base <strong>de</strong> données, reportez-vous à la section "Etablissement d'une connexion à<br />
partir d'une classe JDBC côté serveur", page 158.<br />
Le co<strong>de</strong> ci-après est le co<strong>de</strong> source <strong>de</strong>s métho<strong>de</strong>s utilisées pour établir une<br />
connexion. Ce co<strong>de</strong> source figure dans la métho<strong>de</strong> main et la métho<strong>de</strong><br />
ASAConnect du fichier JDBCExamples.java, placé dans le sous-répertoire<br />
Samples\ASA\Java du répertoire SQL <strong>Anywhere</strong> :
Chapitre 5 Accès aux données via JDBC<br />
import java.sql.*; // JDBC<br />
import com.sybase.jdbc2.jdbc.*; // <strong>Sybase</strong> jConnect<br />
import java.util.Properties; // Propriétés<br />
import sybase.sql.*; // Utilitaires <strong>Sybase</strong><br />
import asa<strong>de</strong>mo.*; // Exemples <strong>de</strong> classes<br />
public class JDBCExamples{<br />
private static Connection conn;<br />
public static void main( String args[] ){<br />
// Etablit une connexion<br />
conn = null;<br />
String machineName = ( args.length == 1 ? args[0] :<br />
"localhost" );<br />
ASAConnect( "DBA", "SQL", machineName );<br />
if( conn!=null ) {<br />
System.out.println( "Réussite connexion" );<br />
}else{<br />
System.out.println( "Echec connexion" );<br />
}<br />
);<br />
}<br />
}<br />
try{<br />
getObjectColumn();<br />
getObjectColumnCastClass();<br />
insertObject();<br />
}<br />
catch( Exception e ){<br />
System.out.println( "Erreur : " + e.getMessage()<br />
e.printStackTrace();<br />
155
Etablissement <strong>de</strong> connexions JDBC<br />
156<br />
private static void ASAConnect( String userID,<br />
String password,<br />
String machineName ) {<br />
// Connexion à <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
String coninfo = new String( machineName );<br />
Properties props = new Properties();<br />
props.put( "user", userID );<br />
props.put( "password", password );<br />
props.put("DYNAMIC_PREPARE", "true");<br />
// Charge jConnect<br />
try {<br />
Class.forName( "com.sybase.jdbc2.jdbc.SybDriver"<br />
).newInstance();<br />
String dbURL = "jdbc:sybase:Tds:" + machineName +<br />
":2638/?JCONNECT_VERSION=5";<br />
System.out.println( dbURL );<br />
conn = DriverManager.getConnection( dbURL , props<br />
);<br />
}<br />
catch ( Exception e ) {<br />
System.out.println( "Erreur : " + e.getMessage()<br />
);<br />
e.printStackTrace();<br />
}<br />
}<br />
Fonctionnement <strong>de</strong> l’exemple <strong>de</strong> connexion externe<br />
Importation <strong>de</strong><br />
packages<br />
L’exemple <strong>de</strong> connexion externe est une application Java <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong>.<br />
L'application requiert plusieurs bibliothèques, importées selon les premières<br />
lignes <strong>de</strong> JDBCExamples.java :<br />
♦ Le package java.sql contient les classes JDBC <strong>de</strong> Sun Microsystems ,<br />
requises pour toutes les applications JDBC. Elles se trouvent dans le<br />
fichier classes.zip du sous-répertoire Java.<br />
♦ Le gestionnaire JDBC jConnect <strong>de</strong> <strong>Sybase</strong>, importé <strong>de</strong>puis<br />
com.sybase.jdbc2.jdbc, est requis pour toutes les applications<br />
connectées via jConnect.<br />
♦ L'application utilise une liste <strong>de</strong> propriétés. La classe<br />
java.util.Properties est requise pour la gestion <strong>de</strong>s listes <strong>de</strong> propriétés.<br />
Elle se trouve dans le fichier classes.zip du sous-répertoire Java.<br />
♦ Le package asa<strong>de</strong>mo contient <strong>de</strong>s classes utilisées dans certains<br />
exemples. Ils se trouve dans le fichier Samples\ASA\Java\asa<strong>de</strong>mo.jar.
La métho<strong>de</strong> main<br />
La métho<strong>de</strong><br />
ASAConnect<br />
Chapitre 5 Accès aux données via JDBC<br />
Chaque application Java nécessite une classe dotée d'une métho<strong>de</strong> main, qui<br />
est la métho<strong>de</strong> appelée au démarrage du programme. Dans notre exemple,<br />
JDBCExamples.main est la seule métho<strong>de</strong> <strong>de</strong> l'application.<br />
La métho<strong>de</strong> JDBCExamples.main effectue les tâches suivantes :<br />
1 Elle traite l'argument <strong>de</strong> la ligne <strong>de</strong> comman<strong>de</strong> en utilisant le nom <strong>de</strong><br />
machine si celui-ci est fourni. Par défaut, le nom <strong>de</strong> la machine est<br />
localhost, ce qui convient très bien pour le serveur <strong>de</strong> base <strong>de</strong> données<br />
personnel.<br />
2 Elle appelle la métho<strong>de</strong> ASAConnect pour établir une connexion.<br />
3 Elle exécute plusieurs métho<strong>de</strong>s qui font défiler <strong>de</strong>s données sur votre<br />
ligne <strong>de</strong> comman<strong>de</strong>.<br />
La métho<strong>de</strong> JDBCExamples.ASAConnect effectue les tâches suivantes :<br />
1 Elle établit une connexion à la base <strong>de</strong> données active par défaut via<br />
jConnect <strong>de</strong> <strong>Sybase</strong>.<br />
♦ Class.forName charge jConnect. Le fait d'utiliser la métho<strong>de</strong><br />
newInstance simplifie les choses dans certains navigateurs.<br />
♦ Les instructions StringBuffer créent une chaîne <strong>de</strong> connexion à<br />
partir <strong>de</strong>s chaînes littérales et du nom <strong>de</strong> machine donnés sur la<br />
ligne <strong>de</strong> comman<strong>de</strong>.<br />
♦ DriverManager.getConnection établit ensuite une connexion à<br />
l'ai<strong>de</strong> <strong>de</strong> la chaîne <strong>de</strong> connexion.<br />
2 Elle repasse la main à la métho<strong>de</strong> d'appel.<br />
Exécution <strong>de</strong> l'exemple <strong>de</strong> connexion externe<br />
Cette section présente la procédure d'exécution <strong>de</strong> l'exemple <strong>de</strong> connexion<br />
externe.<br />
v Pour créer et exécuter l'application exemple <strong>de</strong> connexion externe :<br />
1 Ouvrez la fenêtre <strong>de</strong> comman<strong>de</strong>s.<br />
2 Positionnez-vous dans le répertoire SQL <strong>Anywhere</strong>.<br />
3 Positionnez-vous dans le sous-répertoire Samples\ASA\Java.<br />
4 Assurez-vous que la base <strong>de</strong> données est chargée sur un serveur <strong>de</strong> base<br />
<strong>de</strong> données exécutant TCP/IP. Pour démarrer le serveur sur votre<br />
machine locale, utilisez la comman<strong>de</strong> suivante (à partir du sousrépertoire<br />
Samples\ASA\Java) :<br />
start dbeng8 ..\..\..\asa<strong>de</strong>mo<br />
157
Etablissement <strong>de</strong> connexions JDBC<br />
158<br />
5 Pour exécuter l'exemple, entrez, à l'invite <strong>de</strong> comman<strong>de</strong>s :<br />
java JDBCExamples<br />
Si vous souhaitez répéter l'opération dans un serveur exécuté sur une<br />
autre machine, entrez le nom exact <strong>de</strong> cette machine. Le nom par défaut<br />
est localhost (qui est un alias du nom <strong>de</strong> la machine courante).<br />
6 Confirmez qu'une liste <strong>de</strong> personnes et <strong>de</strong> produits est bien affichée.<br />
En cas d'échec <strong>de</strong> la tentative <strong>de</strong> connexion, c'est un message d'erreur<br />
qui est affiché. Confirmez que vous avez bien exécuté toutes les étapes<br />
requises. Vérifiez que CLASSPATH est correctement définie. Si elle est<br />
incorrecte, CLASSPATH empêche la localisation d'une classe.<br />
$ Pour plus d'informations sur l'utilisation <strong>de</strong> jConnect, reportez-vous à la<br />
section "Utilisation du gestionnaire JDBC jConnect", page 147 et à la<br />
documentation en ligne relative à jConnect.<br />
Etablissement d'une connexion à partir d'une classe JDBC côté<br />
serveur<br />
Dans JDBC, les instructions SQL sont créées à l'ai<strong>de</strong> <strong>de</strong> la métho<strong>de</strong><br />
createStatement d'un objet Connection. Même les classes exécutées dans le<br />
serveur doivent établir une connexion pour créer un objet Connection.<br />
L'établissement d'une connexion à partir d'une classe JDBC côté serveur est<br />
une opération plus simple que l'établissement d'une connexion externe. En<br />
effet, du fait que la classe côté serveur est exécutée par un utilisateur déjà<br />
connecté, la classe utilise directement la connexion active.<br />
Co<strong>de</strong> <strong>de</strong> l'exemple <strong>de</strong> connexion côté serveur<br />
Le co<strong>de</strong> ci-après est le co<strong>de</strong> source <strong>de</strong> l'exemple. Le co<strong>de</strong> source se trouve<br />
dans la métho<strong>de</strong> InternalConnect du fichier<br />
Samples\ASA\Java\JDBCExamples.java du répertoire SQL <strong>Anywhere</strong> :<br />
public static void InternalConnect() {<br />
try {<br />
conn =<br />
DriverManager.getConnection("jdbc:<strong>de</strong>fault:connection");<br />
System.out.println("Salut");<br />
}<br />
catch ( Exception e ) {<br />
System.out.println("Erreur : " + e.getMessage());<br />
e.printStackTrace();<br />
}<br />
}<br />
}
Fonctionnement <strong>de</strong> l'exemple <strong>de</strong> connexion côté serveur<br />
Chapitre 5 Accès aux données via JDBC<br />
Dans cet exemple, InternalConnect() est la seule métho<strong>de</strong> utilisée dans<br />
l'application.<br />
L'application ne requiert qu'une <strong>de</strong>s bibliothèques (JDBC) importées selon la<br />
première ligne <strong>de</strong> la classe JDBCExamples.java. Les autres sont requises<br />
pour les connexions externes. Le package java.sql contient les classes JDBC.<br />
La métho<strong>de</strong> InternalConnect() effectue les tâches suivantes :<br />
1 Elle établit une connexion à la base <strong>de</strong> données active par défaut via la<br />
connexion courante.<br />
♦ DriverManager.getConnection établit ensuite une connexion à<br />
l'ai<strong>de</strong> <strong>de</strong> la chaîne <strong>de</strong> connexion jdbc:<strong>de</strong>fault:connection.<br />
2 Elle imprime Salut dans la sortie standard courante, à savoir la fenêtre<br />
du serveur. System.out.println exécute l'impression.<br />
3 En cas d'erreur lors <strong>de</strong> la tentative <strong>de</strong> connexion, un message d'erreur<br />
précisant l'endroit où cette <strong>de</strong>rnière se produit est imprimé dans la<br />
fenêtre du serveur.<br />
Les instructions try et catch offrent un cadre <strong>de</strong> gestion <strong>de</strong>s erreurs.<br />
4 Elle met fin à la classe.<br />
Exécution <strong>de</strong> l'exemple <strong>de</strong> connexion côté serveur<br />
Cette section présente la procédure d'exécution <strong>de</strong> l'exemple <strong>de</strong> connexion<br />
côté serveur.<br />
v Pour créer et exécuter l'application exemple <strong>de</strong> connexion interne :<br />
1 Si ce n’est déjà fait, compilez le fichier JDBCExamples.java. Si vous<br />
utilisez le JDK, vous pouvez le faire dans le répertoire<br />
Samples\ASA\Java à partir d'une invite <strong>de</strong> comman<strong>de</strong>s :<br />
javac JDBCExamples.java<br />
2 Lancez un serveur <strong>de</strong> base <strong>de</strong> données à partir <strong>de</strong> la base <strong>de</strong> données<br />
exemple. Pour démarrer le serveur sur votre machine locale, utilisez la<br />
comman<strong>de</strong> suivante (à partir du sous-répertoire Samples\ASA\Java) :<br />
start dbeng8 ..\..\..\asa<strong>de</strong>mo<br />
Le protocole réseau TCP/IP n'est pas nécessaire puisque jConnect n'est<br />
pas utilisé.<br />
159
Etablissement <strong>de</strong> connexions JDBC<br />
160<br />
3 Installez la classe dans la base <strong>de</strong> données exemple. Une fois connecté à<br />
la base <strong>de</strong> données exemple, entrez la comman<strong>de</strong> suivante à partir<br />
d'Interactive SQL :<br />
INSTALL JAVA NEW<br />
FROM FILE<br />
’chemin\Samples\ASA\Java\JDBCExamples.class’<br />
où chemin est le chemin d'accès à votre répertoire d'installation.<br />
Vous pouvez aussi installer la classe à l'ai<strong>de</strong> <strong>de</strong> <strong>Sybase</strong> Central. Toujours<br />
connecté à la base <strong>de</strong> données exemple, ouvrez le dossier Objets Java et<br />
double-cliquez sur Ajouter une classe Java. Ensuite, suivez les<br />
instructions fournies par l'assistant.<br />
4 Désormais, vous pouvez appeler la métho<strong>de</strong> InternalConnect <strong>de</strong> cette<br />
classe comme s'il s'agissait d'une procédure stockée.<br />
CALL JDBCExamples>>InternalConnect()<br />
La première fois qu'une classe Java est appelée au cours d'une session, la<br />
JVM interne doit être chargée. Cette opération peut prendre quelques<br />
secon<strong>de</strong>s.<br />
5 Vérifiez que le message Salut est bien imprimé dans la fenêtre du<br />
serveur.<br />
Remarques sur les connexions JDBC<br />
♦ Mo<strong>de</strong> AutoCommit La spécification JDBC impose, par défaut,<br />
l'exécution d'une instruction COMMIT à l'issue <strong>de</strong> toute instruction<br />
modifiant les données. Actuellement, le comportement <strong>de</strong> JDBC côté<br />
serveur est d'effectuer la validation. Pour définir ce mo<strong>de</strong>, utilisez une<br />
instruction telle que :<br />
conn.setAutoCommit( false );<br />
où conn est l'objet <strong>de</strong> connexion courant.<br />
♦ Valeurs <strong>de</strong> connexion par défaut Côté serveur JDBC, seul le premier<br />
appel à getConnection( "jdbc:<strong>de</strong>fault:connection" ) crée une nouvelle<br />
connexion avec les valeurs par défaut. Les appels suivants renvoient un<br />
encapsulage <strong>de</strong> la connexion courante, toutes les propriétés <strong>de</strong><br />
connexion étant inchangées. Si vous désactivez AutoCommit (OFF)<br />
dans votre connexion initiale, tous les appels getConnection suivants au<br />
sein du même co<strong>de</strong> Java renvoient une connexion avec AutoCommit sur<br />
OFF.
Chapitre 5 Accès aux données via JDBC<br />
Vous pouvez <strong>de</strong>man<strong>de</strong>r que les propriétés <strong>de</strong> la connexion soient<br />
réinitialisées à leurs valeurs par défaut une fois la connexion fermée, <strong>de</strong><br />
sorte que les connexions suivantes soient établies avec les valeurs JDBC<br />
standard. Pour ce faire, écrivez un co<strong>de</strong> du type :<br />
Connection conn = DriverManager.getConnection("");<br />
boolean oldAutoCommit = conn.getAutoCommit();<br />
try {<br />
// co<strong>de</strong> ici<br />
}<br />
finally {<br />
conn.setAutoCommit( oldAutoCommit );<br />
}<br />
Cela ne s'applique pas uniquement à AutoCommit, mais également aux<br />
autres propriétés <strong>de</strong> la connexion telles que TransactionIsolation et<br />
isReadOnly.<br />
161
Utilisation <strong>de</strong> JDBC pour accé<strong>de</strong>r aux données<br />
Utilisation <strong>de</strong> JDBC pour accé<strong>de</strong>r aux données<br />
Préparation <strong>de</strong>s exemples<br />
Co<strong>de</strong> exemple<br />
162<br />
Les applications Java qui disposent <strong>de</strong> tout ou partie <strong>de</strong>s classes dans la base<br />
<strong>de</strong> données sont considérablement avantagées par rapport aux procédures<br />
stockées SQL traditionnelles. Dans cette phase <strong>de</strong> prise en main, il peut<br />
cependant être utile <strong>de</strong> faire un parallèle avec les procédures stockées SQL<br />
pour mettre en évi<strong>de</strong>nce les capacités <strong>de</strong> JDBC. Dans les exemples suivants,<br />
nous allons écrire <strong>de</strong>s classes Java qui insèrent une ligne dans la table<br />
Department.<br />
Comme avec les autres interfaces, les instructions SQL dans JDBC peuvent<br />
être soit statiques, soit dynamiques. Les instructions SQL statiques sont<br />
créées dans l'application Java, puis envoyées à la base <strong>de</strong> données. Le<br />
serveur <strong>de</strong> base <strong>de</strong> données analyse l'instruction, élabore un plan d'exécution,<br />
puis exécute l'instruction. Les phases d'analyse et d'élaboration du plan<br />
d'exécution constituent la préparation <strong>de</strong> l’instruction.<br />
Si une même instruction doit être exécutée plusieurs fois (plusieurs insertions<br />
dans une table, par exemple), une instruction SQL statique peut entraîner un<br />
overhead important puisque la préparation doit être effectuée à chaque<br />
occurrence.<br />
En revanche, une instruction SQL dynamique contient <strong>de</strong>s marques <strong>de</strong><br />
réservation. L'instruction est préparée une seule fois, à l'ai<strong>de</strong> <strong>de</strong> ces marques<br />
<strong>de</strong> réservation, puis exécutée autant <strong>de</strong> fois que nécessaire sans nouvelle<br />
préparation.<br />
Dans la présente section, nous utiliserons <strong>de</strong>s instructions SQL statiques. Les<br />
instructions SQL dynamiques seront abordées ultérieurement, dans une autre<br />
section.<br />
Cette section décrit la préparation <strong>de</strong>s exemples pour leur utilisation dans le<br />
reste du chapitre.<br />
Les échantillons <strong>de</strong> co<strong>de</strong> présentés dans cette section sont issus <strong>de</strong> la classe<br />
complète Samples\ASA\Java\JDBCExamples.java.<br />
v Pour installer la classe JDBCExamples :<br />
1 Si ce n'est pas déjà fait, installez le fichier JDBCExamples.class dans la<br />
base <strong>de</strong> données exemple. Une fois connecté à la base <strong>de</strong> données<br />
exemple à partir d'Interactive SQL, entrez la comman<strong>de</strong> suivante dans le<br />
volet Instructions SQL :<br />
INSTALL JAVA NEW
Chapitre 5 Accès aux données via JDBC<br />
FROM FILE<br />
’chemin\Samples\ASA\Java\JDBCExamples.class’<br />
où chemin est le chemin d'accès à votre répertoire d'installation.<br />
Vous pouvez aussi installer la classe à l'ai<strong>de</strong> <strong>de</strong> <strong>Sybase</strong> Central. Toujours<br />
connecté à la base <strong>de</strong> données exemple, ouvrez le dossier Objets Java et<br />
double-cliquez sur Ajouter une classe Java. Ensuite, suivez les<br />
instructions fournies par l'assistant.<br />
Insertions, mises à jour et suppressions avec JDBC<br />
L’objet Statement exécute <strong>de</strong>s instructions SQL statiques. Ainsi, l'exécution<br />
d'instructions SQL telles que INSERT, UPDATE et DELETE, qui ne<br />
retournent pas <strong>de</strong> jeux <strong>de</strong> résultats, s'opère à l'ai<strong>de</strong> <strong>de</strong> la métho<strong>de</strong><br />
executeUpdate <strong>de</strong> l'objet Statement. Les instructions telles que<br />
CREATE TABLE, et autres instructions <strong>de</strong> définition <strong>de</strong>s données, peuvent<br />
aussi être exécutées à l'ai<strong>de</strong> <strong>de</strong> executeUpdate.<br />
Le co<strong>de</strong> suivant montre la procédure d'exécution d'instructions INSERT dans<br />
JDBC. Il utilise une connexion interne contenue dans l'objet Connection<br />
conn. Le co<strong>de</strong> permettant d'insérer <strong>de</strong>s valeurs à partir d'une application<br />
externe via JDBC suppose d'utiliser une autre connexion, sinon il reste<br />
inchangé.<br />
public static void InsertFixed() {<br />
// retourne la connexion courante<br />
conn =<br />
DriverManager.getConnection("jdbc:<strong>de</strong>fault:connection");<br />
// Désactivation autocommit<br />
conn.setAutoCommit( false );<br />
Statement stmt = conn.createStatement();<br />
Integer IRows = new Integer( stmt.executeUpdate<br />
("INSERT INTO Department (<strong>de</strong>pt_id, <strong>de</strong>pt_name )"<br />
+ "VALUES (201, 'Eastern Sales')"<br />
) );<br />
// Impression nombre <strong>de</strong> lignes mises à jour<br />
System.out.println(IRows.toString() + " row<br />
inserted" );<br />
}<br />
Co<strong>de</strong> source disponible<br />
Cet échantillon <strong>de</strong> co<strong>de</strong> appartient à la métho<strong>de</strong> InsertFixed <strong>de</strong> la classe<br />
JDBCExamples, disponible dans le sous-répertoire Samples\ASA\Java<br />
<strong>de</strong> votre répertoire d'installation.<br />
163
Utilisation <strong>de</strong> JDBC pour accé<strong>de</strong>r aux données<br />
Remarques<br />
164<br />
♦ La métho<strong>de</strong> setAutoCommit désactive AutoCommit (OFF), <strong>de</strong> sorte<br />
que les modifications ne sont validées que si une instruction COMMIT<br />
explicite est exécutée.<br />
♦ La métho<strong>de</strong> executeUpdate retourne un entier correspondant au nombre<br />
<strong>de</strong> lignes affectées par l'opération. Dans le cas présent, une instruction<br />
INSERT réussie renverrait la valeur un (1).<br />
♦ Le type <strong>de</strong> l'entier renvoyé est converti en objet Integer. La classe<br />
Integer, qui constitue une encapsulation du type <strong>de</strong> données <strong>de</strong> base int,<br />
inclut quelques métho<strong>de</strong>s fort utiles telles que toString().<br />
♦ L'entier IRows est converti en chaîne pour être imprimé. La sortie est<br />
dirigée vers la fenêtre du serveur.<br />
v Pour exécuter l'exemple JDBC Insert :<br />
1 Via Interactive SQL, connectez-vous à la base <strong>de</strong> données exemple avec<br />
l'ID utilisateur DBA.<br />
2 Vérifiez que la classe JDBCExamples est installée. Elle est installée<br />
avec les autres exemples <strong>de</strong> classes Java.<br />
$ Pour plus d'informations sur l'installation <strong>de</strong>s exemples <strong>de</strong> classes<br />
Java, reportez-vous à la section "Installation <strong>de</strong>s exemples Java",<br />
page 92.<br />
3 Appelez la métho<strong>de</strong> comme suit :<br />
CALL JDBCExamples>>InsertFixed()<br />
4 Vérifiez qu'une ligne a été ajoutée dans la table <strong>de</strong>partment.<br />
SELECT *<br />
FROM <strong>de</strong>partment<br />
Cette ligne, dotée <strong>de</strong> l'ID 201, n'est pas validée. Vous pouvez exécuter<br />
un ROLLBACK pour supprimer la ligne.<br />
Dans cet exemple, nous avons vu comment créer une classe JDBC très<br />
rudimentaire. Dans les exemples suivants, nous verrons comment l'étoffer.<br />
Transmission d'arguments à <strong>de</strong>s métho<strong>de</strong>s Java<br />
Nous allons maintenant compléter la métho<strong>de</strong> InsertFixed, ce qui va nous<br />
permettre d'abor<strong>de</strong>r la transmission d'arguments aux métho<strong>de</strong>s Java.<br />
La métho<strong>de</strong> suivante utilise <strong>de</strong>s arguments transmis dans l'appel sous forme<br />
<strong>de</strong> valeurs à insérer :<br />
public static void InsertArguments(
Remarques<br />
try {<br />
Chapitre 5 Accès aux données via JDBC<br />
String id, String name) {<br />
conn = DriverManager.getConnection(<br />
"jdbc:<strong>de</strong>fault:connection" );<br />
String sqlStr = "INSERT INTO Department "<br />
+ " ( <strong>de</strong>pt_id, <strong>de</strong>pt_name )"<br />
+ " VALUES (" + id + ", ’" + nom + "’)";<br />
// Exécution <strong>de</strong> l'instruction<br />
Statement stmt = conn.createStatement();<br />
Integer IRows = new Integer( stmt.executeUpdate(<br />
sqlStr.toString() ) );<br />
// Impression du nombre <strong>de</strong> lignes mises à jour<br />
System.out.println(IRows.toString() + "ligne<br />
insérée" );<br />
}<br />
catch ( Exception e ) {<br />
System.out.println("Erreur : " + e.getMessage());<br />
e.printStackTrace();<br />
}<br />
}<br />
♦ Les <strong>de</strong>ux arguments sont l'ID du département (un entier) et son nom<br />
(une chaîne). Dans le cas présent, ces <strong>de</strong>ux arguments sont transmis à la<br />
métho<strong>de</strong> sous forme <strong>de</strong> chaîne, puisqu'ils sont utilisés comme éléments<br />
<strong>de</strong> la chaîne d'instruction SQL.<br />
♦ L'instruction INSERT est statique et elle ne prend aucun paramètre en<br />
plus <strong>de</strong> l'instruction elle-même.<br />
♦ Si vous vous trompez dans le nombre ou le type <strong>de</strong>s arguments, l'erreur<br />
La procédure est introuvable est renvoyée.<br />
v Pour utiliser une métho<strong>de</strong> Java avec <strong>de</strong>s arguments :<br />
1 Si ce n'est pas déjà fait, installez le fichier JDBCExamples.class dans la<br />
base <strong>de</strong> données exemple.<br />
2 Pour ce faire, connectez-vous à la base <strong>de</strong> données exemple à partir<br />
d'Interactive SQL, puis entrez la comman<strong>de</strong> suivante :<br />
call JDBCExamples>>InsertArguments( ’203’, ’Northern<br />
Sales’ )<br />
3 Vérifiez qu'une nouvelle ligne a bien été ajoutée à la table Department :<br />
SELECT *<br />
FROM Department<br />
4 Annulez les modifications pour laisser la base intacte :<br />
165
Utilisation <strong>de</strong> JDBC pour accé<strong>de</strong>r aux données<br />
Requêtes avec JDBC<br />
Exécution <strong>de</strong><br />
l'exemple<br />
166<br />
ROLLBACK<br />
L’objet Statement permet d'exécuter <strong>de</strong>s requêtes statiques, ainsi que <strong>de</strong>s<br />
instructions qui ne retournent pas <strong>de</strong> jeux <strong>de</strong> résultats. Pour exécuter <strong>de</strong>s<br />
requêtes, utilisez la métho<strong>de</strong> executeQuery <strong>de</strong> l'objet Statement. Le jeu <strong>de</strong><br />
résultats est alors retourné dans un objet ResultSet.<br />
L'échantillon <strong>de</strong> co<strong>de</strong> ci-après montre comment les requêtes peuvent être<br />
gérées dans JDBC. Il place la valeur totale d'inventaire d'un produit dans une<br />
variable nommée inventory. Le nom du produit est contenu dans la variable<br />
String prodname. Cet exemple figure dans la métho<strong>de</strong> Query <strong>de</strong> la classe<br />
JDBCExamples.<br />
Il suppose qu'une connexion interne ou externe a été établie et qu'elle est<br />
maintenue dans l'objet Connection nommé conn.<br />
public static int Query () {<br />
int max_price = 0;<br />
try{<br />
conn = DriverManager.getConnection(<br />
"jdbc:<strong>de</strong>fault:connection" );<br />
// Création <strong>de</strong> la requête<br />
String sqlStr = "SELECT id, unit_price "<br />
+ "FROM product" ;<br />
// Exécution <strong>de</strong> l'instruction<br />
Statement stmt = conn.createStatement();<br />
ResultSet result = stmt.executeQuery( sqlStr );<br />
while( result.next() ) {<br />
int price = result.getInt(2);<br />
System.out.println( "Le prix est " + price );<br />
if( price > max_price ) {<br />
max_price = price ;<br />
}<br />
}<br />
}<br />
catch( Exception e ) {<br />
System.out.println("Erreur : " + e.getMessage());<br />
e.printStackTrace();<br />
}<br />
return max_price;<br />
}<br />
Une fois la classe JDBCExamples installée dans la base <strong>de</strong> données<br />
exemple, vous pouvez exécuter cette métho<strong>de</strong> à l'ai<strong>de</strong> <strong>de</strong> l'instruction<br />
suivante dans Interactive SQL :
Remarques<br />
select JDBCExamples>>Query()<br />
Chapitre 5 Accès aux données via JDBC<br />
♦ La requête sélectionne la quantité et le prix unitaire <strong>de</strong> tous les produits<br />
nommés prodname. Les résultats sont renvoyés dans l'objet ResultSet<br />
nommé result.<br />
♦ Une boucle d'itération est appliquée sur chacune <strong>de</strong>s lignes du jeu <strong>de</strong><br />
résultats. Cette boucle utilise la métho<strong>de</strong> next.<br />
♦ Pour chaque ligne, la valeur <strong>de</strong> chaque colonne est extraite sous forme<br />
<strong>de</strong> variable entière, à l'ai<strong>de</strong> <strong>de</strong> la métho<strong>de</strong> getInt. ResultSet comprend<br />
aussi <strong>de</strong>s métho<strong>de</strong>s pour d'autres types <strong>de</strong> données, telles que getString,<br />
getDate et getBinaryString.<br />
Pour la métho<strong>de</strong> getInt, l'argument est un numéro d'in<strong>de</strong>x pour la<br />
colonne (à partir <strong>de</strong> 1).<br />
La conversion <strong>de</strong> type <strong>de</strong> données <strong>de</strong> SQL en Java est assurée selon la<br />
métho<strong>de</strong> présentée dans la section "Conversions <strong>de</strong> types <strong>de</strong> données<br />
SQL en Java", page 92 du document ASA Manuel <strong>de</strong> référence SQL.<br />
♦ <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte les curseurs à défilement<br />
bidirectionnel. Toutefois, JDBC propose uniquement la métho<strong>de</strong> next,<br />
qui correspond à un défilement vers l'avant dans le jeu <strong>de</strong> résultats.<br />
♦ La métho<strong>de</strong> retourne la valeur <strong>de</strong> max_price à l'environnement appelant<br />
et Interactive SQL l'affiche dans le volet Résultats.<br />
Utilisation d'instructions préparées pour un accès optimisé<br />
Exemple<br />
Avec l’interface Statement, vous analysez chaque instruction envoyée à la<br />
base <strong>de</strong> données, vous générez un plan d'accès et vous exécutez l'instruction.<br />
Les étapes préalables à l'exécution correspon<strong>de</strong>nt à la préparation <strong>de</strong><br />
l’instruction.<br />
Avec l’interface PreparedStatement, vous pouvez considérablement gagner<br />
en performances. En effet, vous pouvez ainsi préparer une instruction dotée<br />
<strong>de</strong> marques <strong>de</strong> réservation, auxquelles vous affectez ensuite <strong>de</strong>s valeurs à son<br />
exécution.<br />
Le recours aux instructions préparées est particulièrement utile pour effectuer<br />
plusieurs actions i<strong>de</strong>ntiques, par exemple pour insérer plusieurs lignes.<br />
$ Pour plus d'informations sur les instructions préparées, reportez-vous à<br />
la section "Préparation <strong>de</strong>s instructions", page 12.<br />
L'exemple suivant décrit comment utiliser l'interface PreparedStatement,<br />
bien que l'insertion d'une seule ligne ne constitue pas une utilisation optimale<br />
<strong>de</strong>s instructions préparées.<br />
167
Utilisation <strong>de</strong> JDBC pour accé<strong>de</strong>r aux données<br />
Exécution <strong>de</strong><br />
l'exemple<br />
168<br />
La métho<strong>de</strong> ci-après <strong>de</strong> la classe JDBCExamples effectue une exécution<br />
préparée :<br />
public static void JInsertPrepared(int id, String name)<br />
try {<br />
conn = DriverManager.getConnection(<br />
"jdbc:<strong>de</strong>fault:connection" );<br />
// Création <strong>de</strong> l'instruction INSERT<br />
// ? est un caractère <strong>de</strong> marque <strong>de</strong> réservation<br />
String sqlStr = "INSERT INTO Department "<br />
+ " ( <strong>de</strong>pt_id, <strong>de</strong>pt_name )"<br />
+ "VALUES ( ? , ? )" ;<br />
// Préparation <strong>de</strong> l'instruction<br />
PreparedStatement stmt = conn.prepareStatement(<br />
sqlStr );<br />
stmt.setInt(1, id);<br />
stmt.setString(2, name );<br />
Integer IRows = new Integer(<br />
stmt.executeUpdate() );<br />
// Impression du nombre <strong>de</strong> lignes mises à jour<br />
System.out.println(IRows.toString() + "ligne<br />
insérée" );<br />
}<br />
catch ( Exception e ) {<br />
System.out.println("Erreur : " + e.getMessage());<br />
e.printStackTrace();<br />
}<br />
}<br />
Une fois la classe JDBCExamples installée dans la base <strong>de</strong> données<br />
exemple, l'instruction suivante permet d'exécuter l'instruction donnée en<br />
exemple :<br />
call JDBCExamples>>InsertPrepared(<br />
202, ’Eastern Sales’ )<br />
L'argument <strong>de</strong> chaîne est placé entre guillemets simples, conformément aux<br />
règles syntaxiques <strong>de</strong> SQL. En revanche, pour appeler cette métho<strong>de</strong> <strong>de</strong>puis<br />
une application Java, délimitez la chaîne avec <strong>de</strong>s guillemets doubles.
Insertion et extraction d’objets<br />
Extraction d’objets<br />
Insertion d’objets<br />
Chapitre 5 Accès aux données via JDBC<br />
En tant qu'interface <strong>de</strong> bases <strong>de</strong> données relationnelles, JDBC est<br />
spécifiquement conçu pour extraire et manipuler <strong>de</strong>s types <strong>de</strong> données SQL<br />
classiques. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> fournit également <strong>de</strong>s types <strong>de</strong><br />
données abstraites sous la forme <strong>de</strong> classes Java. Le mo<strong>de</strong> d'accès à ces<br />
classes Java via JDBC est fonction <strong>de</strong> l'opération que vous souhaitez<br />
effectuer, à savoir l'insertion ou l'extraction d'objets.<br />
$ Pour en savoir plus, reportez-vous à la section "Création d'applications<br />
distribuées", page 171.<br />
Pour extraire <strong>de</strong>s objets ainsi que leurs champs et leurs métho<strong>de</strong>s, plusieurs<br />
solutions sont possibles :<br />
♦ Accès aux métho<strong>de</strong>s et aux champs Les métho<strong>de</strong>s et champs Java<br />
peuvent être inclus dans la liste <strong>de</strong> sélection d'une requête. Ces champs<br />
et métho<strong>de</strong>s apparaissent ensuite sous forme <strong>de</strong> colonnes dans le jeu <strong>de</strong><br />
résultats, et vous pouvez y accé<strong>de</strong>r via l'une <strong>de</strong>s métho<strong>de</strong>s ResultSet<br />
standard, telles que getInt ou getString.<br />
♦ Récupération d'un objet Si vous incluez une colonne avec un type <strong>de</strong><br />
classe Java dans une liste <strong>de</strong> sélection d'une requête, vous pouvez<br />
ensuite récupérer l'objet dans une classe Java via la métho<strong>de</strong> ResultSet<br />
getObject. L'accès aux métho<strong>de</strong>s et aux champs <strong>de</strong> cet objet est alors<br />
possible à partir <strong>de</strong> la classe Java.<br />
Depuis une classe Java côté serveur, la métho<strong>de</strong> JDBC setObject permet<br />
d'insérer un objet dans une colonne <strong>de</strong> type classe Java.<br />
Vous pouvez insérer <strong>de</strong>s objets en utilisant une instruction préparée. Par<br />
exemple, l'échantillon <strong>de</strong> co<strong>de</strong> ci-après insère un objet <strong>de</strong> type MyJavaClass<br />
dans une colonne <strong>de</strong> table T :<br />
java.sql.PreparedStatement ps =<br />
conn.prepareStatement("insert T values( ? )" );<br />
ps.setObject( 1, new MyJavaClass() );<br />
ps.executeUpdate();<br />
Vous pouvez également choisir <strong>de</strong> configurer une variable SQL contenant<br />
l'objet, puis d'insérer cette variable dans la table.<br />
169
Utilisation <strong>de</strong> JDBC pour accé<strong>de</strong>r aux données<br />
Remarques diverses concernant JDBC<br />
170<br />
♦ Autorisations d'accès A l’instar <strong>de</strong> toutes les classes Java dans la base<br />
<strong>de</strong> données, les classes contenant <strong>de</strong>s instructions JDBC sont en accès<br />
libre pour tous les utilisateurs. Il n'existe pas d'équivalent <strong>de</strong> l'instruction<br />
GRANT EXECUTE, qui autorise l'exécution <strong>de</strong> certaines procédures, et<br />
il n'est pas nécessaire <strong>de</strong> qualifier le nom d'une classe du nom <strong>de</strong> son<br />
propriétaire.<br />
♦ Autorisations d'exécution Les classes Java sont exécutées selon les<br />
autorisations <strong>de</strong> la connexion qui les exécute. Ce mo<strong>de</strong> est différent <strong>de</strong><br />
celui <strong>de</strong>s procédures stockées, exécutées selon les autorisations du<br />
propriétaire.
Création d'applications distribuées<br />
Tâches associées<br />
Conditions<br />
requises pour les<br />
applications<br />
distribuées<br />
Chapitre 5 Accès aux données via JDBC<br />
Dans une application distribuée, certaines parties <strong>de</strong> la logique <strong>de</strong><br />
l'application sont exécutées sur une machine et les autres sur une autre<br />
machine. Avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, vous pouvez créer <strong>de</strong>s<br />
applications Java distribuées, avec une partie <strong>de</strong> la logique exécutée dans le<br />
serveur <strong>de</strong> la base, et le reste sur la machine cliente.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est capable d'échanger <strong>de</strong>s objets Java avec un<br />
client Java externe.<br />
Dans une application distribuée, la tâche principale consiste pour<br />
l'application cliente à extraire un objet Java d'une base <strong>de</strong> données. Cette<br />
section décrit la procédure d'exécution <strong>de</strong> cette tâche.<br />
Dans d'autres parties <strong>de</strong> ce chapitre, nous avons vu comment exécuter<br />
plusieurs tâches qui sont certes associées à la récupération d'objets, mais qui<br />
ne consistent pas à récupérer l'objet lui-même. Par exemple :<br />
♦ "Recherche d'objets Java", page 114 décrit comment récupérer un objet<br />
dans une variable SQL. Toutefois, cette section n'indique pas pour autant<br />
comment intégrer l'objet dans l'application Java.<br />
♦ "Recherche d'objets Java", page 114 décrit également comment<br />
récupérer les champs publics et la valeur renvoyée <strong>de</strong>s métho<strong>de</strong>s Java.<br />
Mais une fois encore, cela n'explique pas comment récupérer un objet<br />
pour l'intégrer dans une application Java.<br />
♦ "Insertion et extraction d'objets", page 169 décrit comment récupérer <strong>de</strong>s<br />
objets dans <strong>de</strong>s classes Java côté serveur. Mais cela ne nous dit toujours<br />
pas comment les récupérer dans une application cliente.<br />
La création d'une application distribuée comprend plusieurs étapes.<br />
v Pour créer une application distribuée :<br />
1 Toute classe exécutée dans le serveur doit mettre en oeuvre l'interface<br />
Serializable. Cela est très simple.<br />
2 L'application côté client doit importer la classe pour que l'objet puisse<br />
être reconstitué côté client.<br />
3 Pour sérialiser l'objet, utilisez la métho<strong>de</strong><br />
sybase.sql.ASAUtils.toByteArray côté serveur. Cette opération n'est<br />
nécessaire que pour <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> version 6.0.1 et<br />
inférieure.<br />
171
Création d'applications distribuées<br />
172<br />
4 Pour reconstituer l'objet, utilisez la métho<strong>de</strong><br />
sybase.sql.ASAUtils.fromByteArray côté client. Cette opération n'est<br />
nécessaire que pour <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> version 6.0.1 et<br />
inférieure.<br />
Ces tâches sont décrites en détail dans les sections suivantes.<br />
Mise en oeuvre <strong>de</strong> l’interface Serializable<br />
Les objets sont transmis du serveur à une application cliente sous une forme<br />
dite sérialisée. Cela signifie que chaque ligne inclut les informations<br />
suivantes :<br />
♦ un i<strong>de</strong>ntificateur <strong>de</strong> version,<br />
♦ un i<strong>de</strong>ntificateur <strong>de</strong> la classe (ou <strong>de</strong> la sous-classe) enregistrée,<br />
♦ les valeurs <strong>de</strong>s champs non statiques et non transitoires <strong>de</strong> la classe,<br />
♦ <strong>de</strong>s informations sur l'overhead.<br />
Pour qu'un objet puisse être envoyé à une application cliente, il doit mettre<br />
en oeuvre l'interface Serializable. Fort heureusement, cette tâche est <strong>de</strong>s plus<br />
simples.<br />
v Pour mettre en oeuvre l’interface Serializable<br />
♦ Ajoutez la séquence implements java.io.Serializable à votre définition<br />
<strong>de</strong> classe.<br />
Par exemple, Samples\ASA\Java\asa<strong>de</strong>mo\Product.java met en oeuvre<br />
l'interface Serializable puisqu'elle comprend la déclaration suivante :<br />
public class Product implements java.io.Serializable<br />
Finalement, mettre en oeuvre l'interface Serializable revient juste à<br />
déclarer que la classe peut être sérialisée.<br />
L'interface Serializable ne contient ni métho<strong>de</strong>, ni variable. Un objet sérialisé<br />
est converti en flux d'octets, ce qui permet <strong>de</strong> l'enregistrer sur disque ou <strong>de</strong><br />
l'envoyer à une autre application Java, où il peut alors être reconstitué, ou<br />
désérialisé.<br />
Un objet Java qui a été sérialisé dans un serveur <strong>de</strong> base <strong>de</strong> données, envoyé<br />
à une application cliente, puis désérialisé, est en tous points i<strong>de</strong>ntique à<br />
l'objet d'origine. Cela étant, il n'est pas indispensable <strong>de</strong> sérialiser toutes les<br />
variables d'un objet et, pour <strong>de</strong>s questions <strong>de</strong> sécurité, certaines ne doivent<br />
pas l'être. Ces variables sont déclarées avec le mot-clé transient, comme<br />
dans la déclaration suivante :
transient String password;<br />
Chapitre 5 Accès aux données via JDBC<br />
Lorsqu'un objet avec cette variable est désérialisé, la variable contient<br />
toujours sa valeur par défaut (NULL).<br />
Vous pouvez personnaliser la sérialisation en ajoutant les métho<strong>de</strong>s<br />
writeObject() et readObject() à vos classes.<br />
$ Pour plus d'informations sur la sérialisation, reportez-vous au JDK<br />
(Java Development Kit) <strong>de</strong> Sun Microsystems.<br />
Importation d'une classe côté client<br />
Côté client, toute classe qui extrait un objet doit disposer d'un accès à la<br />
définition <strong>de</strong> classe correspondante pour pouvoir utiliser cet objet. Pour<br />
utiliser la classe Product, qui figure dans le package asa<strong>de</strong>mo, vous <strong>de</strong>vez<br />
inclure la ligne suivante dans votre application :<br />
import asa<strong>de</strong>mo.*<br />
Exemple d'application distribuée<br />
Pour que ce package puisse être localisé, le fichier asa<strong>de</strong>mo.jar doit être<br />
inclus dans votre CLASSPATH.<br />
La classe JDBCExamples.java contient trois métho<strong>de</strong>s illustrant<br />
l'informatique Java distribuée. Celles-ci sont toutes appelées à partir <strong>de</strong> la<br />
métho<strong>de</strong> main. Cette métho<strong>de</strong> est appelée dans l'exemple <strong>de</strong> connexion<br />
donné dans la section "Connexion à partir d'une application JDBC cliente<br />
avec jConnect", page 154, qui est un exemple d'application distribuée.<br />
Voici la métho<strong>de</strong> getObjectColumn <strong>de</strong> la classe JDBCExamples.<br />
private static void getObjectColumn() throws Exception {<br />
// Renvoie un jeu <strong>de</strong> résultats à partir d'une colonne<br />
// contenant <strong>de</strong>s objets Java<br />
asa<strong>de</strong>mo.ContactInfo ci;<br />
String name;<br />
String sComment ;<br />
if ( conn != null ) {<br />
Statement stmt = conn.createStatement();<br />
ResultSet rs = stmt.executeQuery(<br />
"SELECT JContactInfo FROM jdba.contact"<br />
);<br />
173
Création d'applications distribuées<br />
Ancienne métho<strong>de</strong><br />
Sérialisation et<br />
désérialisation <strong>de</strong>s<br />
résultats <strong>de</strong><br />
requêtes<br />
174<br />
while ( rs.next() ) {<br />
ci = ( asa<strong>de</strong>mo.ContactInfo )rs.getObject(1);<br />
System.out.println( "\n\tRue : " + ci.street +<br />
"Ville : " + ci.city +<br />
"\n\tPays : " + ci.state +<br />
"Téléphone : " + ci.phone +<br />
"\n" );<br />
}<br />
}<br />
}<br />
La métho<strong>de</strong> getObject est utilisée comme dans le cas <strong>de</strong> Java interne.<br />
getObject et setObject conseillées<br />
Les métho<strong>de</strong>s getObject et setObject suppriment la nécessité <strong>de</strong>s<br />
sérialisations et désérialisations explicites qui étaient la règle dans les<br />
versions antérieures du logiciel. La présente section décrit cette ancienne<br />
métho<strong>de</strong> à l'intention <strong>de</strong>s utilisateurs chargés <strong>de</strong> la maintenance <strong>de</strong> co<strong>de</strong><br />
utilisant ces techniques.<br />
Dans cette section, nous verrons le mo<strong>de</strong> <strong>de</strong> fonctionnement d'un <strong>de</strong> ces<br />
exemples. Néanmoins, vous pouvez aussi étudier le co<strong>de</strong> <strong>de</strong>s autres<br />
exemples.<br />
Voici la métho<strong>de</strong> serializeColumn d'une ancienne version <strong>de</strong> la classe<br />
JDBCExamples.<br />
private static void serializeColumn() throws Exception {<br />
Statement stmt;<br />
ResultSet rs;<br />
byte arrayb[];<br />
asa<strong>de</strong>mo.ContactInfo ci;<br />
String name;<br />
if ( conn != null ) {<br />
stmt = conn.createStatement();<br />
rs = stmt.executeQuery( "SELECT<br />
sybase.sql.ASAUtils.toByteArray( JName.getName() )<br />
AS Name,<br />
sybase.sql.ASAUtils.toByteArray(<br />
jdba.contact.JContactInfo )<br />
FROM jdba.contact" );<br />
while ( rs.next() ) {<br />
arrayb = rs.getBytes("Name");<br />
name = ( String<br />
)sybase.sql.ASAUtils.fromByteArray( arrayb );
Chapitre 5 Accès aux données via JDBC<br />
arrayb = rs.getBytes(2);<br />
ci =<br />
(asa<strong>de</strong>mo.ContactInfo)sybase.sql.ASAUtils.fromByteArray(<br />
arrayb );<br />
System.out.println( "Nom : " + name +<br />
"\n\tRue : " + ci.street +<br />
"\n\tVille : " + ci.city +<br />
"\n\tPays : " + ci.state +<br />
"\n\tTéléphone : " + ci.phone<br />
+<br />
"\n" );<br />
}<br />
System.out.println( "\n\n" );<br />
}<br />
}<br />
Voici, dans le détail, le mo<strong>de</strong> <strong>de</strong> fonctionnement <strong>de</strong> la métho<strong>de</strong> :<br />
1 Une connexion existe déjà lorsque la métho<strong>de</strong> est appelée. L'objet<br />
connexion est contrôlé et, du moment qu'il existe, le co<strong>de</strong> est exécuté.<br />
2 Une requête SQL est créée et exécutée. Cette requête est la suivante :<br />
SELECT<br />
sybase.sql.ASAUtils.toByteArray( JName.getName() )<br />
AS Name,<br />
sybase.sql.ASAUtils.toByteArray(<br />
jdba.contact.JContactInfo )<br />
FROM jdba.contact<br />
Cette instruction lance une requête sur la table jdba.contact. Elle obtient<br />
les résultats à partir <strong>de</strong>s colonnes JName et JContactInfo. Au lieu<br />
d'extraire la colonne ou une métho<strong>de</strong> <strong>de</strong> la colonne, la fonction<br />
sybase.sql.ASAUtils.toByteArray convertit les valeurs en flux d'octets<br />
<strong>de</strong> sorte qu'il puisse être sérialisé.<br />
3 Le client passe en boucle sur les lignes du jeu <strong>de</strong> résultats. Dans chaque<br />
ligne, la valeur <strong>de</strong> chaque colonne est désérialisée en un objet.<br />
4 La sortie (System.out.println) indique que les champs et métho<strong>de</strong>s <strong>de</strong><br />
l'objet peuvent être utilisés tout comme ils pouvaient l'être à l'origine.<br />
Autres fonctionnalités <strong>de</strong>s applications distribuées<br />
JDBCExamples.java comprend <strong>de</strong>ux autres métho<strong>de</strong>s relevant <strong>de</strong><br />
l'informatique distribuée :<br />
♦ serializeVariable Cette métho<strong>de</strong> crée un objet Java natif référencé par<br />
une variable SQL sur le serveur <strong>de</strong> base <strong>de</strong> données, puis le transmet à<br />
l'application cliente.<br />
175
Création d'applications distribuées<br />
176<br />
♦ serializeColumnCastClass I<strong>de</strong>ntique à la métho<strong>de</strong> serializeColumn,<br />
cette métho<strong>de</strong> indique en plus comment reconstituer les sous-classes. La<br />
colonne interrogée (JProd <strong>de</strong> la table product) est <strong>de</strong> type<br />
asa<strong>de</strong>mo.Product. Certaines lignes sont <strong>de</strong> type asa<strong>de</strong>mo.Hat, qui est<br />
une sous-classe <strong>de</strong> la classe Product. La classe est reconstituée du côté<br />
client.
CHAPITRE 6<br />
Programmation avec Embed<strong>de</strong>d SQL<br />
Présentation<br />
Sommaire<br />
Ce chapitre explique comment utiliser l’interface <strong>de</strong> <strong>programmation</strong><br />
Embed<strong>de</strong>d SQL avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Sujet Page<br />
Introduction 178<br />
Exemples <strong>de</strong> programmes Embed<strong>de</strong>d SQL 186<br />
Types <strong>de</strong> données Embed<strong>de</strong>d SQL 192<br />
Utilisation <strong>de</strong>s variables hôte 196<br />
Zone <strong>de</strong> communication SQL (SQLCA) 205<br />
Lecture <strong>de</strong> données 211<br />
SQL statique et SQL dynamique 221<br />
Zone <strong>de</strong>scripteur SQL (SQLDA) 226<br />
Envoi et extraction <strong>de</strong> valeurs longues 235<br />
Utilisation <strong>de</strong> procédures stockées 241<br />
Techniques <strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL 245<br />
Préprocesseur SQL 247<br />
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque 251<br />
Récapitulatif <strong>de</strong>s comman<strong>de</strong>s Embed<strong>de</strong>d SQL 270<br />
177
Introduction<br />
Introduction<br />
178<br />
Embed<strong>de</strong>d SQL est une interface <strong>de</strong> <strong>programmation</strong> <strong>de</strong> bases <strong>de</strong> données<br />
pour les langages C et C++. Elle fait appel à <strong>de</strong>s instructions SQL imbriquées<br />
dans du co<strong>de</strong> source C ou C++. Un préprocesseur SQL traduit ces<br />
instructions SQL en co<strong>de</strong> source C ou C++, que vous compilez par la suite.<br />
Lors <strong>de</strong> leur exécution, les applications Embed<strong>de</strong>d SQL utilisent une<br />
bibliothèque d'interface <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> pour communiquer<br />
avec le serveur <strong>de</strong> base <strong>de</strong> données. La bibliothèque d'interface est une DLL<br />
(dynamic link library) ou une bibliothèque partagée sur la plupart <strong>de</strong>s platesformes.<br />
♦ Sous Windows 95/98, Windows CE et Windows NT/2000, la<br />
bibliothèque d'interface est dblib8.dll.<br />
♦ Sous UNIX, la bibliothèque d'interface est libdblib8.so, libdblib8.sl ou<br />
libdblib8.a, selon le système d'exploitation.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> fournit <strong>de</strong>ux versions d'Embed<strong>de</strong>d SQL. La<br />
version statique est plus facile à utiliser mais moins souple que la version<br />
dynamique. Les <strong>de</strong>ux versions sont présentées dans ce chapitre.
Présentation du processus <strong>de</strong> développement<br />
Co<strong>de</strong> Source C<br />
Préprocesseur<br />
SQL<br />
Compilateur C<br />
Editeur <strong>de</strong> lien<br />
Application<br />
cliente<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Bibliothèque<br />
d'importation<br />
DLL<br />
DLL<br />
Base <strong>de</strong><br />
données<br />
Une fois le programme prétraité et compilé, il est lié à la bibliothèque<br />
d'importation afin que la bibliothèque d'interface<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> génère un fichier exécutable. Lorsque la base <strong>de</strong><br />
données est active, ce fichier exécutable utilise la DLL<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> pour communiquer avec la base <strong>de</strong> données. Il<br />
n'est pas nécessaire que la base <strong>de</strong> données soit active lors du prétraitement<br />
du programme.<br />
Sous Windows 95/98 et Windows NT/2000, il existe <strong>de</strong>s bibliothèques<br />
d'importation spécifiques pour Watcom C/C++, Microsoft Visual C++ et<br />
Borland C++.<br />
$ L'utilisation <strong>de</strong> bibliothèques d'importation est la métho<strong>de</strong> <strong>de</strong><br />
développement standard pour les applications appelant <strong>de</strong>s fonctions dans<br />
<strong>de</strong>s DLL. Toutefois, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> offre une autre métho<strong>de</strong><br />
qu'il est recommandé d'utiliser et qui permet d'éviter le recours aux<br />
bibliothèques d'importation. Pour plus d'informations, reportez-vous à la<br />
section "Chargement dynamique <strong>de</strong> la bibliothèque d'interface", page 183.<br />
179
Introduction<br />
Exécution du préprocesseur SQL<br />
Ligne <strong>de</strong><br />
comman<strong>de</strong><br />
Compilateurs supportés<br />
180<br />
Le préprocesseur SQL est un exécutable appelé sqlpp.exe.<br />
La ligne <strong>de</strong> comman<strong>de</strong> SQLPP se présente comme suit :<br />
sqlpp [ options ] nom_fichier_SQL [nom_fichier_résultat]<br />
Le préprocesseur SQL traite un programme en langage C avec<br />
Embed<strong>de</strong>d SQL avant l'exécution du compilateur C ou C++. Le<br />
préprocesseur convertit les instructions SQL en co<strong>de</strong> source C/C++, ce<br />
<strong>de</strong>rnier étant ensuite placé dans le fichier <strong>de</strong> résultat. L'extension normale<br />
pour les programmes source en Embed<strong>de</strong>d SQL est .sqc. Le nom du fichier<br />
<strong>de</strong> résultat par défaut est nom_fichier_SQL avec l'extension .c. Si<br />
nom_fichier_SQL comporte déjà l'extension .c, l'extension du fichier <strong>de</strong><br />
résultat sera, par défaut, .cc.<br />
$ Pour obtenir la liste complète <strong>de</strong>s options <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong>,<br />
reportez-vous à la section "Préprocesseur SQL", page 247.<br />
Le préprocesseur SQL <strong>de</strong> langage C a été testé avec les compilateurs<br />
suivants :<br />
Système d'exploitation Compilateur Version<br />
Windows 95/98 et NT/2000 Watcom C/C++ 9.5 et versions<br />
supérieures<br />
Windows 95/98 et NT/2000 Microsoft Visual C/C++ 1.0 et versions<br />
supérieures<br />
Windows 95/98 et NT/2000 Borland C++ 4.5<br />
Windows CE Microsoft Visual C/C++ 5.0<br />
UNIX GNU ou compilateur<br />
natif<br />
NetWare Watcom C/C++ 10.6, 11<br />
$ Pour plus d’informations sur la compilation <strong>de</strong>s NLM NetWare,<br />
reportez-vous à la section "Compilation <strong>de</strong>s modules chargeables NetWare<br />
(NLM)", page 185.
Fichiers d'en-tête Embed<strong>de</strong>d SQL<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Tous les fichiers d'en-tête sont installés dans le sous-répertoire h du<br />
répertoire d'installation d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Nom <strong>de</strong><br />
fichier<br />
Description<br />
sqlca.h Principal fichier d'en-tête inclus dans tous les programmes<br />
Embed<strong>de</strong>d SQL. Ce fichier contient la définition <strong>de</strong> structure <strong>de</strong><br />
la zone <strong>de</strong> communication SQL (SQLCA), ainsi que <strong>de</strong>s<br />
prototypes pour toutes les fonctions d'interface <strong>de</strong> base <strong>de</strong><br />
données Embed<strong>de</strong>d SQL.<br />
sqlda.h Définition <strong>de</strong> structure <strong>de</strong> la zone <strong>de</strong>scripteur SQL incluse dans<br />
les programmes Embed<strong>de</strong>d SQL qui utilisent du SQL dynamique.<br />
sql<strong>de</strong>f.h Définition <strong>de</strong>s types <strong>de</strong> données <strong>de</strong> l'interface Embed<strong>de</strong>d SQL.<br />
Ce fichier contient également les définitions <strong>de</strong> structure et les<br />
co<strong>de</strong>s <strong>de</strong> retour nécessaires au démarrage du serveur <strong>de</strong> base <strong>de</strong><br />
données à partir d'un programme en C.<br />
sqlerr.h Définition <strong>de</strong>s co<strong>de</strong>s d'erreur renvoyés dans le champ sqlco<strong>de</strong> <strong>de</strong><br />
la zone SQLCA.<br />
sqlstate.h Définition <strong>de</strong>s états d'erreur standard SQL ANSI/ISO renvoyés<br />
dans le champ sqlstate <strong>de</strong> la zone SQLCA.<br />
pshpk1.h,<br />
pshpk2.h,<br />
poppk.h<br />
Bibliothèques d'importation<br />
Ces fichiers d'en-tête assurent une gestion correcte <strong>de</strong>s groupes<br />
<strong>de</strong> structure. Ils supportent les compilateurs Watcom C/C++,<br />
Microsoft Visual C++, IBM Visual Age et Borland C/C++.<br />
Toutes les bibliothèques d'importation sont installées à l'intérieur du sousrépertoire<br />
lib, dans le sous-répertoire du système d'exploitation du répertoire<br />
d'installation d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Par exemple, les bibliothèques<br />
d'importation <strong>de</strong> Windows 95/98 et Windows NT/2000 sont stockées dans le<br />
sous-répertoire win32\lib.<br />
181
Introduction<br />
Exemple simple<br />
182<br />
Système d'exploitation Compilateur Bibliothèque<br />
d'importation<br />
Windows 95/98, Windows NT Watcom C/C++ dblibtw.lib<br />
Windows 95/98, Windows NT Microsoft Visual<br />
C++<br />
Windows CE Microsoft Visual<br />
C++<br />
dblibtm.lib<br />
dblib8.lib<br />
NetWare Watcom C/C++ dblib8.lib<br />
Solaris (applications n’utilisant<br />
pas les threads natifs)<br />
Solaris (applications utilisant les<br />
threads natifs)<br />
Tous les<br />
compilateurs<br />
Tous les<br />
compilateurs<br />
libdblib8.so,<br />
libdbtasks8.so<br />
libdblib8_r.so,<br />
libdbtasks8_r.so<br />
Les bibliothèques libdbtasks8 sont appelées par la bibliothèque libdblib8 .<br />
Certains compilateurs localisent libdbtasks8 automatiquement ; avec d'autres,<br />
vous <strong>de</strong>vez la spécifier explicitement.<br />
Voici un exemple très simple <strong>de</strong> programme Embed<strong>de</strong>d SQL :<br />
#inclu<strong>de</strong> <br />
EXEC SQL INCLUDE SQLCA;<br />
main()<br />
{<br />
db_init( &sqlca );<br />
EXEC SQL WHENEVER SQLERROR GOTO error;<br />
EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL";<br />
EXEC SQL UPDATE employee<br />
SET emp_lname = ’Plankton’<br />
WHERE emp_id = 195;<br />
EXEC SQL COMMIT WORK;<br />
EXEC SQL DISCONNECT;<br />
db_fini( &sqlca );<br />
return( 0 );<br />
}<br />
error:<br />
printf( "echec <strong>de</strong> mise à jour --- sqlco<strong>de</strong> = %ld.n",<br />
sqlca.sqlco<strong>de</strong> );<br />
db_fini( &sqlca );<br />
return( -1 );
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Ce programme effectue la connexion à la base <strong>de</strong> données, met à jour le nom<br />
<strong>de</strong> l'employé 195, vali<strong>de</strong> la modification et s'arrête. Il n'existe pratiquement<br />
aucune interaction entre les co<strong>de</strong>s SQL et C dans cet exemple. Dans cet<br />
exemple, le co<strong>de</strong> C est utilisé uniquement pour le contrôle <strong>de</strong> flux.<br />
L'instruction WHENEVER permet d'effectuer le contrôle d'erreurs. L'action<br />
sur erreur (GOTO, dans cet exemple) est exécutée après toute instruction<br />
SQL ayant généré une erreur.<br />
$ Pour obtenir la <strong>de</strong>scription <strong>de</strong>s opérations d'extraction <strong>de</strong>s données,<br />
reportez-vous à la section "Lecture <strong>de</strong> données", page 211.<br />
Structure <strong>de</strong>s programmes Embed<strong>de</strong>d SQL<br />
Les instructions SQL sont placées (imbriquées) dans du co<strong>de</strong> C ou C++<br />
normal. Toutes les instructions Embed<strong>de</strong>d SQL commencent par les mots<br />
EXEC SQL et se terminent par un point-virgule (;). Les commentaires du<br />
langage C normal peuvent être intégrés aux instructions Embed<strong>de</strong>d SQL.<br />
Tout programme en langage C faisant appel à Embed<strong>de</strong>d SQL doit contenir<br />
l'instruction ci-après avant toute autre instruction Embed<strong>de</strong>d SQL dans le<br />
fichier source :<br />
EXEC SQL INCLUDE SQLCA;<br />
La première instruction Embed<strong>de</strong>d SQL exécutée par le programme en<br />
langage C doit être une instruction CONNECT. L'instruction CONNECT<br />
permet d'établir une connexion avec le serveur <strong>de</strong> base <strong>de</strong> données et<br />
d'indiquer l'ID utilisateur utilisé pour autoriser toutes les instructions<br />
exécutées au cours <strong>de</strong> la connexion.<br />
L'instruction CONNECT doit être la première instruction Embed<strong>de</strong>d SQL<br />
exécutée. Certaines comman<strong>de</strong>s Embed<strong>de</strong>d SQL ne génèrent pas <strong>de</strong> co<strong>de</strong> C<br />
ou n'établissent aucune communication avec la base <strong>de</strong> données. Par<br />
conséquent, leur utilisation est autorisée avant l'instruction CONNECT. Il<br />
s'agit notamment <strong>de</strong>s instructions INCLUDE et WHENEVER (pour le<br />
traitement <strong>de</strong>s erreurs).<br />
Chargement dynamique <strong>de</strong> la bibliothèque d'interface<br />
Il est courant, dans le développement d'applications faisant appel à <strong>de</strong>s<br />
fonctions provenant <strong>de</strong> DLL, <strong>de</strong> lier l'application à une bibliothèque<br />
d'importation contenant les définitions <strong>de</strong>s fonctions requises.<br />
183
Introduction<br />
Exemple<br />
184<br />
Cette section présente une alternative à l'utilisation <strong>de</strong> la bibliothèque<br />
d'importation pour développer <strong>de</strong>s applications <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Il est possible <strong>de</strong> charger la bibliothèque d'interface<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> dynamiquement, sans créer <strong>de</strong> lien à la<br />
bibliothèque d'importation, par l'intermédiaire du module esqldll.c qui se<br />
trouve dans le sous-répertoire src du répertoire d'installation. Il est<br />
recommandé d'utiliser esqldll.c car ce module permet <strong>de</strong> localiser la DLL<br />
d'interface plus facilement et <strong>de</strong> façon plus stable.<br />
v Pour charger la DLL d'interface <strong>de</strong> façon dynamique :<br />
1 Votre programme doit appeler db_init_dll pour charger la DLL, puis<br />
db_fini_dll pour la libérer. La fonction db_init_dll doit être appelée<br />
avant toute autre fonction dans l'interface <strong>de</strong> base <strong>de</strong> données, et aucune<br />
fonction ne peut être appelée après db_fini_dll.<br />
Les fonctions <strong>de</strong> bibliothèque db_init et db_fini doivent toujours être<br />
appelées.<br />
2 Vous <strong>de</strong>vez inclure (#inclu<strong>de</strong>) le fichier d'en-tête esqldll.h avant<br />
l'instruction EXEC SQL INCLUDE SQLCA ou la ligne dans<br />
votre programme Embed<strong>de</strong>d SQL.<br />
3 Vous <strong>de</strong>vez définir une macro SQL OS. Le fichier d'en-tête sqlca.h,<br />
inclus dans esqdll.c, tente <strong>de</strong> déterminer la macro appropriée et la<br />
définit. Notez cependant que cette opération peut échouer sur certaines<br />
combinaisons plate-forme/compilateur. Dans ce cas, ajoutez une<br />
définition (#<strong>de</strong>fine) au début du fichier ou définissez la macro à l'ai<strong>de</strong><br />
d'une option <strong>de</strong> compilateur.<br />
Macro Plates-formes<br />
_SQL_OS_WINNT Windows 95/98, Windows CE et<br />
Windows NT/2000<br />
_SQL_OS_UNIX UNIX<br />
_SQL_OS_NETWARE NetWare<br />
4 Compilez esqldll.c.<br />
5 Au lieu d'effectuer la liaison avec la bibliothèque d'importation, liez le<br />
module objet esqldll.obj avec les objets <strong>de</strong> votre application<br />
Embed<strong>de</strong>d SQL.<br />
Il existe un programme exemple, qui indique comment charger la<br />
bibliothèque d'interface <strong>de</strong> manière dynamique, dans le sous-répertoire<br />
Samples\ASA\ESQLDynamicLoad du répertoire SQL <strong>Anywhere</strong>. Le co<strong>de</strong><br />
source se trouve dans Samples\ASA\ESQLDynamicLoad\sample.sqc.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Compilation <strong>de</strong>s modules chargeables NetWare (NLM)<br />
Vous <strong>de</strong>vez utiliser le compilateur Watcom C/C++, version 10.6 ou 11.0,<br />
pour compiler les programmes Embed<strong>de</strong>d SQL sous la forme <strong>de</strong> NLM<br />
(module chargeable NetWare).<br />
v Pour créer un NLM Embed<strong>de</strong>d SQL :<br />
1 Sous Windows, prétraitez le fichier ESQL avec la comman<strong>de</strong> suivante :<br />
sqlpp -o NETWARE fichier_src.sqc<br />
Cette instruction crée un fichier avec l'extension .c.<br />
2 Compilez fichier.c à l'ai<strong>de</strong> du compilateur Watcom (10.6 ou 11.0), en<br />
utilisant l'option /bt=netware.<br />
3 Liez le fichier objet obtenu en utilisant le générateur <strong>de</strong> liens Watcom<br />
avec les options suivantes :<br />
FORMAT NOVELL<br />
MODULE dblib8<br />
OPTION CASEEXACT<br />
IMPORT @dblib8.imp<br />
LIBRARY dblib8.lib<br />
Les fichiers dblib8.imp et dblib8.lib sont fournis avec <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>, dans le répertoire nlm\lib. Dans les lignes IMPORT et<br />
LIBRARY, il se peut que vous ayez à préciser le chemin complet.<br />
185
Exemples <strong>de</strong> programmes Embed<strong>de</strong>d SQL<br />
Exemples <strong>de</strong> programmes Embed<strong>de</strong>d SQL<br />
186<br />
Des exemples <strong>de</strong> programmes Embed<strong>de</strong>d SQL sont inclus dans l’installation<br />
d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Ils sont placés dans le sous-répertoire<br />
Samples\ASA\C du répertoire SQL <strong>Anywhere</strong>.<br />
♦ L'exemple <strong>de</strong> curseur statique Embed<strong>de</strong>d SQL, Samples\ASA\C\cur.sqc,<br />
démontre l'utilisation d'instructions SQL statiques.<br />
♦ L'exemple <strong>de</strong> curseur dynamique Embed<strong>de</strong>d SQL,<br />
Samples\ASA\C\dcur.sqc, démontre l'utilisation d'instructions SQL<br />
dynamiques.<br />
Pour réduire la quantité <strong>de</strong> co<strong>de</strong> dupliqué par les programmes exemples, les<br />
lignes principales et les fonctions d'impression <strong>de</strong>s données ont été placées<br />
dans <strong>de</strong>s fichiers séparés. Ces fichiers sont mainch.c pour les systèmes en<br />
mo<strong>de</strong> caractères et mainwin.c pour les environnements utilisateur graphiques.<br />
Chaque programme exemple fournit les trois routines suivantes, appelées<br />
<strong>de</strong>puis les lignes principales :<br />
♦ WSQLEX_Init Etablit une connexion à la base <strong>de</strong> données et ouvre le<br />
curseur.<br />
♦ WSQLEX_Process_Command Traite les comman<strong>de</strong>s entrées par<br />
l'utilisateur en manipulant le curseur selon les besoins.<br />
♦ WSQLEX_Finish Ferme le curseur et interrompt la connexion avec la<br />
base <strong>de</strong> données.<br />
La ligne principale a plusieurs fonctions :<br />
1 Appel <strong>de</strong> la routine WSQLEX_Init.<br />
2 Boucle, obtention <strong>de</strong> comman<strong>de</strong>s <strong>de</strong> l'utilisateur et appel <strong>de</strong><br />
WSQL_Process_Command jusqu'à ce que l'utilisateur quitte le<br />
programme.<br />
3 Appel <strong>de</strong> la routine WSQLEX_Finish.<br />
La connexion à la base <strong>de</strong> données s'effectue à l'ai<strong>de</strong> <strong>de</strong> la comman<strong>de</strong><br />
Embed<strong>de</strong>d SQL CONNECT, qui fournit l'ID utilisateur et le mot <strong>de</strong> passe<br />
appropriés.<br />
En plus <strong>de</strong> ces exemples, vous trouverez d'autres programmes et fichiers<br />
source faisant partie <strong>de</strong> SQL <strong>Anywhere</strong> Studio, qui illustrent <strong>de</strong>s<br />
fonctionnalités disponibles sur <strong>de</strong>s plates-formes spécifiques.
Création <strong>de</strong>s programmes exemples<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Les fichiers utilisés pour créer les programmes exemples sont fournis avec le<br />
co<strong>de</strong> exemple.<br />
♦ Pour les systèmes d'exploitation Windows et les systèmes d'exploitation<br />
NetWare fonctionnant sous Windows, utilisez makeall.bat pour compiler<br />
les programmes exemples.<br />
♦ Pour UNIX, utilisez le script shell makeall.<br />
♦ Pour Windows CE, utilisez le fichier projet dcur.dsp pour Microsoft<br />
Visual C++.<br />
Le format <strong>de</strong> cette comman<strong>de</strong> est le suivant :<br />
makeall {Exemple} {Plate-forme} {Compilateur}<br />
Le premier paramètre est le nom du programme exemple que vous souhaitez<br />
compiler. C'est l'un <strong>de</strong>s paramètres suivants :<br />
♦ CUR exemple <strong>de</strong> curseur statique<br />
♦ DCUR exemple <strong>de</strong> curseur dynamique<br />
♦ ODBC exemple ODBC<br />
Le second paramètre concerne la plate-forme cible. C'est l'un <strong>de</strong>s paramètres<br />
suivants :<br />
♦ WINNT Compile pour Windows NT/2000, Windows 95 et Windows 98<br />
♦ NETWARE Compile pour Netware NLM<br />
Le troisième paramètre est le compilateur à utiliser pour la compilation du<br />
programme. Il peut s'agir <strong>de</strong> l'un <strong>de</strong>s compilateurs suivants :<br />
♦ WC Watcom C/C++<br />
♦ MC Microsoft C<br />
♦ BC Borland C<br />
Exécution <strong>de</strong>s programmes exemples<br />
Les fichiers exécutables et le co<strong>de</strong> source se trouvent dans le sous-répertoire<br />
Samples\ASA\C.<br />
187
Exemples <strong>de</strong> programmes Embed<strong>de</strong>d SQL<br />
Exemples<br />
Windows<br />
188<br />
v Pour exécuter le programme exemple <strong>de</strong> curseur statique :<br />
1 Démarrez le programme :<br />
♦ Démarrez la base <strong>de</strong> données exemple du serveur personnel<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
♦ Exécutez le fichier Samples\ASA\C\curwnt.exe.<br />
2 Suivez les instructions qui s'affichent à l'écran.<br />
Les différentes comman<strong>de</strong>s agissent sur un curseur <strong>de</strong> base <strong>de</strong> données<br />
et affichent les résultats <strong>de</strong> la requête à l'écran. Tapez la lettre associée à<br />
la comman<strong>de</strong> que vous souhaitez exécuter. Certains systèmes <strong>de</strong>man<strong>de</strong>nt<br />
d'appuyer sur ENTREE après la lettre.<br />
v Pour exécuter le programme exemple <strong>de</strong> curseur dynamique :<br />
1 Démarrez le programme :<br />
♦ Exécutez le fichier Samples\ASA\C\dcurwnt.exe.<br />
2 Connectez-vous à une base <strong>de</strong> données.<br />
♦ Chacun <strong>de</strong>s programmes exemples présente une interface utilisateur<br />
<strong>de</strong> type console qui vous invite à entrer une comman<strong>de</strong>. Pour vous<br />
connecter à la base <strong>de</strong> données exemple, saisissez la chaîne <strong>de</strong><br />
connexion suivante :<br />
DSN=ASA 8.0 Sample<br />
3 Choisissez une table :<br />
♦ Chaque programme exemple vous invite à choisir une table.<br />
Choisissez une <strong>de</strong>s tables <strong>de</strong> la base <strong>de</strong> données exemple. Ainsi,<br />
vous pouvez saisir Customer ou Employee.<br />
4 Suivez les instructions qui s'affichent à l'écran.<br />
Les différentes comman<strong>de</strong>s agissent sur un curseur <strong>de</strong> base <strong>de</strong> données<br />
et affichent les résultats <strong>de</strong> la requête à l'écran. Tapez la lettre associée à<br />
la comman<strong>de</strong> que vous souhaitez exécuter. Certains systèmes <strong>de</strong>man<strong>de</strong>nt<br />
d'appuyer sur ENTREE après la lettre.<br />
Les versions Windows <strong>de</strong>s programmes exemples sont <strong>de</strong> véritables<br />
programmes Windows. Toutefois, afin que le co<strong>de</strong> <strong>de</strong> l'interface utilisateur<br />
reste relativement compréhensible, certaines simplifications ont été<br />
effectuées. Notamment, ces applications ne réaffichent pas Windows<br />
lorsqu'elles reçoivent <strong>de</strong>s messages WM_PAINT, si ce n'est pour réafficher<br />
l'invite.
Exemple <strong>de</strong> curseur statique<br />
Exemple <strong>de</strong> curseur dynamique<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Cet exemple illustre l'emploi <strong>de</strong>s curseurs. Le curseur utilisé ici extrait<br />
certaines informations <strong>de</strong> la table employee <strong>de</strong> la base <strong>de</strong> données exemple.<br />
Il est déclaré statiquement, c'est-à-dire que la véritable instruction SQL qui<br />
permet d'extraire les informations est "codée en dur" dans le programme<br />
source. C'est un bon point <strong>de</strong> départ pour comprendre le fonctionnement <strong>de</strong>s<br />
curseurs. L'exemple suivant ("Exemple <strong>de</strong> curseur dynamique", page 189)<br />
reprend ce premier exemple et l'adapte à l'utilisation d'instructions SQL<br />
dynamiques.<br />
$ Pour savoir où se trouve le co<strong>de</strong> source et comment construire ce<br />
programme exemple, reportez-vous à la section "Exemples <strong>de</strong> programmes<br />
Embed<strong>de</strong>d SQL", page 186.<br />
La routine open_cursor déclare un curseur pour la comman<strong>de</strong> SQL<br />
spécifique et ouvre ce curseur.<br />
L'impression d'une page d'informations est effectuée par la routine print.<br />
Elle exécute autant <strong>de</strong> boucles qu'il existe <strong>de</strong> pages (pagesize fois) pour<br />
extraire une ligne unique du curseur et l'imprimer. Notez que la routine<br />
FETCH vérifie la présence d'avertissements (tels que La ligne est<br />
introuvable) et imprime les messages appropriés lorsqu'ils se produisent. De<br />
plus, le curseur est repositionné par le programme sur la ligne qui précè<strong>de</strong> la<br />
ligne affichée en haut <strong>de</strong> la page <strong>de</strong> données courante.<br />
Les routines move, top et bottom utilisent le format approprié <strong>de</strong><br />
l'instruction FETCH pour positionner le curseur. Notez que l'instruction<br />
FETCH, sous cette forme, n'extrait pas les données ; elle déplace seulement<br />
le curseur. En outre, une routine générale <strong>de</strong> positionnement relatif, move, a<br />
été mise en oeuvre pour permettre les déplacements dans l'un ou l'autre sens<br />
selon le signe du paramètre.<br />
Lorsque l'utilisateur quitte le programme, le curseur est refermé et la<br />
connexion à la base <strong>de</strong> données est interrompue. Le curseur est fermé par une<br />
instruction ROLLBACK WORK et la connexion libérée à l'ai<strong>de</strong> <strong>de</strong><br />
DISCONNECT.<br />
Cet exemple illustre l'utilisation <strong>de</strong>s curseurs pour une instruction<br />
SQL SELECT dynamique. Il comporte quelques modifications par rapport à<br />
l'exemple <strong>de</strong> curseur statique. Il est d'ailleurs conseillé <strong>de</strong> prendre<br />
connaissance <strong>de</strong> la section "Exemple <strong>de</strong> curseur statique", page 189 avant <strong>de</strong><br />
vous pencher sur cet exemple.<br />
189
Exemples <strong>de</strong> programmes Embed<strong>de</strong>d SQL<br />
190<br />
$ Pour savoir où se trouve le co<strong>de</strong> source et comment construire ce<br />
programme exemple, reportez-vous à la section "Exemples <strong>de</strong> programmes<br />
Embed<strong>de</strong>d SQL", page 186.<br />
Le programme dcur permet <strong>de</strong> sélectionner une table à consulter à l'ai<strong>de</strong> <strong>de</strong><br />
la comman<strong>de</strong> n. Il présente ensuite autant d'informations <strong>de</strong> la table que<br />
l'écran peut en contenir.<br />
Lorsque ce programme est exécuté, il invite l'utilisateur à entrer une chaîne<br />
<strong>de</strong> connexion <strong>de</strong> la forme suivante :<br />
uid=DBA;pwd=SQL;dbf=c:\asa\asa<strong>de</strong>mo.db<br />
Le programme en langage C avec Embed<strong>de</strong>d SQL se trouve dans le sousrépertoire<br />
Samples\ASA\C du répertoire SQL <strong>Anywhere</strong>. Il ressemble<br />
beaucoup à l'exemple <strong>de</strong> curseur statique, à l'exception <strong>de</strong>s fonctions<br />
connect, open_cursor et print.<br />
La fonction connect fait appel à la fonction <strong>de</strong> l'interface Embed<strong>de</strong>d SQL<br />
db_string_connect pour la connexion à la base <strong>de</strong> données. Elle gère<br />
également la chaîne <strong>de</strong> connexion utilisée pour la connexion à la base.<br />
La routine open_cursor génère d'abord l'instruction SELECT :<br />
SELECT * FROM nom_table<br />
où nom_table est un paramètre transmis à la routine. Elle prépare ensuite une<br />
instruction SQL dynamique à l'ai<strong>de</strong> <strong>de</strong> cette chaîne.<br />
La comman<strong>de</strong> Embed<strong>de</strong>d SQL DESCRIBE permet <strong>de</strong> compléter la structure<br />
SQLDA avec les résultats <strong>de</strong> l'instruction SELECT.<br />
Taille <strong>de</strong> la zone SQLDA<br />
Initialement, la taille <strong>de</strong> la zone SQLDA (3) est estimée. Si elle n'est pas<br />
suffisamment importante, la taille effective <strong>de</strong> la liste <strong>de</strong> sélection<br />
renvoyée par le serveur <strong>de</strong> base <strong>de</strong> données est utilisée pour allouer une<br />
taille correcte à la zone SQLDA.<br />
La structure SQLDA est ensuite complétée avec <strong>de</strong>s buffers afin <strong>de</strong><br />
pouvoir stocker les chaînes qui constituent le résultat <strong>de</strong> la requête. La<br />
routine fill_s_sqlda convertit tous les types <strong>de</strong> données <strong>de</strong> la zone<br />
SQLDA en DT_STRING, puis alloue <strong>de</strong>s buffers <strong>de</strong> la taille appropriée.<br />
Un curseur est ensuite déclaré, puis ouvert pour cette instruction. Les<br />
routines <strong>de</strong> déplacement et <strong>de</strong> fermeture du curseur restantes sont i<strong>de</strong>ntiques.<br />
La routine fetch est quelque peu différente : elle place les résultats dans la<br />
structure SQLDA et non dans une liste <strong>de</strong> variables hôte. La routine print a<br />
été largement modifiée ; elle affiche les résultats <strong>de</strong> la structure SQLDA sur<br />
toute la largeur <strong>de</strong> l'écran. Cette routine utilise également les champs "nom"<br />
<strong>de</strong> la zone SQLDA pour imprimer les en-têtes <strong>de</strong> chaque colonne.
Exemples <strong>de</strong> service<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Lorsqu'ils sont compilés pour Windows, les programmes exemples cur.sqc et<br />
dcur.sqc peuvent être exploités en tant que services.<br />
Les <strong>de</strong>ux fichiers contenant le co<strong>de</strong> exemple pour les services Windows sont<br />
le fichier source ntsvc.c et le fichier d'en-tête ntsvc.h. Ce co<strong>de</strong> permet <strong>de</strong><br />
lancer un fichier exécutable associé, en tant qu'exécutable normal ou service<br />
Windows.<br />
v Pour exécuter l'un <strong>de</strong>s exemples compilés en tant que service<br />
Windows :<br />
1 Démarrez <strong>Sybase</strong> Central et ouvrez le dossier Services.<br />
2 Sélectionnez un type <strong>de</strong> service d'application exemple, puis cliquez sur<br />
OK.<br />
3 Entrez un nom <strong>de</strong> service dans le champ approprié.<br />
4 Sélectionnez le programme exemple (curwnt.exe ou dcurwnt.exe) dans<br />
le sous-répertoire Samples\ASA\C du répertoire SQL <strong>Anywhere</strong>.<br />
5 Cliquez sur OK pour lancer l'installation.<br />
6 Cliquez sur Démarrer dans la fenêtre principale pour démarrer le<br />
service.<br />
Lorsque les programmes sont exécutés en tant que services, ils affichent, si<br />
possible, l'interface utilisateur normale. Ils écrivent également le résultat<br />
dans le journal d'événements <strong>de</strong> l'application (Application Event Log). S'il<br />
est impossible <strong>de</strong> démarrer l'interface utilisateur, les programmes<br />
enregistrent une page <strong>de</strong> données dans ce journal, puis s'interrompent.<br />
Ces exemples ont été testés avec les compilateurs Watcom C/C++<br />
version 10.5 et Microsoft Visual C++.<br />
191
Types <strong>de</strong> données Embed<strong>de</strong>d SQL<br />
Types <strong>de</strong> données Embed<strong>de</strong>d SQL<br />
192<br />
Le transfert d’informations entre un programme et le serveur <strong>de</strong> bases <strong>de</strong><br />
données n'est possible que si chaque élément <strong>de</strong> données est assorti d'un<br />
type. Les constantes du type <strong>de</strong> données Embed<strong>de</strong>d SQL sont précédées du<br />
préfixe DT_ et se trouvent dans le fichier d'en-tête sql<strong>de</strong>f.h. Vous pouvez<br />
créer une variable hôte <strong>de</strong> n'importe quel type <strong>de</strong> données supporté. Vous<br />
pouvez également utiliser ces types <strong>de</strong> données dans une structure SQLDA<br />
pour transférer <strong>de</strong>s données <strong>de</strong>puis et vers la base <strong>de</strong> données.<br />
Vous pouvez définir <strong>de</strong>s variables pour ces types <strong>de</strong> données en utilisant les<br />
macros DECL_ répertoriées dans sqlca.h. Par exemple, une variable<br />
contenant une valeur BIGINT peut être déclarée avec DECL_BIGINT.<br />
Les types <strong>de</strong> données suivants sont supportés par l'interface <strong>de</strong><br />
<strong>programmation</strong> Embed<strong>de</strong>d SQL :<br />
♦ DT_BIT Entier signé (8 bits)<br />
♦ DT_SMALLINT Entier signé (16 bits)<br />
♦ DT_UNSMALLINT Entier non signé (16 bits)<br />
♦ DT_TINYINT Entier signé (8 bits)<br />
♦ DT_BIGINT Entier signé (64 bits)<br />
♦ DT_INT Entier signé (32 bits)<br />
♦ DT_UNSINT Entier non signé (16 bits)<br />
♦ DT_FLOAT Nombre en virgule flottante (4 octets).<br />
♦ DT_DOUBLE Nombre en virgule flottante (8 octets).<br />
♦ DT_DECIMAL Décimal con<strong>de</strong>nsé.<br />
type<strong>de</strong>f struct DECIMAL {<br />
char array[1];<br />
} DECIMAL;<br />
♦ DT_STRING Chaîne <strong>de</strong> caractères terminée par une valeur NULL. Elle<br />
est complétée par <strong>de</strong>s blancs si la base <strong>de</strong> données est initialisée avec <strong>de</strong>s<br />
chaînes complétées par <strong>de</strong>s blancs.<br />
♦ DT_DATE Chaîne <strong>de</strong> caractères terminée par une valeur NULL,<br />
correspondant à une date correcte.<br />
♦ DT_TIME Chaîne <strong>de</strong> caractères terminée par une valeur NULL,<br />
correspondant à une heure correcte.<br />
♦ DT_TIMESTAMP Chaîne <strong>de</strong> caractères terminée par une valeur NULL,<br />
correspondant à une estampille correcte.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ DT_FIXCHAR Chaîne <strong>de</strong> caractères <strong>de</strong> longueur fixe complétée par <strong>de</strong>s<br />
blancs.<br />
♦ DT_VARCHAR Chaîne <strong>de</strong> caractères <strong>de</strong> longueur variable comportant<br />
un champ "longueur" <strong>de</strong> <strong>de</strong>ux octets. Lorsque vous fournissez <strong>de</strong>s<br />
informations au serveur <strong>de</strong> bases <strong>de</strong> données, vous <strong>de</strong>vez définir le<br />
champ "longueur". Lors <strong>de</strong> la lecture d'informations dans le serveur <strong>de</strong><br />
bases <strong>de</strong> données, celui-ci définit le champ "longueur" (non complété).<br />
type<strong>de</strong>f struct VARCHAR {<br />
unsigned short int len;<br />
char array[1];<br />
} VARCHAR;<br />
♦ DT_LONGVARCHAR Longue chaîne <strong>de</strong> données <strong>de</strong> type caractère <strong>de</strong><br />
longueur variable. La macro définit une structure similaire à celle qui<br />
suit :<br />
#<strong>de</strong>fine DECL_LONGVARCHAR( size ) \<br />
struct { a_sql_uint32 array_len; \<br />
a_sql_uint32 stored_len; \<br />
a_sql_uint32 untrunc_len; \<br />
char array[size+1];\<br />
}<br />
La structure DECL_LONGVARCHAR peut être utilisée avec plus <strong>de</strong><br />
32 ko <strong>de</strong> données. Les données volumineuses peuvent être lues en une<br />
seule opération, ou en plusieurs fois au moyen <strong>de</strong> l'instruction<br />
GET DATA. Il est également possible <strong>de</strong> les transmettre au serveur en<br />
une seule opération, ou en plusieurs fois en les ajoutant à une variable <strong>de</strong><br />
base <strong>de</strong> données via l'instruction SET. Ces données ne se terminent pas<br />
par une valeur NULL.<br />
$ Pour plus d'informations, reportez-vous à la section "Envoi et<br />
extraction <strong>de</strong> valeurs longues", page 235.<br />
♦ DT_BINARY Données binaires <strong>de</strong> longueur variable comportant un<br />
champ "longueur" <strong>de</strong> <strong>de</strong>ux octets. Lorsque vous fournissez <strong>de</strong>s<br />
informations au serveur <strong>de</strong> bases <strong>de</strong> données, vous <strong>de</strong>vez définir le<br />
champ "longueur". Lors <strong>de</strong> la lecture d'informations dans le serveur <strong>de</strong><br />
bases <strong>de</strong> données, celui-ci définit le champ "longueur".<br />
type<strong>de</strong>f struct BINARY {<br />
unsigned short int len;<br />
char array[1];<br />
} BINARY;<br />
♦ DT_LONGBINARY Données binaires longues. La macro définit une<br />
structure similaire à celle qui suit :<br />
193
Types <strong>de</strong> données Embed<strong>de</strong>d SQL<br />
194<br />
#<strong>de</strong>fine DECL_LONGBINARY( size ) \<br />
struct { a_sql_uint32 array_len; \<br />
a_sql_uint32 stored_len; \<br />
a_sql_uint32 untrunc_len; \<br />
char array[size]; \<br />
}<br />
La structure DECL_LONGBINARY peut être utilisée avec plus <strong>de</strong><br />
32 ko <strong>de</strong> données. Les données volumineuses peuvent être lues en une<br />
seule opération, ou en plusieurs fois au moyen <strong>de</strong> l'instruction<br />
GET DATA. Il est également possible <strong>de</strong> les transmettre au serveur en<br />
une seule opération, ou en plusieurs fois en les ajoutant à une variable <strong>de</strong><br />
base <strong>de</strong> données via l'instruction SET.<br />
$ Pour plus d'informations, reportez-vous à la section "Envoi et<br />
extraction <strong>de</strong> valeurs longues", page 235.<br />
♦ DT_TIMESTAMP_STRUCT Structure SQLDATETIME comportant <strong>de</strong>s<br />
champs pour chaque partie d'une estampille.<br />
type<strong>de</strong>f struct sqldatetime {<br />
unsigned short year; /* par exemple 1999 */<br />
unsigned char month; /* 0-11 */<br />
unsigned char day_of_week; /* 0-6 0=Dimanche */<br />
unsigned short day_of_year; /* 0-365 */<br />
unsigned char day; /* 1-31 */<br />
unsigned char hour; /* 0-23 */<br />
unsigned char minute; /* 0-59 */<br />
unsigned char second; /* 0-59 */<br />
unsigned long microsecond; /* 0-999999 */<br />
} SQLDATETIME;<br />
Vous pouvez faire appel à la structure SQLDATETIME pour récupérer<br />
<strong>de</strong>s champs <strong>de</strong> type DATE, TIME et TIMESTAMP (ou tout élément<br />
pouvant être converti dans l'un <strong>de</strong> ces types). Bien souvent, les<br />
applications disposent <strong>de</strong> leurs propres formats et <strong>de</strong> leur propre co<strong>de</strong> <strong>de</strong><br />
manipulation <strong>de</strong> date. L'utilisation <strong>de</strong> cette structure pour la lecture <strong>de</strong><br />
données facilite la manipulation <strong>de</strong>s données pour un programmeur.<br />
Notez que les champs DATE, TIME et TIMESTAMP peuvent<br />
également être lus et mis à jour avec n'importe quel type <strong>de</strong> caractère.<br />
Si vous utilisez une structure SQLDATETIME pour insérer une date,<br />
une heure ou une estampille dans la base <strong>de</strong> données, les éléments<br />
day_of_year et day_of_week sont ignorés.<br />
$ Pour plus d'informations, reportez-vous aux options <strong>de</strong> base <strong>de</strong><br />
données DATE_FORMAT, TIME_FORMAT,<br />
TIMESTAMP_FORMAT et DATE_ORDER dans le chapitre "Options<br />
<strong>de</strong> base <strong>de</strong> données", page 583 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.
Types <strong>de</strong> base <strong>de</strong><br />
données DATE et<br />
TIME<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ DT_VARIABLE Chaîne <strong>de</strong> caractères terminée par une valeur NULL. La<br />
chaîne <strong>de</strong> caractères doit être le nom d'une variable SQL dont la valeur<br />
est utilisée par le serveur <strong>de</strong> base <strong>de</strong> données. Ce type <strong>de</strong> données est<br />
utilisé uniquement pour fournir <strong>de</strong>s données au serveur. Il ne peut pas<br />
être utilisé lors <strong>de</strong> la lecture <strong>de</strong> données <strong>de</strong>puis le serveur <strong>de</strong> base <strong>de</strong><br />
données.<br />
Les structures sont définies dans le fichier sqlca.h. Les types VARCHAR,<br />
BINARY et DECIMAL contiennent un tableau <strong>de</strong> un caractère et ne peuvent<br />
donc pas servir à déclarer <strong>de</strong>s variables hôtes ; elles sont toutefois utiles pour<br />
allouer dynamiquement <strong>de</strong>s variables ou pour transtyper d'autres variables.<br />
Dans l'interface Embed<strong>de</strong>d SQL, il n'existe pas <strong>de</strong> types <strong>de</strong> données<br />
correspondant aux différents types DATE et TIME <strong>de</strong> base <strong>de</strong> données. Tous<br />
ces types <strong>de</strong> base <strong>de</strong> données sont lus et mis à jour soit à l'ai<strong>de</strong> <strong>de</strong> la structure<br />
SQLDATETIME, soit à l'ai<strong>de</strong> <strong>de</strong> chaînes <strong>de</strong> caractères.<br />
$ Pour plus d'informations, reportez-vous aux sections "Instruction GET<br />
DATA [ESQL]", page 459 du document ASA Manuel <strong>de</strong> référence SQL et<br />
"Instruction SET", page 557 du document ASA Manuel <strong>de</strong> référence SQL.<br />
195
Utilisation <strong>de</strong>s variables hôte<br />
Utilisation <strong>de</strong>s variables hôte<br />
Déclaration <strong>de</strong>s variables hôte<br />
Exemple<br />
196<br />
Les variables hôte sont <strong>de</strong>s variables <strong>de</strong> langage C i<strong>de</strong>ntifiées auprès du<br />
préprocesseur SQL. Elles peuvent être utilisées pour transmettre <strong>de</strong>s valeurs<br />
ou pour en recevoir du serveur <strong>de</strong> base <strong>de</strong> données.<br />
D'utilisation aisée, les variables hôte présentent néanmoins certaines<br />
restrictions. Le SQL dynamique représente une métho<strong>de</strong> plus courante pour<br />
transmettre <strong>de</strong>s informations <strong>de</strong>puis et vers le serveur <strong>de</strong> base <strong>de</strong> données à<br />
l'ai<strong>de</strong> <strong>de</strong> la structure appelée zone <strong>de</strong>scripteur SQL (SQLDA). Le<br />
préprocesseur SQL génère automatiquement un SQLDA pour chaque<br />
instruction dans laquelle <strong>de</strong>s variables hôte sont utilisées.<br />
$ Pour plus d'informations sur le SQL dynamique, reportez-vous à la<br />
section "SQL statique et SQL dynamique", page 221.<br />
Pour être définies, les variables hôte doivent être placées dans une section <strong>de</strong><br />
déclaration. Conformément aux normes IBM SAA et ANSI<br />
Embed<strong>de</strong>d SQL, les variables hôte doivent encadrer les déclarations <strong>de</strong><br />
variables en langage C normales, comme suit :<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
/* déclaration <strong>de</strong>s variables C */<br />
EXEC SQL END DECLARE SECTION;<br />
Les variables hôte peuvent donc remplacer les constantes dans n'importe<br />
quelle instruction SQL. Lorsque le serveur <strong>de</strong> base <strong>de</strong> données exécute la<br />
comman<strong>de</strong>, il utilise la valeur <strong>de</strong> la variable hôte. Toutefois, sachez que ce<br />
type <strong>de</strong> variable ne peut pas remplacer un nom <strong>de</strong> table ou <strong>de</strong> colonne ; pour<br />
ce faire, un SQL dynamique est requis. Dans une instruction SQL, le nom <strong>de</strong><br />
la variable est précédé du signe <strong>de</strong>ux-points (:) pour le distinguer d'autres<br />
i<strong>de</strong>ntificateurs admis dans l'instruction.<br />
Un préprocesseur SQL standard ne tient pas compte du co<strong>de</strong> en langage C,<br />
excepté dans une section <strong>de</strong> déclaration (DECLARE SECTION). Les types<br />
et les structures TYPEDEF ne sont donc pas autorisés. En revanche, les<br />
initialiseurs sur les variables sont admis dans une section <strong>de</strong> déclaration.<br />
♦ L'exemple <strong>de</strong> co<strong>de</strong> suivant illustre l'utilisation <strong>de</strong> variables hôte dans une<br />
comman<strong>de</strong> INSERT. La valeur <strong>de</strong>s variables est attribuée par le<br />
programme avant qu'elles ne soient insérées dans la base <strong>de</strong> données :
Types <strong>de</strong> variable hôte en langage C<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
long employee_number;<br />
char employee_name[50];<br />
char employee_initials[8];<br />
char employee_phone[15];<br />
EXEC SQL END DECLARE SECTION;<br />
/* le programme affecte la valeur appropriée à<br />
chaque variable<br />
*/<br />
EXEC SQL INSERT INTO Employee<br />
VALUES (:employee_number, :employee_name,<br />
:employee_initials, :employee_phone );<br />
$ Pour obtenir un exemple plus détaillé, reportez-vous à la section<br />
"Exemple <strong>de</strong> curseur statique", page 189.<br />
Seul un nombre limité <strong>de</strong> types <strong>de</strong> données du langage C est supporté pour<br />
les variables hôte. En outre, certains types <strong>de</strong> variable hôte n'ont pas <strong>de</strong> type<br />
correspondant en langage C.<br />
Les macros définies dans le fichier d'en-tête sqlca.h peuvent être utilisées<br />
pour déclarer <strong>de</strong>s variables hôte <strong>de</strong> plusieurs types : VARCHAR, FIXCHAR,<br />
BINARY, PACKED DECIMAL, LONG VARCHAR, LONG BINARY ou<br />
structure SQLDATETIME. Ils sont utilisés comme suit :<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
DECL_VARCHAR( 10 ) v_varchar;<br />
DECL_FIXCHAR( 10 ) v_fixchar;<br />
DECL_LONGVARCHAR( 32678 ) v_longvarchar;<br />
DECL_BINARY( 4000 ) v_binary;<br />
DECL_LONGBINARY( 128000 ) v_longbinary;<br />
DECL_DECIMAL( 10, 2 ) v_packed_<strong>de</strong>cimal;<br />
DECL_DATETIME v_datetime;<br />
EXEC SQL END DECLARE SECTION;<br />
Le préprocesseur reconnaît ces macros à l'intérieur d'une section <strong>de</strong><br />
déclaration et traite la variable en fonction du type correspondant.<br />
Le tableau suivant répertorie les types <strong>de</strong> variable C admis en tant que<br />
variables hôte et les types <strong>de</strong> données correspondants dans l'interface<br />
Embed<strong>de</strong>d SQL.<br />
197
Utilisation <strong>de</strong>s variables hôte<br />
198<br />
Type <strong>de</strong> données en<br />
langage C<br />
short i;<br />
short int i;<br />
unsigned short int i;<br />
long l;<br />
long int l;<br />
unsigned long int l;<br />
Type <strong>de</strong> données<br />
d'interface Embed<strong>de</strong>d SQL<br />
Description<br />
DT_SMALLINT Entier signé (16 bits)<br />
DT_INT Entier signé (32 bits)<br />
float f; DT_FLOAT Nombre en virgule flottante<br />
(4 octets)<br />
double d; DT_DOUBLE Nombre en virgule flottante<br />
(8 octets)<br />
DECL_DECIMAL(p,s) DT_DECIMAL(p,s) Nombre décimal con<strong>de</strong>nsé<br />
char a; /*n=1*/<br />
DECL_FIXCHAR(n) a;<br />
DECL_FIXCHAR a[n];<br />
DT_FIXCHAR(n) Chaîne <strong>de</strong> caractères <strong>de</strong><br />
longueur fixe complétée par<br />
<strong>de</strong>s blancs<br />
char a[n]; /*n>=1*/ DT_STRING(n) Chaîne terminée par une<br />
valeur NULL. Elle est<br />
complétée par <strong>de</strong>s blancs si<br />
la base <strong>de</strong> données est<br />
initialisée avec <strong>de</strong>s chaînes<br />
complétées par <strong>de</strong>s blancs.<br />
char *a; DT_STRING(32767) Chaîne terminée par une<br />
valeur NULL
Pointeurs sur <strong>de</strong>s<br />
données <strong>de</strong> type<br />
char<br />
Type <strong>de</strong> données en<br />
langage C<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Type <strong>de</strong> données<br />
d'interface Embed<strong>de</strong>d SQL<br />
Description<br />
DECL_VARCHAR(n) a; DT_VARCHAR(n) Chaîne <strong>de</strong> caractères <strong>de</strong><br />
longueur variable<br />
comportant un champ<br />
"longueur" <strong>de</strong> <strong>de</strong>ux octets.<br />
Non complétée par <strong>de</strong>s<br />
blancs.<br />
DECL_BINARY(n) a; DT_BINARY(n) Données binaires <strong>de</strong><br />
longueur variable<br />
comportant un champ<br />
"longueur" <strong>de</strong> <strong>de</strong>ux octets<br />
DECL_DATETIME a; DT_TIMESTAMP_STRUCT Structure SQLDATETIME<br />
DECL_LONGVARCHAR( n<br />
) a;<br />
DT_LONGVARCHAR Chaîne longue <strong>de</strong> caractères<br />
<strong>de</strong> longueur variable<br />
comportant trois champs<br />
"longueur" <strong>de</strong> 4 octets. Non<br />
complétée par <strong>de</strong>s blancs ni<br />
terminée par une valeur<br />
NULL.<br />
DECL_LONGBINARY( n ) a; DT_LONGBINARY Données binaires longues<br />
<strong>de</strong> longueur variable<br />
comportant trois champs<br />
"longueur" <strong>de</strong> 4 octets Non<br />
complétée par <strong>de</strong>s blancs.<br />
Une variable hôte déclarée en tant que pointeur sur <strong>de</strong>s données <strong>de</strong> type<br />
caractère (char *a) est considérée par l'interface <strong>de</strong> la base <strong>de</strong> données<br />
comme ayant une longueur <strong>de</strong> 32 767 octets. Toute variable hôte <strong>de</strong> ce type<br />
utilisée pour récupérer <strong>de</strong>s informations <strong>de</strong> la base <strong>de</strong> données doit pointer<br />
sur un buffer d'une taille suffisante pour contenir toute valeur susceptible<br />
d'être renvoyée par la base.<br />
Cette solution peut être à l'origine <strong>de</strong> problèmes lorsque la définition d'une<br />
colonne dans la base a été modifiée et qu'elle est plus gran<strong>de</strong> que lorsque le<br />
programme a été écrit. Une telle opération risque d'altérer la mémoire vive.<br />
De plus, si vous utilisez un compilateur 16 bits, une <strong>de</strong>man<strong>de</strong> <strong>de</strong> 32 767<br />
octets risque <strong>de</strong> provoquer un débor<strong>de</strong>ment <strong>de</strong> la pile du programme. Il est<br />
donc préférable <strong>de</strong> faire appel à un tableau déclaré, même comme paramètre<br />
d'une fonction où il est transmis en tant que pointeur sur <strong>de</strong>s données <strong>de</strong><br />
type char. Les instructions PREPARE peuvent ainsi i<strong>de</strong>ntifier la taille du<br />
tableau.<br />
199
Utilisation <strong>de</strong>s variables hôte<br />
Portée <strong>de</strong>s<br />
variables hôte<br />
Utilisation <strong>de</strong>s variables hôte<br />
Exemples<br />
200<br />
La section <strong>de</strong> déclaration d'une variable hôte standard peut être située aux<br />
emplacements où les variables en langage C peuvent normalement être<br />
déclarées. Cela inclut la section <strong>de</strong> déclaration <strong>de</strong> paramètres d'une fonction<br />
en langage C. Les variables en langage C ont leur portée normale au sein du<br />
bloc dans lequel elles sont définies. Toutefois, le préprocesseur SQL<br />
n'analysant pas le co<strong>de</strong> en langage C, il ne respecte pas les blocs C.<br />
En ce qui concerne le préprocesseur SQL, les variables hôte sont globales ; il<br />
n'est pas possible que <strong>de</strong>ux <strong>de</strong> ces variables portent le même nom.<br />
Les variables hôte peuvent être utilisées dans les circonstances suivantes :<br />
♦ Dans les instructions SELECT, INSERT, UPDATE ou DELETE,<br />
partout où un nombre ou une constante <strong>de</strong> type chaîne est autorisé.<br />
♦ Dans la clause INTO <strong>de</strong>s instructions SELECT et FETCH.<br />
♦ Les variables hôte peuvent également remplacer un nom d'instruction, <strong>de</strong><br />
curseur ou d'option dans <strong>de</strong>s comman<strong>de</strong>s spécifiques d'Embed<strong>de</strong>d SQL.<br />
♦ Pour CONNECT, DISCONNECT et SET CONNECT, une variable hôte<br />
peut remplacer un ID utilisateur, un mot <strong>de</strong> passe, un nom <strong>de</strong> connexion<br />
ou d'environnement <strong>de</strong> base <strong>de</strong> données.<br />
♦ Pour SET OPTION et GET OPTION, une variable hôte peut remplacer<br />
un ID utilisateur, un nom d'option ou une valeur d'option.<br />
♦ Les variables hôte ne peuvent pas remplacer un nom <strong>de</strong> table ou <strong>de</strong><br />
colonne dans une instruction.<br />
♦ L'exemple ci-<strong>de</strong>ssous illustre une syntaxe Embed<strong>de</strong>d SQL correcte :<br />
INCLUDE SQLCA;<br />
long SQLCODE;<br />
sub1() {<br />
char SQLSTATE[6];<br />
exec SQL CREATE TABLE ...<br />
}<br />
♦ L'exemple ci-<strong>de</strong>ssous illustre une syntaxe Embed<strong>de</strong>d SQL incorrecte :
Variables indicateur<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
INCLUDE SQLCA;<br />
sub1() {<br />
char SQLSTATE[6];<br />
exec SQL CREATE TABLE...<br />
}<br />
sub2() {<br />
exec SQL DROP TABLE...<br />
// Pas <strong>de</strong> SQLSTATE dans la portée <strong>de</strong> cette<br />
instruction<br />
}<br />
♦ Le cas <strong>de</strong> SQLSTATE et <strong>de</strong> SQLCODE est important et la norme<br />
ISO/ANSI requiert qu'ils soient définis exactement comme suit :<br />
long SQLCODE;<br />
char SQLSTATE[6];<br />
Les variables indicateur sont <strong>de</strong>s variables en langage C qui fournissent <strong>de</strong>s<br />
informations complémentaires pour les opérations <strong>de</strong> lecture ou d'insertion<br />
<strong>de</strong> données. Il existe plusieurs types d'utilisation pour ces variables :<br />
♦ Valeurs NULL Pour permettre aux applications <strong>de</strong> gérer les valeurs<br />
NULL.<br />
♦ Troncature <strong>de</strong> chaînes Pour permettre aux applications <strong>de</strong> gérer les cas<br />
où les valeurs lues doivent être tronquées pour tenir dans les variables<br />
hôte.<br />
♦ Erreurs <strong>de</strong> conversion Pour stocker les informations relatives aux<br />
erreurs.<br />
Une variable indicateur est une variable hôte <strong>de</strong> type short int suivant<br />
immédiatement une variable hôte normale dans une instruction SQL. Par<br />
exemple, dans l'instruction INSERT ci-<strong>de</strong>ssous, :ind_phone est une variable<br />
indicateur :<br />
EXEC SQL INSERT INTO Employee<br />
VALUES (:employee_number, :employee_name,<br />
:employee_initials, :employee_phone:ind_phone );<br />
Utilisation <strong>de</strong> variables indicateur pour gérer les valeurs NULL<br />
Dans les données SQL, la valeur NULL représente un attribut inconnu ou<br />
une information non applicable. Il ne faut pas confondre la valeur NULL <strong>de</strong><br />
SQL avec la constante C du même nom (NULL). Cette <strong>de</strong>rnière représente<br />
un pointeur non initialisé ou incorrect.<br />
201
Utilisation <strong>de</strong>s variables hôte<br />
Utilisation <strong>de</strong><br />
variables indicateur<br />
pour l’insertion <strong>de</strong><br />
valeurs NULL<br />
Utilisation <strong>de</strong><br />
variables indicateur<br />
pour la lecture <strong>de</strong><br />
valeurs NULL<br />
202<br />
Dans la documentation d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, toute référence à la<br />
valeur NULL renvoie à sa signification relative aux bases <strong>de</strong> données SQL<br />
indiquée ci-<strong>de</strong>ssus. La constante C est désignée sous le nom <strong>de</strong> pointeur null<br />
(en minuscules).<br />
La valeur NULL n'est pas <strong>de</strong> même nature que toute autre valeur <strong>de</strong> type<br />
défini pour les colonnes. Par conséquent, pour transmettre <strong>de</strong>s valeurs NULL<br />
à la base <strong>de</strong> données ou en recevoir <strong>de</strong>s résultats NULL, <strong>de</strong>s variables hôte<br />
d'un type particulier sont requises. Les variables indicateur sont utilisées<br />
dans cette optique.<br />
Une instruction INSERT peut contenir une variable indicateur comme suit :<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
short int employee_number;<br />
char employee_name[50];<br />
char employee_initials[6];<br />
char employee_phone[15];<br />
short int ind_phone;<br />
EXEC SQL END DECLARE SECTION;<br />
/*<br />
le programme fournit le numéro d'i<strong>de</strong>ntification <strong>de</strong><br />
l'employé, son nom,<br />
ses initiales et son numéro <strong>de</strong> téléphone<br />
*/<br />
if( /* numéro <strong>de</strong> téléphone inconnu */ ) {<br />
ind_phone = -1;<br />
} else {<br />
ind_phone = 0;<br />
}<br />
EXEC SQL INSERT INTO Employee<br />
VALUES (:employee_number, :employee_name,<br />
:employee_initials, :employee_phone:ind_phone );<br />
Si la valeur <strong>de</strong> la variable indicateur est égale à –1, une valeur NULL est<br />
écrite. Si la valeur est égale à 0 (zéro), la valeur effective <strong>de</strong><br />
employee_phone est écrite.<br />
Les variables indicateur sont également utilisées lors <strong>de</strong> la réception <strong>de</strong><br />
données <strong>de</strong> la base. Elles indiquent qu'une valeur NULL a été lue (indicateur<br />
négatif). Si une valeur NULL est lue dans la base <strong>de</strong> données et qu'aucune<br />
variable indicateur n'est fournie, une erreur est générée<br />
(SQLE_NO_INDICATOR). Les erreurs sont décrites à la section suivante.<br />
Utilisation <strong>de</strong> variables indicateur pour les valeurs tronquées<br />
Les variables indicateur permettent d'indiquer les valeurs lues qui ont été<br />
tronquées pour tenir dans une variable hôte. Ainsi, les applications peuvent<br />
gérer la troncature <strong>de</strong> façon adéquate.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Si une valeur est tronquée à la lecture, la variable indicateur présente alors<br />
une valeur positive qui contient la longueur effective <strong>de</strong> la valeur dans la<br />
base <strong>de</strong> données avant troncature. Si cette valeur a une longueur supérieure à<br />
32 767, la variable indicateur contient la valeur 32 767.<br />
Utilisation <strong>de</strong> variables indicateur pour les erreurs <strong>de</strong> conversion<br />
Par défaut, l'option <strong>de</strong> base <strong>de</strong> données CONVERSION_ERROR est définie<br />
sur ON (activée) et tout échec <strong>de</strong> conversion <strong>de</strong>s types <strong>de</strong> données provoque<br />
une erreur, sans renvoi <strong>de</strong> ligne.<br />
Vous pouvez utiliser <strong>de</strong>s variables indicateur pour indiquer la colonne qui a<br />
provoqué un échec <strong>de</strong> conversion du type <strong>de</strong> données. Si vous désactivez<br />
(OFF) l'option <strong>de</strong> base <strong>de</strong> données CONVERSION_ERROR, les échecs <strong>de</strong><br />
conversion renvoient un avertissement CANNOT_CONVERT et non une<br />
erreur. Si la colonne sur laquelle l'erreur s'est produite contient une variable<br />
indicateur, cette <strong>de</strong>rnière est prend la valeur -2.<br />
Si vous définissez CONVERSION_ERROR sur OFF lorsque vous insérez<br />
<strong>de</strong>s données dans la base, la valeur NULL est insérée en cas d'échec <strong>de</strong><br />
conversion.<br />
Récapitulatif <strong>de</strong>s valeurs <strong>de</strong>s variables indicateur<br />
Le tableau ci-<strong>de</strong>ssous illustre l’utilisation <strong>de</strong>s variables indicateur.<br />
Valeur<br />
indicate<br />
ur<br />
Valeur fournie à la<br />
base <strong>de</strong> données<br />
Valeur reçue <strong>de</strong> la base <strong>de</strong><br />
données<br />
> 0 Valeur <strong>de</strong> variable hôte Valeur reçue tronquée (valeur réelle<br />
dans la variable indicateur)<br />
0 Valeur <strong>de</strong> variable hôte Lecture aboutie ou<br />
CONVERSION_ERROR définie sur<br />
ON<br />
–1 Valeur NULL Résultat NULL<br />
–2 Valeur NULL Erreur <strong>de</strong> conversion (seulement<br />
lorsque CONVERSION_ERROR est<br />
définie sur OFF). SQLCODE indique<br />
un avertissement<br />
CANNOT_CONVERT<br />
< –2 Valeur NULL Résultat NULL<br />
203
Utilisation <strong>de</strong>s variables hôte<br />
204<br />
$ Pour plus d'informations sur la récupération <strong>de</strong> valeurs longues,<br />
reportez-vous à la section "Instruction GET DATA [ESQL]", page 459 du<br />
document ASA Manuel <strong>de</strong> référence SQL.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Zone <strong>de</strong> communication SQL (SQLCA)<br />
Co<strong>de</strong>s d’erreur<br />
SQLCA<br />
Champs SQLCA<br />
La zone <strong>de</strong> communication SQL (SQLCA) est une zone <strong>de</strong> mémoire qui<br />
permet, pour chaque <strong>de</strong>man<strong>de</strong> adressée à la base <strong>de</strong> données, <strong>de</strong><br />
communiquer <strong>de</strong>s statistiques et <strong>de</strong> signaler <strong>de</strong>s erreurs <strong>de</strong> l'application au<br />
serveur <strong>de</strong> base <strong>de</strong> données, et inversement. La zone SQLCA joue le rôle <strong>de</strong><br />
<strong>de</strong>scripteur pour le lien <strong>de</strong> communication entre l'application et la base <strong>de</strong><br />
données. Elle est transmise à toutes les fonctions <strong>de</strong> bibliothèque <strong>de</strong> base <strong>de</strong><br />
données <strong>de</strong>vant communiquer avec le serveur <strong>de</strong> base <strong>de</strong> données. Elle est<br />
également transmise implicitement à toutes les instructions SQL.<br />
Une variable SQLCA globale est définie dans la bibliothèque d'interface. Le<br />
préprocesseur génère <strong>de</strong>ux références externes, l'une pour la variable<br />
SQLCA globale et l'autre pour un pointeur sur cette variable. La référence<br />
externe, sqlca, est <strong>de</strong> type SQLCA. Le pointeur est dénommé sqlcaptr. La<br />
variable globale elle-même est déclarée dans la bibliothèque d'importation.<br />
La zone SQLCA est définie par le fichier d'en-tête sqlca.h, inclus dans le<br />
sous-répertoire h du répertoire d'installation.<br />
En consultant la zone SQLCA, vous pouvez tester un co<strong>de</strong> d'erreur<br />
spécifique. Un co<strong>de</strong> d'erreur s'affiche dans les champs sqlco<strong>de</strong> et sqlstate<br />
lorsqu'une requête adressée à la base <strong>de</strong> données provoque une erreur (voir<br />
ci-<strong>de</strong>ssous). Il existe <strong>de</strong>s macros en langage C permettant <strong>de</strong> référencer le<br />
champ sqlco<strong>de</strong>, le champ sqlstate et d'autres champs.<br />
Voici la signification <strong>de</strong>s champs <strong>de</strong> la zone SQLCA :<br />
♦ sqlcaid Champ <strong>de</strong> type caractère codé sur 8 octets contenant la chaîne<br />
SQLCA, qui i<strong>de</strong>ntifie la structure SQLCA. Ce champ facilite le<br />
débogage lors <strong>de</strong> l'analyse du contenu <strong>de</strong> la mémoire.<br />
♦ sqlcabc Entier long correspondant à la longueur <strong>de</strong> la structure SQLCA<br />
(136 octets).<br />
♦ sqlco<strong>de</strong> Entier long spécifiant le co<strong>de</strong> d'erreur lorsque la base <strong>de</strong><br />
données détecte une erreur dans une <strong>de</strong>man<strong>de</strong>. Le fichier d'en-tête<br />
sqlerr.h. contient les définitions <strong>de</strong>s co<strong>de</strong>s d'erreur. Le co<strong>de</strong> est égal à 0<br />
(zéro) pour les opérations réussies, il est positif pour les avertissements<br />
et négatif pour les erreurs.<br />
$ Pour obtenir la liste complète <strong>de</strong>s co<strong>de</strong>s d'erreur, reportez-vous à la<br />
section "Messages d'erreur <strong>de</strong> bases <strong>de</strong> données", page 1 du document<br />
ASA Messages d’erreur.<br />
205
Zone <strong>de</strong> communication SQL (SQLCA)<br />
Tableau sqlerror<br />
206<br />
♦ sqlerrml Indique la longueur <strong>de</strong>s données contenues dans le champ<br />
sqlerrmc.<br />
♦ sqlerrmc Chaîne <strong>de</strong> caractères (une, plusieurs ou aucune) à insérer dans<br />
un message d'erreur. Certains messages d'erreur contiennent une ou<br />
plusieurs chaînes <strong>de</strong> réservation (%1, %2, ...) qui sont remplacées par les<br />
chaînes <strong>de</strong> ce champ.<br />
Par exemple, si une erreur du type La table est introuvable est générée,<br />
sqlerrmc contient le nom <strong>de</strong> la table qui est inséré à l'endroit approprié<br />
dans le message d'erreur.<br />
$ Pour obtenir la liste complète <strong>de</strong>s messages d'erreur, reportez-vous<br />
à la section "Messages d'erreur <strong>de</strong> bases <strong>de</strong> données", page 1 du<br />
document ASA Messages d’erreur.<br />
♦ sqlerrp Réservé.<br />
♦ sqlerrd Table d'entiers longs.<br />
♦ sqlwarn Réservé.<br />
♦ sqlstate Valeur d'état SQLSTATE. La norme SQL ANSI (SQL-92)<br />
définit un nouveau type <strong>de</strong> valeur renvoyée par une instruction SQL, en<br />
plus <strong>de</strong> la valeur SQLCODE définie dans <strong>de</strong>s normes antérieures. La<br />
valeur SQLSTATE est toujours une chaîne <strong>de</strong> cinq caractères terminée<br />
par une valeur NULL, divisée en une classe <strong>de</strong> <strong>de</strong>ux caractères (les <strong>de</strong>ux<br />
premiers) et une sous-classe <strong>de</strong> trois caractères. Chaque caractère peut<br />
être un chiffre compris entre 0 et 9 ou une lettre majuscule comprise<br />
entre A et Z.<br />
Toute classe ou sous-classe commençant par un chiffre compris entre 0<br />
et 4 ou une lettre comprise entre A et H, est définie par la norme SQL ;<br />
les autres classes ou sous-classes sont définies lors <strong>de</strong> la mise en oeuvre.<br />
La valeur SQLSTATE '00000' signifie qu'il n'y a eu ni erreur ni<br />
avertissement.<br />
$ Pour connaître les autres valeurs SQLSTATE, reportez-vous à la<br />
section "Messages d'erreur <strong>de</strong> bases <strong>de</strong> données", page 1 du document<br />
ASA Messages d’erreur.<br />
Le tableau du champ sqlerror contient les éléments ci-après :<br />
♦ sqlerrd[1] (SQLIOCOUNT) Nombre effectif d'entrées/sorties requises<br />
pour l'exécution d'une comman<strong>de</strong>.<br />
La base <strong>de</strong> données ne démarre pas à zéro pour chaque comman<strong>de</strong>.<br />
Votre programme peut attribuer la valeur zéro à cette variable avant<br />
d'exécuter une séquence <strong>de</strong> comman<strong>de</strong>s. Après l'exécution <strong>de</strong> la <strong>de</strong>rnière<br />
comman<strong>de</strong>, ce nombre correspond au nombre total d'entrées/sorties pour<br />
toute la séquence <strong>de</strong> comman<strong>de</strong>s.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ sqlerrd[2] (SQLCOUNT) La valeur <strong>de</strong> ce champ est fonction <strong>de</strong><br />
l'instruction exécutée.<br />
♦ Instructions INSERT, UPDATE, PUT et DELETE Nombre <strong>de</strong> lignes<br />
traitées par l'instruction.<br />
Sur un curseur OPEN, ce champ est complété soit avec le nombre<br />
effectif <strong>de</strong> lignes du curseur (c'est-à-dire une valeur supérieure ou<br />
égale à 0), soit avec une valeur estimée <strong>de</strong> ce nombre (nombre<br />
négatif dont la valeur absolue est cette valeur estimée). C'est le<br />
nombre effectif <strong>de</strong> lignes qui est pris en compte si le serveur <strong>de</strong> base<br />
<strong>de</strong> données peut le calculer sans compter les lignes. La base <strong>de</strong><br />
données peut également être configurée <strong>de</strong> sorte à toujours renvoyer<br />
le nombre réel <strong>de</strong> lignes par l'intermédiaire <strong>de</strong> l'option<br />
ROW_COUNTS.<br />
♦ Instruction <strong>de</strong> curseur FETCH Le champ SQLCOUNT est<br />
complété si un avertissement SQLE_NOTFOUND est renvoyé. Cet<br />
avertissement fournit le nombre <strong>de</strong> lignes hors <strong>de</strong> l'intervalle <strong>de</strong><br />
positions <strong>de</strong> curseur possibles renvoyées par une instruction<br />
FETCH RELATIVE ou FETCH ABSOLUTE (un curseur peut se<br />
trouver sur une ligne, avant la première ligne ou après la <strong>de</strong>rnière<br />
ligne). Dans le cas d'une extraction étendue, SQLCOUNT<br />
correspond au nombre <strong>de</strong> lignes réellement extraites et il est<br />
inférieur ou égal au nombre <strong>de</strong> lignes <strong>de</strong>mandées. Durant une<br />
extraction étendue, SQLE_NOTFOUND n'est pas défini.<br />
$ Pour plus d'informations sur les extractions étendues, reportezvous<br />
à la section "Extraction simultanée <strong>de</strong> plusieurs lignes",<br />
page 215.<br />
La valeur est 0 (zéro) si la ligne est introuvable bien que la position<br />
soit correcte, par exemple, en exécutant FETCH RELATIVE 1<br />
lorsque vous êtes positionné sur la <strong>de</strong>rnière ligne d'un curseur. La<br />
valeur est positive si la tentative d'extraction a été effectuée au-<strong>de</strong>là<br />
<strong>de</strong> la <strong>de</strong>rnière position du curseur, et négative si elle a été effectuée<br />
avant le début du curseur.<br />
♦ Instruction GET DATA Le champ SQLCOUNT contient la<br />
longueur réelle <strong>de</strong> la valeur.<br />
♦ Instruction DESCRIBE Dans la clause WITH VARIABLE<br />
RESULT utilisée pour décrire <strong>de</strong>s procédures pouvant générer<br />
plusieurs jeux <strong>de</strong> résultats, SQLCOUNT est défini sur l'une <strong>de</strong>s<br />
valeurs ci-<strong>de</strong>ssous :<br />
♦ 0 Le jeu <strong>de</strong> résultats est variable : il convient <strong>de</strong> décrire l'appel<br />
<strong>de</strong> procédure après chaque instruction OPEN.<br />
207
Zone <strong>de</strong> communication SQL (SQLCA)<br />
208<br />
♦ 1 Le jeu <strong>de</strong> résultats est fixe : aucune nouvelle <strong>de</strong>scription n'est<br />
requise.<br />
Dans le cas d'une erreur <strong>de</strong> syntaxe (SQLE_SYNTAX_ERROR), ce<br />
champ contient la position approximative du caractère dans la<br />
chaîne <strong>de</strong> comman<strong>de</strong> où l'erreur a été détectée.<br />
♦ sqlerrd[3] (SQLIOESTIMATE) Nombre estimé d'entrées/sorties requises<br />
pour l'exécution <strong>de</strong> la comman<strong>de</strong>. Ce champ reçoit une valeur pour une<br />
comman<strong>de</strong> OPEN ou EXPLAIN.<br />
Gestion <strong>de</strong> la zone SQLCA pour le co<strong>de</strong> multi-thread ou réentrant<br />
Vous pouvez insérer <strong>de</strong>s instructions Embed<strong>de</strong>d SQL dans du co<strong>de</strong><br />
multi-threa<strong>de</strong>d ou réentrant. Cependant, si vous utilisez une connexion<br />
unique, vous êtes limité à une <strong>de</strong>man<strong>de</strong> active par connexion. Dans une<br />
application multi-threa<strong>de</strong>d, ne faites pas appel à la même connexion <strong>de</strong> base<br />
<strong>de</strong> données sur chaque thread, à moins <strong>de</strong> contrôler l'accès à l'ai<strong>de</strong> d'un<br />
sémaphore.<br />
Il n'existe pas <strong>de</strong> restrictions sur l'utilisation <strong>de</strong> connexions séparées sur<br />
chaque thread souhaitant accé<strong>de</strong>r à la base <strong>de</strong> données. La bibliothèque<br />
d'exécution utilise la zone SQLCA pour distinguer les différents contextes <strong>de</strong><br />
thread. Ainsi, chaque thread souhaitant accé<strong>de</strong>r à la base <strong>de</strong> données doit<br />
disposer <strong>de</strong> sa propre zone SQLCA.<br />
Une connexion donnée n'est accessible qu'à partir d'une zone SQLCA<br />
unique, à l'exception d'une instruction d'annulation, qui doit être formulée à<br />
partir d'un thread distinct.<br />
$ Pour plus d'informations sur l'annulation <strong>de</strong>s requêtes, reportez-vous à<br />
la section "Mise en oeuvre <strong>de</strong> la gestion <strong>de</strong>s requêtes", page 245.<br />
Utilisation <strong>de</strong> plusieurs zones SQLCA<br />
v Pour gérer plusieurs zones SQLCA dans votre application :<br />
1 Vous <strong>de</strong>vez indiquer, pour le préprocesseur SQL, l'option qui génère du<br />
co<strong>de</strong> réentrant (-r). Ce co<strong>de</strong> prend un peu plus <strong>de</strong> place et est un peu<br />
plus lent, car il ne permet pas d'utiliser les variables globales initialisées<br />
<strong>de</strong> manière statique. Cette contrainte est toutefois mineure.<br />
2 Chaque zone SQLCA utilisée dans un programme doit être initialisée<br />
par un appel <strong>de</strong> db_init, puis éliminée par un appel <strong>de</strong> db_fini.
Utilisation <strong>de</strong> plusieurs zones SQLCA<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Attention<br />
Sous NetWare, si db_fini n'est pas appelé pour chaque db_init, le<br />
serveur <strong>de</strong> base <strong>de</strong> données et le serveur <strong>de</strong> fichiers NetWare<br />
risquent <strong>de</strong> s'arrêter.<br />
3 L’instruction Embed<strong>de</strong>d SQL SET SQLCA (voir "Instruction SET<br />
SQLCA [ESQL]", page 572 du document ASA Manuel <strong>de</strong> référence<br />
SQL) permet d'indiquer au préprocesseur SQL d'utiliser une autre zone<br />
SQLCA pour les requêtes adressées à la base <strong>de</strong> données. Généralement,<br />
il s'agit d'une instruction <strong>de</strong> ce type : EXEC SQL SET SQLCA<br />
'task_data->sqlca'. Elle est utilisée en début <strong>de</strong> programme ou dans un<br />
fichier d'en-tête afin que la référence à la zone SQLCA pointe sur <strong>de</strong>s<br />
données spécifiques <strong>de</strong> la tâche. Cette instruction ne génère aucun co<strong>de</strong><br />
et n'influe donc pas sur les performances. Elle modifie l'état interne du<br />
préprocesseur pour que toute référence à la zone SQLCA utilise la<br />
chaîne appropriée.<br />
$ Pour plus d'informations sur la création <strong>de</strong> zones SQLCA, reportezvous<br />
à la section "Instruction SET SQLCA [ESQL]", page 572 du document<br />
ASA Manuel <strong>de</strong> référence SQL.<br />
Vous pouvez utiliser plusieurs SQLCA dans tous les environnements<br />
Embed<strong>de</strong>d SQL pris en charge ; dans le cas du co<strong>de</strong> réentrant, le recours à<br />
<strong>de</strong>s zones SQLCA multiples est obligatoire.<br />
Les environnements dans lesquels vous <strong>de</strong>vez faire appel à plusieurs SQLCA<br />
sont détaillés ci-après :<br />
♦ Applications Multi-threa<strong>de</strong>d Si <strong>de</strong>ux threads tentent d'accé<strong>de</strong>r à la<br />
même zone SQLCA, une option <strong>de</strong> contexte peut entraîner l'utilisation<br />
simultanée <strong>de</strong> la même zone SQLCA par les <strong>de</strong>ux threads. Chaque<br />
thread doit disposer <strong>de</strong> sa propre zone SQLCA. Ce peut être également<br />
le cas si une DLL utilisant Embed<strong>de</strong>d SQL est appelée par plusieurs<br />
threads <strong>de</strong> l'application.<br />
♦ Bibliothèques <strong>de</strong> liens dynamiques (DLL) et bibliothèques<br />
partagées Une DLL dispose d'un seul segment <strong>de</strong> données. Pendant que<br />
le serveur <strong>de</strong> base <strong>de</strong> données traite une requête d'une application<br />
donnée, il peut cé<strong>de</strong>r la priorité à une autre application qui lui envoie<br />
également une requête. Si votre DLL utilise la zone SQLCA globale, les<br />
<strong>de</strong>ux applications utilisent cette <strong>de</strong>rnière simultanément. Chaque<br />
application Windows doit disposer <strong>de</strong> sa propre zone SQLCA.<br />
209
Zone <strong>de</strong> communication SQL (SQLCA)<br />
210<br />
♦ DLL avec un segment <strong>de</strong> données Il est possible <strong>de</strong> créer une DLL<br />
avec un segment <strong>de</strong> données unique ou avec un segment <strong>de</strong> données<br />
pour chaque application. Si votre DLL ne comporte qu'un seul segment<br />
<strong>de</strong> données, vous ne pouvez pas utiliser la zone SQLCA globale (tout<br />
comme une DLL ne peut pas utiliser la zone SQLCA globale). Chaque<br />
application doit disposer <strong>de</strong> sa propre zone SQLCA.<br />
Gestion <strong>de</strong>s connexions avec plusieurs zones SQLCA<br />
Il n'est pas nécessaire d'avoir recours à plusieurs zones SQLCA pour vous<br />
connecter à plusieurs bases <strong>de</strong> données ou pour disposer <strong>de</strong> plusieurs<br />
connexions à une même base <strong>de</strong> données.<br />
Chaque zone SQLCA peut avoir une connexion non nommée. Chaque zone<br />
SQLCA dispose d'une connexion active (reportez-vous à la section<br />
"Instruction SET CONNECTION [Interactive SQL] [ESQL]", page 563 du<br />
document ASA Manuel <strong>de</strong> référence SQL). Toutes les opérations effectuées<br />
par le biais d'une connexion à une base <strong>de</strong> données particulière doivent<br />
utiliser la même zone SQLCA que celle employée pour établir la connexion.<br />
Verrouillage d’enregistrement<br />
Les opérations effectuées sur plusieurs connexions sont susceptibles d'être<br />
soumises aux mécanismes <strong>de</strong> verrouillage d'enregistrement normaux et<br />
risquent <strong>de</strong> se bloquer mutuellement, voire d'entraîner un interblocage.<br />
Pour plus d'informations sur le verrouillage, reportez-vous au chapitre<br />
"Transactions et niveaux d'isolement", page 93 du document ASA <strong>Gui<strong>de</strong></strong><br />
<strong>de</strong> l’utilisateur SQL.
Lecture <strong>de</strong> données<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Dans Embed<strong>de</strong>d SQL, la lecture <strong>de</strong> données s'effectue via l'instruction<br />
SELECT. Deux cas peuvent se présenter :<br />
♦ L’instruction SELECT renvoie au plus une ligne Utilisez une clause<br />
INTO pour affecter les valeurs renvoyées directement aux variables<br />
hôte.<br />
$ Pour plus d'informations, reportez-vous à la section "Instruction<br />
SELECT qui renvoie une ligne au plus", page 211.<br />
♦ L’instruction SELECT renvoie plusieurs lignes Utilisez les curseurs<br />
pour gérer les lignes du jeu <strong>de</strong> résultats.<br />
$ Pour plus d'informations, reportez-vous à la section "Utilisation <strong>de</strong><br />
curseurs dans Embed<strong>de</strong>d SQL", page 212.<br />
$ Les types <strong>de</strong> données LONG VARCHAR et LONG BINARY sont<br />
gérés différemment <strong>de</strong>s autres types <strong>de</strong> données. Pour plus d'informations,<br />
reportez-vous à la section "Récupération <strong>de</strong> données <strong>de</strong> type LONG",<br />
page 236.<br />
Instruction SELECT qui renvoie une ligne au plus<br />
Exemple<br />
Une requête <strong>de</strong> ligne unique n'extrait pas plus d'une ligne <strong>de</strong> la base <strong>de</strong><br />
données. L'instruction SELECT d'une requête <strong>de</strong> ligne unique comporte une<br />
clause INTO, entre la liste <strong>de</strong> sélection et la clause FROM. La clause INTO<br />
contient une liste <strong>de</strong> variables hôte <strong>de</strong>stinées à recevoir la valeur <strong>de</strong> chaque<br />
élément <strong>de</strong> la liste <strong>de</strong> sélection. Le nombre <strong>de</strong> variables hôte doit être<br />
i<strong>de</strong>ntique au nombre d'éléments <strong>de</strong> la liste <strong>de</strong> sélection. Les variables hôte<br />
peuvent être accompagnées <strong>de</strong> variables indicateur afin d'indiquer les<br />
résultats NULL.<br />
Lors <strong>de</strong> l'exécution <strong>de</strong> l'instruction SELECT, le serveur <strong>de</strong> base <strong>de</strong> données<br />
récupère les résultats et les place dans les variables hôte. Si le résultat <strong>de</strong> la<br />
requête contient plusieurs lignes, le serveur renvoie une erreur.<br />
Si la requête n'aboutit pas à la sélection d'une ligne, l'avertissement La ligne<br />
est introuvable est renvoyé. Les erreurs et les avertissements sont renvoyés<br />
dans la structure SQLCA, comme décrit dans la section "Zone <strong>de</strong><br />
communication SQL (SQLCA)", page 205.<br />
Par exemple, l'extrait <strong>de</strong> co<strong>de</strong> suivant renvoie 1 si une ligne <strong>de</strong> la table<br />
"employee" est lue, 0 si aucune ligne n'est lue et –1 si une erreur se produit.<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
long emp_id;<br />
211
Lecture <strong>de</strong> données<br />
212<br />
char name[41];<br />
char sex;<br />
char birthdate[15];<br />
short int ind_birthdate;<br />
EXEC SQL END DECLARE SECTION;<br />
. . .<br />
int find_employee( long employee )<br />
{<br />
emp_id = employee;<br />
EXEC SQL SELECT emp_fname ||<br />
’ ’ || emp_lname, sex, birth_date<br />
INTO :name, :sex,<br />
:birthdate:ind_birthdate<br />
FROM "DBA".employee<br />
WHERE emp_id = :emp_id;<br />
if( SQLCODE == SQLE_NOTFOUND ) {<br />
return( 0 ); /* employé introuvable */<br />
} else if( SQLCODE < 0 ) {<br />
return( -1 ); /* erreur */<br />
} else {<br />
return( 1 ); /* employé trouvé */<br />
}<br />
}<br />
Utilisation <strong>de</strong> curseurs dans Embed<strong>de</strong>d SQL<br />
Un curseur permet d'extraire les lignes du jeu <strong>de</strong> résultats d'une requête, qui<br />
comporte plusieurs lignes. Un curseur est un <strong>de</strong>scripteur ou un i<strong>de</strong>ntificateur<br />
pour la requête SQL, et une position dans le jeu <strong>de</strong> résultats.<br />
$ Pour plus d'informations sur les curseurs, reportez-vous à la section<br />
"Utilisation <strong>de</strong>s curseurs", page 20.<br />
v Pour gérer un curseur dans Embed<strong>de</strong>d SQL :<br />
1 Déclarez un curseur pour une instruction SELECT donnée à l'ai<strong>de</strong> <strong>de</strong><br />
l'instruction DECLARE.<br />
2 Ouvrez le curseur à l'ai<strong>de</strong> <strong>de</strong> l'instruction OPEN.<br />
3 Récupérez une par une les lignes du curseur à l'ai<strong>de</strong> <strong>de</strong> l'instruction<br />
FETCH.<br />
4 Continuez l'extraction <strong>de</strong>s lignes jusqu'à ce que l'avertissement La ligne<br />
est introuvable soit renvoyé.<br />
Les erreurs et les avertissements sont renvoyés dans la structure<br />
SQLCA, décrite à la section "Zone <strong>de</strong> communication SQL (SQLCA)",<br />
page 205.
Positionnement du<br />
curseur<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
5 Fermez le curseur à l'ai<strong>de</strong> <strong>de</strong> l'instruction CLOSE.<br />
Par défaut, les curseurs sont automatiquement refermés à la fin d'une<br />
transaction (lors du COMMIT ou du ROLLBACK). Les curseurs ouverts<br />
avec une clause WITH HOLD restent ouverts pour les transactions suivantes,<br />
jusqu'à ce qu'ils soient explicitement refermés.<br />
Voici un exemple simple d'utilisation d'un curseur :<br />
void print_employees( void )<br />
{<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
char name[50];<br />
char sex;<br />
char birthdate[15];<br />
short int ind_birthdate;<br />
EXEC SQL END DECLARE SECTION;<br />
EXEC SQL DECLARE C1 CURSOR FOR<br />
SELECT emp_fname || ’ ’ || emp_lname,<br />
sex, birth_date<br />
FROM "DBA".employee;<br />
EXEC SQL OPEN C1;<br />
for( ;; ) {<br />
EXEC SQL FETCH C1 INTO :name, :sex,<br />
:birthdate:ind_birthdate;<br />
if( SQLCODE == SQLE_NOTFOUND ) {<br />
break;<br />
} else if( SQLCODE < 0 ) {<br />
break;<br />
}<br />
if( ind_birthdate < 0 ) {<br />
strcpy( birthdate, "UNKNOWN" );<br />
}<br />
printf( "Nom : %s Sexe : %c Date <strong>de</strong> naissance :<br />
%s.n",name, sex, birthdate );<br />
}<br />
EXEC SQL CLOSE C1;<br />
}<br />
$ Des exemples complets d'utilisation <strong>de</strong>s curseurs sont fournis aux<br />
sections "Exemple <strong>de</strong> curseur statique", page 189 et "Exemple <strong>de</strong> curseur<br />
dynamique", page 189.<br />
Un curseur peut occuper l'une <strong>de</strong>s trois positions suivantes :<br />
♦ sur une ligne quelconque,<br />
♦ avant la première ligne,<br />
♦ après la <strong>de</strong>rnière ligne.<br />
213
Lecture <strong>de</strong> données<br />
214<br />
Lors <strong>de</strong> son ouverture, un curseur est placé avant la première ligne. La<br />
comman<strong>de</strong> FETCH permet <strong>de</strong> modifier cette position (reportez-vous à la<br />
section "Instruction FETCH [ESQL] [SP]", page 446 du document ASA<br />
Manuel <strong>de</strong> référence SQL). Il peut occuper une position absolue à partir du<br />
début ou <strong>de</strong> la fin <strong>de</strong>s résultats <strong>de</strong> la requête. Il peut aussi être déplacé<br />
relativement à sa position courante.<br />
Il existe une version positionnée <strong>de</strong>s instructions UPDATE et DELETE, qui<br />
peut servir à mettre à jour ou à supprimer la ligne à la position courante du<br />
curseur. Si le curseur est positionné avant la première ligne ou après la<br />
<strong>de</strong>rnière ligne, l'erreur Aucune ligne <strong>de</strong> curseur n’est actuellement<br />
sélectionnée est renvoyée.<br />
L'instruction PUT permet d'insérer une ligne dans un curseur.
Problèmes liés au<br />
positionnement du<br />
curseur<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Les insertions et certaines mises à jour apportées aux curseurs DYNAMIC<br />
SCROLL (à défilement dynamique) peuvent engendrer <strong>de</strong>s problèmes <strong>de</strong><br />
positionnement. Le serveur ne place les lignes insérées dans un curseur à une<br />
position prévisible que si l'instruction SELECT comporte une clause<br />
ORDER BY. Dans certains cas, la ligne insérée n'apparaît pas avant que le<br />
curseur soit fermé puis rouvert.<br />
Avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, ce problème survient si une table<br />
temporaire a dû être créée pour ouvrir le curseur.<br />
$ Pour plus d'informations, reportez-vous à la section "Utilisation <strong>de</strong><br />
tables <strong>de</strong> travail dans le traitement <strong>de</strong>s requêtes", page 170 du document ASA<br />
<strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL.<br />
L'instruction UPDATE peut provoquer le déplacement d'une ligne dans le<br />
curseur. Cela se produit si le curseur inclut une clause ORDER BY qui<br />
utilise un in<strong>de</strong>x existant (aucune table temporaire n'est créée).<br />
Extraction simultanée <strong>de</strong> plusieurs lignes<br />
Il est possible <strong>de</strong> modifier l’instruction FETCH afin d’extraire plusieurs<br />
lignes simultanément, ce qui peut améliorer les performances. On parle alors<br />
d'extraction étendue ou <strong>de</strong> lecture <strong>de</strong> tableau.<br />
$ <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> prend également en charge <strong>de</strong>s instructions<br />
PUT et INSERT étendues. Pour plus d'informations sur ces instructions,<br />
reportez-vous aux sections "Instruction PUT [ESQL]", page 523 du<br />
document ASA Manuel <strong>de</strong> référence SQL et "Instruction EXECUTE<br />
[ESQL]", page 437 du document ASA Manuel <strong>de</strong> référence SQL.<br />
Pour effectuer <strong>de</strong>s extractions étendues en Embed<strong>de</strong>d SQL, vous <strong>de</strong>vez<br />
inclure l'instruction FETCH dans votre co<strong>de</strong> comme suit :<br />
EXEC SQL FETCH . . . ARRAY nnn<br />
où ARRAY nnn est le <strong>de</strong>rnier élément <strong>de</strong> l'instruction. Le nombre<br />
d'extractions nnn peut être une variable hôte. Le nombre <strong>de</strong> variables <strong>de</strong> la<br />
SQLDA doit correspondre au produit <strong>de</strong> nnn et du nombre <strong>de</strong> colonnes par<br />
ligne. La première ligne est placée dans les variables SQLDA 0 (zéro) à<br />
(colonnes par ligne)-1, etc.<br />
Le type <strong>de</strong> chaque colonne doit être i<strong>de</strong>ntique dans chaque ligne <strong>de</strong><br />
la SQLDA. Dans le cas contraire, une erreur SQLDA_INCONSISTENT est<br />
renvoyée.<br />
215
Lecture <strong>de</strong> données<br />
Exemple<br />
216<br />
Le serveur renvoie dans SQLCOUNT le nombre d’enregistrements extraits,<br />
qui est toujours supérieur à zéro, sauf s'il y a <strong>de</strong>s erreurs ou <strong>de</strong>s<br />
avertissements. Dans le cas d'une extraction étendue, une valeur<br />
SQLCOUNT égale à 1 sans condition d'erreur indique qu'une ligne correcte<br />
a été extraite.<br />
L'exemple suivant illustre l'utilisation d'extractions étendues. Ce co<strong>de</strong> figure<br />
dans le fichier samples\ASA\esqlwi<strong>de</strong>fetch\wi<strong>de</strong>fetch.sqc du répertoire<br />
SQL <strong>Anywhere</strong>.
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> "sql<strong>de</strong>f.h"<br />
EXEC SQL INCLUDE SQLCA;<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
EXEC SQL WHENEVER SQLERROR { PrintSQLError();<br />
goto err; };<br />
static void PrintSQLError()<br />
/*************************/<br />
{<br />
char buffer[200];<br />
}<br />
printf( "erreur SQL %d -- %s\n",<br />
SQLCODE,<br />
sqlerror_message( &sqlca,<br />
buffer,<br />
sizeof( buffer ) ) );<br />
static SQLDA * PrepareSQLDA(<br />
a_sql_statement_number stat0,<br />
unsigned width,<br />
unsigned *cols_per_row )<br />
/*********************************************/<br />
/* Allouez une SQLDA pour récupérer <strong>de</strong>s lignes à partir<br />
<strong>de</strong> l'instruction i<strong>de</strong>ntifiée par "stat0". "width"<br />
les lignes sont extraites à chaque requête FETCH.<br />
Le nombre <strong>de</strong> colonnes par ligne est affecté à<br />
"cols_per_row". */<br />
{<br />
int num_cols;<br />
unsigned row, col, offset;<br />
SQLDA * sqlda;<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
a_sql_statement_number stat;<br />
EXEC SQL END DECLARE SECTION;<br />
stat = stat0;<br />
sqlda = alloc_sqlda( 100 );<br />
if( sqlda == NULL ) return( NULL );<br />
EXEC SQL DESCRIBE :stat INTO sqlda;<br />
*cols_per_row = num_cols = sqlda->sqld;<br />
if( num_cols * width > sqlda->sqln ) {<br />
free_sqlda( sqlda );<br />
sqlda = alloc_sqlda( num_cols * width );<br />
if( sqlda == NULL ) return( NULL );<br />
EXEC SQL DESCRIBE :stat INTO sqlda;<br />
}<br />
// copie dans les lignes (étendues) suivantes<br />
// la première ligne contenue dans SQLDA<br />
217
Lecture <strong>de</strong> données<br />
218<br />
// définie par <strong>de</strong>scribe<br />
sqlda->sqld = num_cols * width;<br />
offset = num_cols;<br />
for( row = 1; row < width; row++ ) {<br />
for( col = 0;<br />
col < num_cols;<br />
col++, offset++ ) {<br />
sqlda->sqlvar[offset].sqltype =<br />
sqlda->sqlvar[col].sqltype;<br />
sqlda->sqlvar[offset].sqllen =<br />
sqlda->sqlvar[col].sqllen;<br />
// facultatif : copie le nom <strong>de</strong>s colonnes<br />
décrites<br />
memcpy( &sqlda->sqlvar[offset].sqlname,<br />
&sqlda->sqlvar[col].sqlname,<br />
sizeof( sqlda->sqlvar[0].sqlname )<br />
);<br />
}<br />
}<br />
fill_s_sqlda( sqlda, 40 );<br />
return( sqlda );<br />
err:<br />
return( NULL );<br />
}<br />
static void PrintFetchedRows( SQLDA * sqlda,<br />
unsigned cols_per_row )<br />
/******************************************/<br />
/* Imprime les lignes déjà extraites <strong>de</strong> manière étendue<br />
dans SQLDA */<br />
{<br />
long rows_fetched;<br />
int row, col, offset;<br />
}<br />
if( SQLCOUNT == 0 ) {<br />
rows_fetched = 1;<br />
} else {<br />
rows_fetched = SQLCOUNT;<br />
}<br />
printf( "%d lignes extraites :\n", rows_fetched );<br />
for( row = 0; row < rows_fetched; row++ ) {<br />
for( col = 0; col < cols_per_row; col++ ) {<br />
offset = row * cols_per_row + col;<br />
printf( " \"%s\"",<br />
(char *)sqlda->sqlvar[offset]<br />
.sqldata );<br />
}<br />
printf( "\n" );<br />
}
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
static int DoQuery( char * query_str0,<br />
unsigned fetch_width0 )<br />
/*****************************************/<br />
/* Instruction select "query_str0" pour extraction<br />
/* étendue avec une largeur <strong>de</strong> "fetch_width0"<br />
* lignes " */<br />
{<br />
SQLDA * sqlda;<br />
unsigned cols_per_row;<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
a_sql_statement_number stat;<br />
char * query_str;<br />
unsigned fetch_width;<br />
EXEC SQL END DECLARE SECTION;<br />
query_str = query_str0;<br />
fetch_width = fetch_width0;<br />
EXEC SQL PREPARE :stat FROM :query_str;<br />
EXEC SQL DECLARE QCURSOR CURSOR FOR :stat<br />
FOR READ ONLY;<br />
EXEC SQL OPEN QCURSOR;<br />
sqlda = PrepareSQLDA( stat,<br />
fetch_width,<br />
&cols_per_row );<br />
if( sqlda == NULL ) {<br />
printf( "Erreur d'allocation SQLDA\n" );<br />
return( SQLE_NO_MEMORY );<br />
}<br />
for( ;; ) {<br />
EXEC SQL FETCH QCURSOR INTO DESCRIPTOR sqlda<br />
ARRAY :fetch_width;<br />
if( SQLCODE != SQLE_NOERROR ) break;<br />
PrintFetchedRows( sqlda, cols_per_row );<br />
}<br />
EXEC SQL CLOSE QCURSOR;<br />
EXEC SQL DROP STATEMENT :stat;<br />
free_filled_sqlda( sqlda );<br />
err:<br />
return( SQLCODE );<br />
}<br />
void main( int argc, char *argv[] )<br />
/*********************************/<br />
/* Le premier argument facultatif est une instruction<br />
/* select,<br />
* le second argument est l'étendue <strong>de</strong> l'extraction*/<br />
{<br />
char *query_str =<br />
"select emp_fname, emp_lname from employee";<br />
unsigned fetch_width = 10;<br />
219
Lecture <strong>de</strong> données<br />
Remarques sur<br />
l’utilisation <strong>de</strong>s<br />
extractions<br />
étendues<br />
220<br />
if( argc > 1 ) {<br />
query_str = argv[1];<br />
if( argc > 2 ) {<br />
fetch_width = atoi( argv[2] );<br />
if( fetch_width < 2 ) {<br />
fetch_width = 2;<br />
}<br />
}<br />
}<br />
db_init( &sqlca );<br />
EXEC SQL CONNECT "dba" IDENTIFIED BY "sql";<br />
DoQuery( query_str, fetch_width );<br />
EXEC SQL DISCONNECT;<br />
err:<br />
db_fini( &sqlca );<br />
}<br />
♦ Dans la fonction PrepareSQLDA, la mémoire SQLDA est allouée au<br />
travers <strong>de</strong> la fonction alloc_sqlda. Cela permet <strong>de</strong> réserver <strong>de</strong> l'espace<br />
pour les variables indicateur sans utiliser la fonction alloc_sqlda_noind.<br />
♦ Lorsque le nombre <strong>de</strong> lignes extraites est inférieur au nombre <strong>de</strong>mandé<br />
mais pas égal à zéro (à la fin du curseur, par exemple), les éléments<br />
SQLDA correspondant aux lignes non extraites sont renvoyés en tant<br />
que valeurs NULL dans la valeur indicateur. En l'absence <strong>de</strong> variable<br />
indicateur, une erreur est générée (SQLE_NO_INDICATOR : pas <strong>de</strong><br />
variable indicateur pour résultat NULL).<br />
♦ En cas <strong>de</strong> mise à jour d'une ligne qui est extraite (ce qui génère un<br />
avertissement SQLE_ROW_UPDATED_WARNING) la recherche<br />
s'arrête sur la ligne qui a provoqué l'avertissement. Les valeurs <strong>de</strong> toutes<br />
les lignes traitées jusqu'à cette <strong>de</strong>rnière (ligne ayant provoqué<br />
l'avertissement comprise) sont renvoyées. SQLCOUNT contient le<br />
nombre <strong>de</strong> lignes extraites, y compris celle à l'origine <strong>de</strong> l'avertissement.<br />
Tous les éléments SQLDA restants sont marqués comme valeurs NULL.<br />
♦ En cas <strong>de</strong> suppression ou <strong>de</strong> verrouillage d'une ligne qui est extraite (ce<br />
qui provoque la génération d'une erreur SQLE_NO_CURRENT_ROW<br />
ou SQLE_LOCKED) SQLCOUNT contient alors le nombre <strong>de</strong> lignes<br />
lues avant l'erreur. La ligne à l'origine <strong>de</strong> l'erreur n'est pas incluse. La<br />
zone SQLDA ne contient pas les valeurs <strong>de</strong>s lignes, les valeurs SQLDA<br />
n'étant pas renvoyées en cas d'erreur. La valeur SQLCOUNT peut servir,<br />
si nécessaire, à repositionner le curseur <strong>de</strong> façon qu'il puisse lire les<br />
lignes.
SQL statique et SQL dynamique<br />
Instructions SQL statiques<br />
Instructions SQL dynamiques<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Il existe <strong>de</strong>ux façons d'imbriquer <strong>de</strong>s instructions SQL dans un programme<br />
en langage C :<br />
♦ Instructions statiques<br />
♦ Instructions dynamiques<br />
Jusqu'à présent, nous avons traité <strong>de</strong>s instructions SQL statiques. La présente<br />
section fournit une comparaison entre les instructions SQL statiques et<br />
dynamiques.<br />
Toutes les instructions <strong>de</strong> manipulation et <strong>de</strong> définition <strong>de</strong> données SQL<br />
standard peuvent être imbriquées dans un programme en langage C ; pour ce<br />
faire, elles doivent être précédées d'EXEC SQL et se terminer par un pointvirgule<br />
(;). Ces instructions sont dites statiques.<br />
Les instructions statiques peuvent contenir <strong>de</strong>s références à <strong>de</strong>s variables<br />
hôte, comme indiqué dans la section "Utilisation <strong>de</strong>s variables hôte",<br />
page 196. Tous les exemples proposés jusqu'ici utilisaient <strong>de</strong>s instructions<br />
Embed<strong>de</strong>d SQL statiques.<br />
Les variables hôte peuvent remplacer uniquement <strong>de</strong>s constantes <strong>de</strong> type<br />
chaîne ou <strong>de</strong>s constantes numériques. Elles ne peuvent se substituer à un<br />
nom <strong>de</strong> colonne ou <strong>de</strong> table ; <strong>de</strong> telles opérations requièrent <strong>de</strong>s instructions<br />
dynamiques.<br />
En langage C, les chaînes sont stockées dans <strong>de</strong>s tableaux <strong>de</strong> caractères. Les<br />
instructions dynamiques sont créées dans <strong>de</strong>s chaînes en langage C. Elles<br />
peuvent ensuite être exécutées à l'ai<strong>de</strong> <strong>de</strong>s instructions PREPARE et<br />
EXECUTE. Ces instructions SQL ne peuvent pas référencer <strong>de</strong>s variables<br />
hôte <strong>de</strong> la même façon que les instructions statiques, les variables C n'étant<br />
pas accessibles par leur nom lorsque le programme est en cours d'exécution.<br />
221
SQL statique et SQL dynamique<br />
Exemple<br />
222<br />
Pour transférer les informations entre les instructions et les variables en<br />
langage C, on utilise une structure <strong>de</strong> données appelée Zone <strong>de</strong>scripteur<br />
SQL (SQLDA). Elle peut être définie par le préprocesseur SQL si vous<br />
spécifiez une liste <strong>de</strong> variables hôte dans la clause USING <strong>de</strong> la comman<strong>de</strong><br />
EXECUTE. Ces variables correspon<strong>de</strong>nt, <strong>de</strong> par leur position, à <strong>de</strong>s marques<br />
<strong>de</strong> réservation, situées dans la position appropriée <strong>de</strong> la chaîne <strong>de</strong> comman<strong>de</strong><br />
préparée.<br />
$ Pour plus d'informations sur SQLDA, reportez-vous à la section "Zone<br />
<strong>de</strong>scripteur SQL (SQLDA)", page 226.<br />
Une marque <strong>de</strong> réservation est incluse dans l'instruction pour indiquer où<br />
l'on doit accé<strong>de</strong>r aux variables hôte. Une marque <strong>de</strong> réservation est un point<br />
d'interrogation (?) ou une référence <strong>de</strong> variable hôte comme dans une<br />
instruction statique (c'est-à-dire un nom <strong>de</strong> variable hôte précédé d'un signe<br />
<strong>de</strong>ux-points). Dans ce <strong>de</strong>rnier cas, le nom <strong>de</strong> variable hôte utilisé dans le<br />
texte <strong>de</strong> l'instruction sert uniquement <strong>de</strong> marque <strong>de</strong> réservation et indique<br />
une référence à la zone <strong>de</strong>scripteur SQL.<br />
Une variable hôte permettant <strong>de</strong> transmettre <strong>de</strong>s informations à la base <strong>de</strong><br />
données est appelée variable <strong>de</strong> liaison.<br />
Par exemple :<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
char comm[200];<br />
char address[30];<br />
char city[20];<br />
short int cityind;<br />
long empnum;<br />
EXEC SQL END DECLARE SECTION;<br />
. . .<br />
sprintf( comm, "update %s set address = :?,<br />
city = :?"<br />
" where employee_number = :?",<br />
tablename );<br />
EXEC SQL PREPARE S1 FROM :comm;<br />
EXEC SQL EXECUTE S1 USING :address, :city:cityind,<br />
:empnum;<br />
Cette métho<strong>de</strong> requiert <strong>de</strong> la part du programmeur qu'il sache combien <strong>de</strong><br />
variables hôte sont incluses dans l'instruction. Or, ce n'est généralement pas<br />
le cas. Vous pouvez donc définir votre propre structure SQLDA et la<br />
spécifier dans la clause USING <strong>de</strong> la comman<strong>de</strong> EXECUTE.<br />
L'instruction DESCRIBE BIND VARIABLES renvoie le nom <strong>de</strong>s variables<br />
<strong>de</strong> liaison trouvées dans une instruction préparée. Un programme en<br />
langage C gère ainsi plus facilement les variables hôte. La métho<strong>de</strong> générale<br />
est la suivante :<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
char comm[200];
Contenu <strong>de</strong> la<br />
zone SQLDA<br />
Variables<br />
indicateurs et<br />
valeur NULL<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
EXEC SQL END DECLARE SECTION;<br />
. . .<br />
sprintf( comm, "update %s set address = :address,<br />
city = :city"<br />
" where employee_number = :empnum",<br />
tablename );<br />
EXEC SQL PREPARE S1 FROM :comm;<br />
/* Suppose qu'il n'existe pas plus <strong>de</strong> 10 variables hôte.<br />
Reportez-vous à l'exemple suivant si vous ne pouvez pas<br />
en limiter le nombre */<br />
sqlda = alloc_sqlda( 10 );<br />
EXEC SQL DESCRIBE BIND VARIABLES FOR S1 USING DESCRIPTOR<br />
sqlda;<br />
/* sqlda->sqld indique le nombre <strong>de</strong> variables hôte. */<br />
/* Renseigne les champs SQLDA_VARIABLE avec <strong>de</strong>s valeurs<br />
fondées sur<br />
les noms <strong>de</strong> champ <strong>de</strong> sqlda */<br />
. . .<br />
EXEC SQL EXECUTE S1 USING DESCRIPTOR sqlda;<br />
free_sqlda( sqlda );<br />
La zone SQLDA consiste en un tableau <strong>de</strong> <strong>de</strong>scripteurs <strong>de</strong> variables. Chaque<br />
<strong>de</strong>scripteur détaille les attributs <strong>de</strong> la variable C correspondante ou<br />
l'emplacement dans lequel la base <strong>de</strong> données enregistre les données (ou d'où<br />
elle les récupère), comme suit :<br />
♦ type <strong>de</strong> données<br />
♦ longueur si type correspond à une chaîne,<br />
♦ précision et échelle si type est numérique,<br />
♦ adresse mémoire,<br />
♦ variable indicateur.<br />
$ Pour obtenir une <strong>de</strong>scription exhaustive <strong>de</strong> la structure SQLDA,<br />
reportez-vous à la section "Zone <strong>de</strong>scripteur SQL (SQLDA)", page 226.<br />
La variable indicateur permet <strong>de</strong> transmettre une valeur NULL à la base <strong>de</strong><br />
données ou <strong>de</strong> récupérer une valeur NULL <strong>de</strong> cette <strong>de</strong>rnière. Elle est<br />
également utilisée par le serveur <strong>de</strong> base <strong>de</strong> données pour signaler les<br />
conditions <strong>de</strong> troncature rencontrées lors d'une opération <strong>de</strong> base <strong>de</strong> données.<br />
La variable indicateur prend une valeur positive lorsque l'espace <strong>de</strong>stiné à<br />
recevoir une valeur <strong>de</strong> la base <strong>de</strong> données est insuffisant.<br />
$ Pour plus d'informations, reportez-vous à la section "Variables<br />
indicateur", page 201.<br />
223
SQL statique et SQL dynamique<br />
Instruction SELECT dynamique<br />
224<br />
Une instruction SELECT qui ne renvoie qu'une seule ligne peut être préparée<br />
dynamiquement et suivie d'une instruction EXECUTE avec une clause INTO<br />
qui extrait un résultat uniligne. En revanche, les instructions SELECT qui<br />
renvoient plusieurs lignes sont gérées à l'ai<strong>de</strong> <strong>de</strong> curseurs dynamiques.<br />
Avec les curseurs dynamiques, les résultats sont placés dans une liste <strong>de</strong><br />
variables hôte ou dans une SQLDA spécifiée dans l'instruction FETCH<br />
(FETCH INTO ou FETCH USING DESCRIPTOR). Le nombre d'éléments<br />
<strong>de</strong> la liste <strong>de</strong> sélection n'étant généralement pas connu du programmeur, la<br />
métho<strong>de</strong> utilisant une SQLDA est la plus courante. L'instruction<br />
DESCRIBE SELECT LIST définit une SQLDA avec les types <strong>de</strong>s éléments<br />
<strong>de</strong> la liste <strong>de</strong> sélection. De l'espace est alors alloué pour les valeurs via la<br />
fonction fill_sqlda() et les informations sont extraites à l'ai<strong>de</strong> <strong>de</strong> l'instruction<br />
FETCH USING DESCRIPTOR.<br />
Le scénario classique est le suivant :<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
char comm[200];<br />
EXEC SQL END DECLARE SECTION;<br />
int actual_size;<br />
SQLDA * sqlda;<br />
. . .<br />
sprintf( comm, "select * from %s", table_name );<br />
EXEC SQL PREPARE S1 FROM :comm;<br />
/* Le résultat est initialement estimé à 10 colonnes.<br />
S'il est faux,<br />
il est corrigé après la première instruction<br />
DESCRIBE par l'allocation d'une nouvelle SQLDA et la<br />
réexécution <strong>de</strong> DESCRIBE . */<br />
sqlda = alloc_sqlda( 10 );<br />
EXEC SQL DESCRIBE SELECT LIST FOR S1 USING DESCRIPTOR<br />
sqlda;<br />
if( sqlda->sqld > sqlda->sqln ) {<br />
actual_size = sqlda->sqld;<br />
free_sqlda( sqlda );<br />
sqlda = alloc_sqlda( actual_size );<br />
EXEC SQL DESCRIBE SELECT LIST FOR S1<br />
USING DESCRIPTOR sqlda;<br />
}<br />
fill_sqlda( sqlda );<br />
EXEC SQL DECLARE C1 CURSOR FOR S1;<br />
EXEC SQL OPEN C1;<br />
EXEC SQL WHENEVER NOTFOUND {break};<br />
for( ;; ) {<br />
EXEC SQL FETCH C1 USING DESCRIPTOR sqlda;<br />
/* traite les données */<br />
}
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
EXEC SQL CLOSE C1;<br />
EXEC SQL DROP STATEMENT S1;<br />
Suppression <strong>de</strong>s instructions après utilisation<br />
Afin d'éviter toute occupation inutile <strong>de</strong>s ressources, assurez-vous que les<br />
instructions sont supprimées après leur utilisation.<br />
$ Pour plus d'informations sur l'utilisation <strong>de</strong>s curseurs dans une<br />
instruction SELECT dynamique, reportez-vous à la section "Exemple <strong>de</strong><br />
curseur dynamique", page 189.<br />
$ Pour plus d'informations sur les fonctions ci-<strong>de</strong>ssus, reportez-vous à la<br />
section "Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque", page 251.<br />
225
Zone <strong>de</strong>scripteur SQL (SQLDA)<br />
Zone <strong>de</strong>scripteur SQL (SQLDA)<br />
Le fichier d'en-tête SQLDA<br />
226<br />
La zone SQLDA (zone <strong>de</strong>scripteur SQL) est une structure d'interface utilisée<br />
pour les instructions SQL dynamiques. Cette structure transmet, vers et<br />
<strong>de</strong>puis la base <strong>de</strong> données, <strong>de</strong>s informations concernant les variables hôte et<br />
le résultat <strong>de</strong>s instructions SELECT. La zone SQLDA est définie dans le<br />
fichier d'en-tête sqlda.h.<br />
$ Vous pouvez utiliser certaines fonctions <strong>de</strong> la bibliothèque d'interface<br />
ou <strong>de</strong> la DLL <strong>de</strong> la base <strong>de</strong> données pour gérer les zones SQLDA. Pour en<br />
obtenir la <strong>de</strong>scription, reportez-vous à la section "Références <strong>de</strong>s fonctions<br />
<strong>de</strong> bibliothèque", page 251.<br />
Lorsque <strong>de</strong>s instructions SQL statiques appellent <strong>de</strong>s variables hôte, le<br />
préprocesseur définit une zone SQLDA pour ces variables. Cette zone<br />
SQLDA est utilisée ensuite pour les transmissions vers et <strong>de</strong>puis le serveur<br />
<strong>de</strong> base <strong>de</strong> données.<br />
Le contenu du fichier sqlda.h se présente comme suit :<br />
#ifn<strong>de</strong>f _SQLDA_H_INCLUDED<br />
#<strong>de</strong>fine _SQLDA_H_INCLUDED<br />
#<strong>de</strong>fine II_SQLDA<br />
#inclu<strong>de</strong> "sqlca.h"<br />
#if <strong>de</strong>fined( _SQL_PACK_STRUCTURES )<br />
#inclu<strong>de</strong> "pshpk1.h"<br />
#endif<br />
#<strong>de</strong>fine SQL_MAX_NAME_LEN 30<br />
#<strong>de</strong>fine _sqldafar _sqlfar<br />
type<strong>de</strong>f short int a_sql_type;<br />
struct sqlname {<br />
short int length; /* longueur <strong>de</strong>s données caractère /<br />
char data[ SQL_MAX_NAME_LEN ]; /* données */<br />
};<br />
struct sqlvar { /* tableau <strong>de</strong> <strong>de</strong>scripteurs <strong>de</strong> variable /<br />
short int sqltype; /* type <strong>de</strong> variable hôte /<br />
short int sqllen; /* longueur <strong>de</strong> variable hôte */<br />
void _sqldafar sqldata; /* adresse <strong>de</strong> la variable */<br />
short int _sqldafar sqlind; /* pointeur indicateur variable */<br />
struct sqlname sqlname;<br />
};
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
struct sqlda{<br />
unsigned char sqldaid[8]; /* eye catcher "SQLDA"*/<br />
a_SQL_int32 sqldabc; /* longueur <strong>de</strong> la structure sqlda*/<br />
short int sqln; /* taille du <strong>de</strong>scripteur en nombre d'entrées /<br />
short int sqld; / nombre <strong>de</strong> variables i<strong>de</strong>ntifiées par DESCRIBE*/<br />
struct sqlvar sqlvar[1]; /* tableau <strong>de</strong>s <strong>de</strong>scripteurs <strong>de</strong><br />
variables */<br />
};<br />
#<strong>de</strong>fine SCALE(sqllen) ((sqllen)/256)<br />
#<strong>de</strong>fine PRECISION(sqllen) ((sqllen)&0xff)<br />
#<strong>de</strong>fine SET_PRECISION_SCALE(sqllen,precision,scale) \<br />
sqllen = (scale)*256 + (precision)<br />
#<strong>de</strong>fine DECIMALSTORAGE(sqllen) (PRECISION(sqllen)/2 + 1)<br />
type<strong>de</strong>f struct sqlda SQLDA;<br />
type<strong>de</strong>f struct sqlvar SQLVAR, SQLDA_VARIABLE;<br />
type<strong>de</strong>f struct sqlname SQLNAME, SQLDA_NAME;<br />
#ifn<strong>de</strong>f SQLDASIZE<br />
#<strong>de</strong>fine SQLDASIZE(n) ( sizeof( struct sqlda ) + \<br />
(n-1) * sizeof( struct sqlvar) )<br />
#endif<br />
#if <strong>de</strong>fined( _SQL_PACK_STRUCTURES )<br />
#inclu<strong>de</strong> "poppk.h"<br />
#endif<br />
#endif<br />
Champs SQLDA<br />
Le tableau suivant décrit les champs <strong>de</strong> la zone SQLDA :<br />
Champ Description<br />
sqldaid Champ <strong>de</strong> type caractère codé sur 8 octets contenant la chaîne<br />
SQLDA, qui i<strong>de</strong>ntifie la structure SQLDA. Ce champ facilite le<br />
débogage lors <strong>de</strong> l'analyse du contenu <strong>de</strong> la mémoire.<br />
sqldabc Entier long contenant la longueur <strong>de</strong> la structure SQLDA.<br />
sqln Nombre <strong>de</strong> <strong>de</strong>scripteurs <strong>de</strong> variable du tableau sqlvar.<br />
sqld Nombre <strong>de</strong> <strong>de</strong>scripteurs <strong>de</strong> variable corrects (contenant <strong>de</strong>s<br />
informations <strong>de</strong> <strong>de</strong>scription d'une variable hôte). Ce champ est<br />
défini par l'instruction DESCRIBE ou par le programmeur lorsque<br />
<strong>de</strong>s données sont fournies au serveur.<br />
sqlvar Tableau <strong>de</strong> <strong>de</strong>scripteurs <strong>de</strong> type struct sqlvar, décrivant chacun<br />
une variable hôte.<br />
227
Zone <strong>de</strong>scripteur SQL (SQLDA)<br />
Descriptions <strong>de</strong>s variables hôte <strong>de</strong> la zone SQLDA<br />
228<br />
Chacune <strong>de</strong>s structures sqlvar <strong>de</strong> la zone SQLDA décrit une variable hôte.<br />
Les champs <strong>de</strong> la structure sqlvar ont les significations suivantes :<br />
♦ sqltype Type <strong>de</strong> la variable décrite par le <strong>de</strong>scripteur (reportez-vous à la<br />
section "Types <strong>de</strong> données Embed<strong>de</strong>d SQL", page 192).<br />
Le bit <strong>de</strong> poids faible indique si les valeurs NULL sont admises. Les<br />
définitions <strong>de</strong>s types admis et <strong>de</strong>s constantes sont fournies dans le fichier<br />
d'en-tête sql<strong>de</strong>f.h.<br />
Ce champ est renseigné par l'instruction DESCRIBE. Vous pouvez le<br />
définir avec n'importe quel type lorsque vous fournissez ou récupérez<br />
<strong>de</strong>s données à partir du serveur <strong>de</strong> base <strong>de</strong> données. Le cas échéant, le<br />
type est automatiquement converti.<br />
♦ sqllen Longueur <strong>de</strong> la variable. La signification <strong>de</strong> la longueur dépend<br />
du type indiqué et <strong>de</strong> la façon dont la zone SQLDA est utilisée.<br />
Pour les variables <strong>de</strong> type DECIMAL, ce champ est divisé en <strong>de</strong>ux<br />
champs <strong>de</strong> 1 octet. L'octet <strong>de</strong> poids fort est la précision et l'octet <strong>de</strong> poids<br />
faible, l'échelle. Par précision, on entend le nombre total <strong>de</strong> chiffres. Par<br />
échelle, on entend le nombre <strong>de</strong> chiffres après la virgule.<br />
Pour les types <strong>de</strong> données LONG VARCHAR et LONG BINARY, le<br />
champ array_len <strong>de</strong>s structures <strong>de</strong> type <strong>de</strong> données<br />
DT_LONGBINARY et DT_LONGVARCHAR est utilisé à la place du<br />
champ sqllen.<br />
$ Pour plus d'informations sur le champ <strong>de</strong> longueur, reportez-vous à<br />
la section "Valeurs du champ sqllen <strong>de</strong> la zone SQLDA", page 229.<br />
♦ sqldata Pointeur <strong>de</strong> quatre octets sur la mémoire occupée par cette<br />
variable. Cette mémoire doit correspondre aux champs sqltype et sqllen.<br />
$ Pour plus d'informations sur les formats <strong>de</strong> stockage, reportez-vous<br />
à la section "Types <strong>de</strong> données Embed<strong>de</strong>d SQL", page 192.<br />
Pour les comman<strong>de</strong>s UPDATE et INSERT, cette variable n'est pas<br />
impliquée dans l'opération si le pointeur sqldata est un pointeur NULL.<br />
Pour la comman<strong>de</strong> FETCH, aucune donnée n'est renvoyée si le pointeur<br />
sqldata est un pointeur NULL. En d'autres termes, la colonne renvoyée<br />
par le pointeur sqldata est une colonne non liée.<br />
Si l’instruction DESCRIBE utilise un type LONG NAMES, ce champ<br />
contient alors le nom long <strong>de</strong> la colonne du jeu <strong>de</strong> résultats. Si, par<br />
ailleurs, l'instruction DESCRIBE est une instruction <strong>de</strong> type DESCRIBE<br />
USER TYPES, ce champ contient le nom long du type <strong>de</strong> données défini<br />
par l'utilisateur et non la colonne. S'il s'agit d'un type <strong>de</strong> base, le champ<br />
reste vi<strong>de</strong>.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ sqlind Pointeur sur la valeur indicateur. Une valeur indicateur est <strong>de</strong><br />
type short int. Une valeur indicateur négative indique une valeur<br />
NULL. Une valeur indicateur positive indique que la variable a été<br />
tronquée par une instruction FETCH ; elle contient la longueur <strong>de</strong>s<br />
données avant troncature. La valeur –2 indique une erreur <strong>de</strong> conversion<br />
si l'option <strong>de</strong> base <strong>de</strong> données CONVERSION_ERROR est définie à<br />
OFF.<br />
$ Pour plus d'informations, reportez-vous à la section "Variables<br />
indicateur", page 201.<br />
Si le pointeur sqlind est le pointeur NULL, aucune variable indicateur<br />
n'existe pour cette variable hôte.<br />
Le champ sqlind est également utilisé par l'instruction DESCRIBE pour<br />
indiquer les types <strong>de</strong> paramètre. S'il s'agit d'un type <strong>de</strong> données défini<br />
par l'utilisateur, ce champ a la valeur DT_HAS_USERTYPE_INFO.<br />
Dans ce cas, vous pouvez exécuter DESCRIBE USER TYPES pour<br />
obtenir <strong>de</strong>s informations sur les types <strong>de</strong> données définis par l'utilisateur.<br />
♦ sqlname Structure <strong>de</strong> type VARCHAR qui contient un buffer <strong>de</strong><br />
longueur et <strong>de</strong> caractère. Elle est renseignée par une instruction<br />
DESCRIBE et n'a pas d'autre utilisation. Ce champ n'a pas la même<br />
signification pour les <strong>de</strong>ux formats <strong>de</strong> l'instruction DESCRIBE :<br />
♦ SELECT LIST Le buffer <strong>de</strong> nom est complété avec l'en-tête <strong>de</strong><br />
colonne <strong>de</strong> l'élément correspondant dans la liste <strong>de</strong> sélection.<br />
♦ BIND VARIABLES Le buffer <strong>de</strong> nom est complété soit avec le nom<br />
<strong>de</strong> la variable hôte utilisée comme variable <strong>de</strong> liaison, soit avec le<br />
signe "?" si un marqueur <strong>de</strong> paramètre non nommé est utilisé.<br />
Dans une comman<strong>de</strong> DESCRIBE SELECT LIST, les variables<br />
indicateur présentes sont assorties d'un drapeau signalant si l'élément <strong>de</strong><br />
liste <strong>de</strong> sélection peut être ou non mis à jour. Vous trouverez plus<br />
d'informations sur cet indicateur dans le fichier d'en-tête sql<strong>de</strong>f.h.<br />
Si l'instruction DESCRIBE est <strong>de</strong> type DESCRIBE USER TYPES, ce<br />
champ contient le nom long du type <strong>de</strong> données défini par l'utilisateur et<br />
non la colonne. S'il s'agit d'un type <strong>de</strong> base, le champ reste vi<strong>de</strong>.<br />
Valeurs du champ sqllen <strong>de</strong> la zone SQLDA<br />
La longueur du champ sqllen <strong>de</strong> la structure sqlvar d'une zone SQLDA<br />
intervient dans trois types d'interaction avec le serveur <strong>de</strong> base <strong>de</strong> données :<br />
229
Zone <strong>de</strong>scripteur SQL (SQLDA)<br />
Description <strong>de</strong> valeurs<br />
230<br />
♦ Description <strong>de</strong> valeurs L’instruction DESCRIBE permet d’obtenir <strong>de</strong>s<br />
informations sur les variables hôte nécessaires pour stocker les données<br />
extraites <strong>de</strong> la base <strong>de</strong> données ou pour transmettre <strong>de</strong>s données à cette<br />
base.<br />
$ Reportez-vous à la section "Description <strong>de</strong> valeurs", page 230.<br />
♦ Extraction <strong>de</strong> valeurs Extraction <strong>de</strong> valeurs <strong>de</strong> la base <strong>de</strong> données.<br />
$ Reportez-vous à la section "Extraction <strong>de</strong> valeurs", page 233.<br />
♦ Envoi <strong>de</strong> valeurs Envoi d'informations à la base <strong>de</strong> données.<br />
$ Reportez-vous à la section "Envoi <strong>de</strong> valeurs", page 231.<br />
Cette section décrit ces interactions.<br />
Les tableaux ci-<strong>de</strong>ssous présentent ces interactions. Ces tableaux donnent la<br />
liste <strong>de</strong>s types <strong>de</strong> constante d'interface (types DT_) figurant dans le fichier<br />
d'en-tête sql<strong>de</strong>f.h. Ces constantes sont en général placées dans le champ<br />
SQLDA sqltype.<br />
$ Pour plus d'informations sur les valeurs du champ sqltype, reportezvous<br />
à la section "Types <strong>de</strong> données Embed<strong>de</strong>d SQL", page 192.<br />
Dans du SQL statique, une zone SQLDA est aussi utilisée, mais est générée<br />
et entièrement complétée par le préprocesseur SQL. Dans ce cas, les tableaux<br />
fournissent la correspondance entre les types <strong>de</strong> variable hôte du langage C<br />
et les constantes d'interface.<br />
Le tableau ci-après indique les valeurs <strong>de</strong>s éléments <strong>de</strong> structure sqllen et<br />
sqltype renvoyées par la comman<strong>de</strong> DESCRIBE pour les différents types <strong>de</strong><br />
base <strong>de</strong> données (instructions SELECT LIST et BIND VARIABLE<br />
DESCRIBE). Dans le cas d'un type <strong>de</strong> base <strong>de</strong> données défini par<br />
l'utilisateur, c'est le type sous-jacent qui est décrit.<br />
Votre programme peut utiliser les types et les longueurs renvoyés par une<br />
instruction DESCRIBE, mais vous pouvez avoir recours à un autre type. Le<br />
serveur <strong>de</strong> base <strong>de</strong> données effectue les conversions nécessaires entre <strong>de</strong>ux<br />
types différents. La mémoire sur laquelle pointe le champ sqldata doit<br />
correspondre aux champs sqltype et sqllen.<br />
$ Pour plus d'informations sur les types <strong>de</strong> données Embed<strong>de</strong>d SQL,<br />
reportez-vous à la section "Types <strong>de</strong> données Embed<strong>de</strong>d SQL", page 192.
Envoi <strong>de</strong> valeurs<br />
Type <strong>de</strong> champ <strong>de</strong><br />
base <strong>de</strong> données<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Type Embed<strong>de</strong>d SQL<br />
renvoyé<br />
BIGINT DT_BIGINT 8<br />
BINARY(n) DT_BINARY n<br />
BIT DT_BIT 1<br />
CHAR(n) DT_FIXCHAR n<br />
Longueur renvoyée<br />
par l'instruction<br />
DESCRIBE<br />
DATE DT_DATE Longueur <strong>de</strong> la chaîne<br />
formatée la plus longue<br />
DECIMAL(p,s) DT_DECIMAL p = octet <strong>de</strong> poids fort du<br />
champ "longueur" <strong>de</strong> la<br />
zone SQLDA, s = octet <strong>de</strong><br />
poids faible<br />
DOUBLE DT_DOUBLE 8<br />
FLOAT DT_FLOAT 4<br />
INT DT_INT 4<br />
LONG BINARY DT_LONGBINARY 32767<br />
LONG VARCHAR DT_LONGVARCHAR 32767<br />
REAL DT_FLOAT 4<br />
SMALLINT DT_SMALLINT 2<br />
TIME DT_TIME Longueur <strong>de</strong> la chaîne<br />
formatée la plus longue<br />
TIMESTAMP DT_TIMESTAMP Longueur <strong>de</strong> la chaîne<br />
formatée la plus longue<br />
TINYINT DT_TINYINT 1<br />
UNSIGNED BIGINT DT_UNSBIGINT 8<br />
UNSIGNED INT DT_UNSINT 4<br />
UNSIGNED<br />
SMALLINT<br />
DT_UNSSMALLINT 2<br />
VARCHAR(n) DT_VARCHAR n<br />
Le tableau ci-après montre la manière dont vous <strong>de</strong>vez spécifier les<br />
longueurs <strong>de</strong> valeur lorsque vous fournissez <strong>de</strong>s données au serveur dans la<br />
zone SQLDA.<br />
231
Zone <strong>de</strong>scripteur SQL (SQLDA)<br />
232<br />
Dans ce cas, seuls les types <strong>de</strong> données répertoriés dans ce tableau sont<br />
admis. Les types DT_DATE, DT_TIME et DT_TIMESTAMP sont gérés <strong>de</strong><br />
la même façon que DT_STRING lorsque <strong>de</strong>s informations sont fournies à la<br />
base <strong>de</strong> données ; la valeur doit être une chaîne <strong>de</strong> caractères terminée par<br />
une valeur NULL dans un format <strong>de</strong> date approprié.<br />
Type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL<br />
Opération du programme pour définir<br />
la longueur<br />
DT_BIGINT Aucune opération requise<br />
DT_BINARY(n) Longueur du champ <strong>de</strong> la structure BINARY<br />
DT_BIT Aucune opération requise<br />
DT_DATE Longueur déterminée par \0 en fin <strong>de</strong> chaîne<br />
DT_DECIMAL(p,s) p = octet <strong>de</strong> poids fort du champ "longueur"<br />
<strong>de</strong> la zone SQLDA, s = octet <strong>de</strong> poids faible<br />
DT_DOUBLE Aucune opération requise<br />
DT_FIXCHAR(n) Longueur <strong>de</strong> la chaîne déterminée par la<br />
valeur du champ "longueur" <strong>de</strong> la zone<br />
SQLDA<br />
DT_FLOAT Aucune opération requise<br />
DT_INT Aucune opération requise<br />
DT_LONGBINARY Champ "longueur" ignoré. Reportez-vous à<br />
la section "Envoi <strong>de</strong> données <strong>de</strong> type<br />
LONG", page 238.<br />
DT_LONGVARCHAR Champ "longueur" ignoré. Reportez-vous à<br />
la section "Envoi <strong>de</strong> données <strong>de</strong> type<br />
LONG", page 238.<br />
DT_SMALLINT Aucune opération requise<br />
DT_STRING Longueur déterminée par \0 en fin <strong>de</strong> chaîne<br />
DT_TIME Longueur déterminée par \0 en fin <strong>de</strong> chaîne<br />
DT_TIMESTAMP Longueur déterminée par \0 en fin <strong>de</strong> chaîne<br />
DT_TIMESTAMP_STRUCT Aucune opération requise<br />
DT_UNSBIGINT Aucune opération requise<br />
DT_UNSINT Aucune opération requise<br />
DT_UNSSMALLINT Aucune opération requise<br />
DT_VARCHAR(n) Longueur du champ <strong>de</strong> la structure<br />
VARCHAR<br />
DT_VARIABLE Longueur déterminée par \0 en fin <strong>de</strong> chaîne
Extraction <strong>de</strong> valeurs<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Le tableau ci-après indique les valeurs du champ "longueur" lors <strong>de</strong> la<br />
récupération <strong>de</strong> données <strong>de</strong>puis la base à l'ai<strong>de</strong> d'une zone SQLDA. Notez<br />
que le champ sqllen n'est jamais modifié lors <strong>de</strong> la récupération <strong>de</strong> données.<br />
Dans ce cas, seuls les types <strong>de</strong> données <strong>de</strong> l'interface répertoriés dans ce<br />
tableau sont admis. Les types <strong>de</strong> données DT_DATE, DT_TIME et<br />
DT_TIMESTAMP sont gérés <strong>de</strong> la même façon que DT_STRING lors <strong>de</strong> la<br />
récupération d'informations <strong>de</strong>puis la base <strong>de</strong> données. La valeur est<br />
formatée en tant que chaîne <strong>de</strong> caractères au format <strong>de</strong> date en vigueur.<br />
Type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL<br />
Valeur affectée par le<br />
programme au champ<br />
"longueur" lors d'une<br />
réception<br />
Informations <strong>de</strong><br />
longueur renvoyées<br />
par la base <strong>de</strong><br />
données après<br />
recherche d'une<br />
valeur<br />
DT_BIGINT Aucune opération requise Aucune opération requise<br />
DT_BINARY(n) Longueur maximale <strong>de</strong> la<br />
structure BINARY (n+2)<br />
Le champ len <strong>de</strong> la<br />
structure BINARY<br />
contient la longueur réelle<br />
DT_BIT Aucune opération requise Aucune opération requise<br />
DT_DATE Longueur du buffer \0 en fin <strong>de</strong> chaîne<br />
DT_DECIMAL(p,s) p = octet <strong>de</strong> poids fort,<br />
s = octet <strong>de</strong> poids faible<br />
Aucune opération requise<br />
DT_DOUBLE Aucune opération requise Aucune opération requise<br />
DT_FIXCHAR(n) Longueur du buffer Ajout <strong>de</strong> blancs jusqu'à<br />
longueur <strong>de</strong>s buffers<br />
DT_FLOAT Aucune opération requise Aucune opération requise<br />
DT_INT Aucune opération requise Aucune opération requise<br />
DT_LONGBINARY Champ "longueur" ignoré.<br />
Reportez-vous à la section<br />
"Récupération <strong>de</strong> données<br />
<strong>de</strong> type LONG",<br />
page 236.<br />
DT_LONGVARCHAR Champ "longueur" ignoré.<br />
Reportez-vous à la section<br />
"Récupération <strong>de</strong> données<br />
<strong>de</strong> type LONG",<br />
page 236.<br />
Champ "longueur" ignoré.<br />
Reportez-vous à la section<br />
"Récupération <strong>de</strong> données<br />
<strong>de</strong> type LONG",<br />
page 236.<br />
Champ "longueur" ignoré.<br />
Reportez-vous à la section<br />
"Récupération <strong>de</strong> données<br />
<strong>de</strong> type LONG",<br />
page 236.<br />
DT_SMALLINT Aucune opération requise Aucune opération requise<br />
DT_STRING Longueur du buffer \0 en fin <strong>de</strong> chaîne<br />
233
Zone <strong>de</strong>scripteur SQL (SQLDA)<br />
234<br />
Type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL<br />
Valeur affectée par le<br />
programme au champ<br />
"longueur" lors d'une<br />
réception<br />
Informations <strong>de</strong><br />
longueur renvoyées<br />
par la base <strong>de</strong><br />
données après<br />
recherche d'une<br />
valeur<br />
DT_TIME Longueur du buffer \0 en fin <strong>de</strong> chaîne<br />
DT_TIMESTAMP Longueur du buffer \0 en fin <strong>de</strong> chaîne<br />
DT_TIMESTAMP_ST<br />
RUCT<br />
Aucune opération requise Aucune opération requise<br />
DT_UNSBIGINT Aucune opération requise Aucune opération requise<br />
DT_UNSINT Aucune opération requise Aucune opération requise<br />
DT_UNSSMALLINT Aucune opération requise Aucune opération requise<br />
DT_VARCHAR(n) Longueur maximale <strong>de</strong> la<br />
structure VARCHAR<br />
(n+2)<br />
Le champ len <strong>de</strong> la<br />
structure VARCHAR<br />
contient la longueur réelle
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Envoi et extraction <strong>de</strong> valeurs longues<br />
Utilisation <strong>de</strong> types<br />
<strong>de</strong> données SQL<br />
statiques<br />
Utilisation <strong>de</strong> types<br />
<strong>de</strong> données SQL<br />
dynamiques<br />
La métho<strong>de</strong> utilisée pour envoyer et récupérer <strong>de</strong>s valeurs<br />
LONG VARCHAR et LONG BINARY dans les applications<br />
Embed<strong>de</strong>d SQL est différente <strong>de</strong> celle employée pour les autres types <strong>de</strong><br />
données. Bien qu'il soit possible d'utiliser les champs SQLDA standard,<br />
ceux-ci sont limités à 32 ko puisque les champs contenant les informations<br />
(sqldata, sqllen et sqlind) sont <strong>de</strong>s valeurs 16-bit. Remplacer ces valeurs par<br />
<strong>de</strong>s valeurs 32-bit interromprait les applications existantes.<br />
La métho<strong>de</strong> utilisée pour décrire les valeurs LONG VARCHAR et<br />
LONG BINARY est la même que celle employée pour les autres types <strong>de</strong><br />
données.<br />
$ Pour plus d'informations sur la récupération et l'envoi <strong>de</strong> valeurs,<br />
reportez-vous aux sections "Récupération <strong>de</strong> données <strong>de</strong> type LONG",<br />
page 236 et "Envoi <strong>de</strong> données <strong>de</strong> type LONG", page 238.<br />
Des structures distinctes sont utilisées pour les longueurs allouées, stockées<br />
et non tronquées <strong>de</strong>s types <strong>de</strong> données LONG BINARY et<br />
LONG VARCHAR. Les types <strong>de</strong> données SQL statiques sont définis dans le<br />
fichier sqlca.h <strong>de</strong> la façon suivante :<br />
#<strong>de</strong>fine DECL_LONGVARCHAR( size ) \<br />
struct { a_sql_uint32 array_len; \<br />
a_sql_uint32 stored_len; \<br />
a_sql_uint32 untrunc_len; \<br />
char array[size+1];\<br />
}<br />
#<strong>de</strong>fine DECL_LONGBINARY( size ) \<br />
struct { a_sql_uint32 array_len; \<br />
a_sql_uint32 stored_len; \<br />
a_sql_uint32 untrunc_len; \<br />
char array[size]; \<br />
}<br />
Pour les types <strong>de</strong> données SQL dynamiques, définissez le champ sqltype à<br />
DT_LONGVARCHAR ou DT_LONGBINARY. Les structures<br />
LONGBINARY et LONGVARCHAR associées sont les suivantes :<br />
235
Envoi et extraction <strong>de</strong> valeurs longues<br />
236<br />
type<strong>de</strong>f struct LONGVARCHAR {<br />
a_sql_uint32 array_len;<br />
/* nombre d'octets alloués dans tableau */<br />
a_sql_uint32 stored_len;<br />
/* nombre d'octets stockés dans tableau<br />
* (jamais supérieur à array_len)<br />
*/<br />
a_sql_uint32 untrunc_len;<br />
/* nombre d'octets dans expression non<br />
* tronquée<br />
* (peut être supérieur à array_len)<br />
*/<br />
char array[1]; /* données */<br />
} LONGVARCHAR, LONGBINARY;<br />
$ Pour plus d'informations sur la mise en oeuvre <strong>de</strong> cette fonctionnalité<br />
dans vos applications, reportez-vous aux sections "Récupération <strong>de</strong> données<br />
<strong>de</strong> type LONG", page 236 et "Envoi <strong>de</strong> données <strong>de</strong> type LONG", page 238.<br />
Récupération <strong>de</strong> données <strong>de</strong> type LONG<br />
Cette section décrit comment récupérer <strong>de</strong>s valeurs <strong>de</strong> type LONG <strong>de</strong> la base<br />
<strong>de</strong> données. Pour plus d'informations, reportez-vous à la section "Envoi et<br />
extraction <strong>de</strong> valeurs longues", page 235.<br />
Les procédures sont différentes selon que vous utilisiez <strong>de</strong>s instructions SQL<br />
statiques ou dynamiques.<br />
v Pour recevoir une valeur LONG VARCHAR ou LONG BINARY<br />
(SQL statique) :<br />
1 Déclarez une variable hôte <strong>de</strong> type DECL_LONGVARCHAR ou<br />
DECL_LONGBINARY.<br />
2 Récupérez les données au moyen d'une instruction FETCH, GET DATA<br />
ou EXECUTE INTO. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> définit les<br />
informations suivantes :<br />
♦ Variable indicateur La variable indicateur est négative si la valeur<br />
est NULL, égale à 0 (zéro) en l'absence <strong>de</strong> troncature, ou<br />
correspond à la longueur non tronquée positive en octets jusqu'à une<br />
valeur maximale <strong>de</strong> 32 767.<br />
$ Pour plus d'informations, reportez-vous à la section "Variables<br />
indicateur", page 201.<br />
♦ stored_len Ce champ DECL_LONGVARCHAR ou<br />
DECL_LONGBINARY contient le nombre d'octets récupérés dans<br />
le tableau. Sa valeur n'est jamais supérieure à celle d'array_len.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ untrunc_len Ce champ DECL_LONGVARCHAR ou<br />
DECL_LONGBINARY contient le nombre d'octets présents sur le<br />
serveur <strong>de</strong> base <strong>de</strong> données. Sa valeur est au moins égale à celle <strong>de</strong><br />
stored_len. Elle est définie même si la valeur n'est pas tronquée.<br />
v Pour recevoir une valeur dans une structure LONGVARCHAR ou<br />
LONGBINARY (SQL dynamique) :<br />
1 Définissez le champ sqltype à DT_LONGVARCHAR ou<br />
DT_LONGBINARY.<br />
2 Définissez le champ sqldata <strong>de</strong> façon qu'il pointe sur la structure<br />
LONGVARCHAR ou LONGBINARY.<br />
Vous pouvez utiliser la macro LONGVARCHARSIZE( n ) ou<br />
LONGBINARYSIZE( n ) pour déterminer le nombre total d'octets à<br />
allouer pour insérer n octets <strong>de</strong> données dans le champ du tableau.<br />
3 Définissez le champ array_len <strong>de</strong> la structure LONGVARCHAR ou<br />
LONGBINARY au nombre d'octets alloués pour le champ du tableau.<br />
4 Récupérez les données au moyen d'une instruction FETCH, GET DATA<br />
ou EXECUTE INTO. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> définit les<br />
informations suivantes :<br />
♦ * sqlind Ce champ sqlda est négatif si la valeur est NULL, égal à 0<br />
(zéro) en l'absence <strong>de</strong> troncature ou correspond à la longueur non<br />
tronquée positive en octets jusqu'à une valeur maximale <strong>de</strong> 32 767.<br />
♦ stored_len Ce champ LONGVARCHAR ou LONGBINARY<br />
contient le nombre d'octets récupérés dans le tableau. Sa valeur n'est<br />
jamais supérieure à celle d'array_len.<br />
♦ untrunc_len Ce champ LONGVARCHAR ou LONGBINARY<br />
contient le nombre d'octets présents sur le serveur <strong>de</strong> base <strong>de</strong><br />
données. Sa valeur est au moins égale à celle <strong>de</strong> stored_len. Elle est<br />
définie même si la valeur n'est pas tronquée.<br />
Le co<strong>de</strong> suivant illustre le mécanisme d'extraction <strong>de</strong> données<br />
LONG VARCHAR au moyen d'instructions Embed<strong>de</strong>d SQL dynamiques. Il<br />
ne s'agit en aucun cas d'une application pratique.<br />
237
Envoi et extraction <strong>de</strong> valeurs longues<br />
238<br />
#<strong>de</strong>fine DATA_LEN 128000<br />
void get_test_var()<br />
/*****************/<br />
{<br />
LONGVARCHAR *longptr;<br />
SQLDA *sqlda;<br />
SQLVAR *sqlvar;<br />
Envoi <strong>de</strong> données <strong>de</strong> type LONG<br />
}<br />
sqlda = alloc_sqlda( 1 );<br />
longptr = (LONGVARCHAR *)malloc(<br />
LONGVARCHARSIZE( DATA_LEN ) );<br />
if( sqlda == NULL || longptr == NULL ) {<br />
fatal_error( "Echec <strong>de</strong> l’allocation" );<br />
}<br />
// init longptr pour la réception <strong>de</strong> données<br />
longptr->array_len = DATA_LEN;<br />
// init sqlda pour la réception <strong>de</strong> données<br />
// (sqllen non utilisé avec les types DT_LONG)<br />
sqlda->sqld = 1; // utilisation <strong>de</strong> 1 sqlvar<br />
sqlvar = &sqlda->sqlvar[0];<br />
sqlvar->sqltype = DT_LONGVARCHAR;<br />
sqlvar->sqldata = longptr;<br />
printf( "lecture <strong>de</strong> test_var\n" );<br />
EXEC SQL PREPARE select_stmt FROM 'SELECT test_var';<br />
EXEC SQL EXECUTE select_stmt INTO DESCRIPTOR sqlda;<br />
EXEC SQL DROP STATEMENT select_stmt;<br />
printf( "stored_len: %d, untrunc_len: %d,<br />
1er car. : %c, <strong>de</strong>rnier car. : %c\n",<br />
longptr->stored_len,<br />
longptr->untrunc_len,<br />
longptr->array[0],<br />
longptr->array[DATA_LEN-1] );<br />
free_sqlda( sqlda );<br />
free( longptr );<br />
Cette section décrit comment envoyer <strong>de</strong>s valeurs <strong>de</strong> type LONG à la base <strong>de</strong><br />
données à partir d'applications Embed<strong>de</strong>d SQL. Pour plus d'informations,<br />
reportez-vous à la section "Envoi et extraction <strong>de</strong> valeurs longues", page 235.<br />
Les procédures sont différentes selon que vous utilisiez <strong>de</strong>s instructions SQL<br />
statiques ou dynamiques.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
v Pour envoyer une valeur LONG VARCHAR ou LONG BINARY<br />
(SQL statique) :<br />
1 Déclarez une variable hôte <strong>de</strong> type DECL_LONGVARCHAR ou<br />
DECL_LONGBINARY.<br />
2 Si vous envoyez une valeur NULL et utilisez une variable indicateur,<br />
attribuez à cette <strong>de</strong>rnière une valeur négative.<br />
$ Pour plus d'informations, reportez-vous à la section "Variables<br />
indicateur", page 201.<br />
3 Définissez le champ stored_len <strong>de</strong> la structure<br />
DECL_LONGVARCHAR ou DECL_LONGBINARY au nombre<br />
d'octets <strong>de</strong>s données du champ du tableau.<br />
4 Envoyez les données en ouvrant un curseur ou en exécutant l'instruction.<br />
Le co<strong>de</strong> suivant illustre le mécanisme d'envoi <strong>de</strong> données<br />
LONG VARCHAR au moyen d'instructions Embed<strong>de</strong>d SQL statiques. Il ne<br />
s'agit en aucun cas d'une application pratique.<br />
#<strong>de</strong>fine DATA_LEN 12800<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
// SQLPP initialise longdata.array_len<br />
DECL_LONGVARCHAR(128000) longdata;<br />
EXEC SQL END DECLARE SECTION;<br />
void set_test_var()<br />
/*****************/<br />
{<br />
// init longdata pour l'envoi <strong>de</strong> données<br />
memset( longdata.array, 'a', DATA_LEN );<br />
longdata.stored_len = DATA_LEN;<br />
printf( "Définition <strong>de</strong> test_var à %d a's\n",<br />
DATA_LEN );<br />
EXEC SQL SET test_var = :longdata;<br />
}<br />
v Pour envoyer une valeur au moyen d’une structure LONGVARCHAR<br />
ou LONGBINARY (SQL dynamique) :<br />
1 Définissez le champ sqltype à DT_LONGVARCHAR ou<br />
DT_LONGBINARY.<br />
2 Si vous envoyez une valeur NULL, attribuez une valeur négative à<br />
* sqlind.<br />
3 Définissez le champ sqldata <strong>de</strong> façon qu'il pointe sur la structure<br />
LONGVARCHAR ou LONGBINARY.<br />
239
Envoi et extraction <strong>de</strong> valeurs longues<br />
240<br />
Vous pouvez utiliser la macro LONGVARCHARSIZE( n ) ou<br />
LONGBINARYSIZE( n ) pour déterminer le nombre total d'octets à<br />
allouer pour insérer n octets <strong>de</strong> données dans le champ du tableau.<br />
4 Définissez le champ array_len <strong>de</strong> la structure LONGVARCHAR ou<br />
LONGBINARY au nombre d'octets alloués pour le champ du tableau.<br />
5 Définissez le champ stored_len <strong>de</strong> la structure LONGVARCHAR ou<br />
LONGBINARY au nombre d'octets <strong>de</strong> données du champ du tableau. Sa<br />
valeur ne doit pas être supérieure à celle d'array_len.<br />
6 Envoyez les données en ouvrant un curseur ou en exécutant l'instruction.
Utilisation <strong>de</strong> procédures stockées<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Cette section décrit l'utilisation <strong>de</strong> procédures SQL avec Embed<strong>de</strong>d SQL.<br />
Utilisation <strong>de</strong> procédures stockées simples<br />
Vous pouvez créer et appeler <strong>de</strong>s procédures stockées avec Embed<strong>de</strong>d SQL.<br />
Une instruction CREATE PROCEDURE peut être imbriquée comme<br />
n'importe quelle autre instruction <strong>de</strong> définition <strong>de</strong> données, par exemple<br />
CREATE TABLE. Vous pouvez également imbriquer une instruction CALL<br />
pour exécuter une procédure stockée. Le fragment <strong>de</strong> co<strong>de</strong> suivant illustre la<br />
création et l'exécution d'une procédure stockée avec Embed<strong>de</strong>d SQL :<br />
EXEC SQL CREATE PROCEDURE pettycash( IN amount<br />
DECIMAL(10,2) )<br />
BEGIN<br />
UPDATE account<br />
SET balance = balance - amount<br />
WHERE name = ’bank’;<br />
UPDATE account<br />
SET balance = balance + amount<br />
WHERE name = ’pettycash expense’;<br />
END;<br />
EXEC SQL CALL pettycash( 10.72 );<br />
Si vous souhaitez transmettre <strong>de</strong>s valeurs <strong>de</strong> variable hôte à une procédure<br />
stockée ou récupérer les variables <strong>de</strong> résultat, vous <strong>de</strong>vez préparer et<br />
exécuter une instruction CALL. Le fragment <strong>de</strong> co<strong>de</strong> suivant illustre<br />
l'utilisation <strong>de</strong> variables hôte. Les clauses USING et INTO sont utilisées avec<br />
l'instruction EXECUTE.<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
double hv_expense;<br />
double hv_balance;<br />
EXEC SQL END DECLARE SECTION;<br />
241
Utilisation <strong>de</strong> procédures stockées<br />
242<br />
// co<strong>de</strong> ici<br />
EXEC SQL CREATE PROCEDURE pettycash(<br />
IN expense DECIMAL(10,2),<br />
OUT endbalance DECIMAL(10,2) )<br />
BEGIN<br />
UPDATE account<br />
SET balance = balance - expense<br />
WHERE name = ’bank’;<br />
UPDATE account<br />
SET balance = balance + expense<br />
WHERE name = ’pettycash expense’;<br />
SET endbalance = ( SELECT balance FROM account<br />
WHERE name = ’bank’ );<br />
END;<br />
EXEC SQL PREPARE S1 FROM ’CALL pettycash( ?, ? )’;<br />
EXEC SQL EXECUTE S1 USING :hv_expense INTO :hv_balance;<br />
$ Pour plus d’informations, reportez-vous aux sections "Instruction<br />
EXECUTE [ESQL]", page 437 du document ASA Manuel <strong>de</strong> référence SQL<br />
et "Instruction PREPARE [ESQL]", page 518 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
Procédures stockées avec jeux <strong>de</strong> résultats<br />
Les procédures <strong>de</strong> base <strong>de</strong> données peuvent aussi contenir <strong>de</strong>s instructions<br />
SELECT. La procédure est déclarée à l'ai<strong>de</strong> d'une clause RESULT qui<br />
spécifie le nombre, le nom et le type <strong>de</strong>s colonnes du jeu <strong>de</strong> résultats. Les<br />
colonnes <strong>de</strong> jeu <strong>de</strong> résultats sont différentes <strong>de</strong>s paramètres <strong>de</strong> sortie. Pour<br />
les procédures avec jeux <strong>de</strong> résultats, vous pouvez remplacer une instruction<br />
SELECT par une instruction CALL dans la déclaration du curseur :<br />
EXEC SQL BEGIN DECLARE SECTION;<br />
char hv_name[100];<br />
EXEC SQL END DECLARE SECTION;<br />
EXEC SQL CREATE PROCEDURE female_employees()<br />
RESULT( name char(50) )<br />
BEGIN<br />
SELECT emp_fname || emp_lname FROM employee<br />
WHERE sex = ’f’;<br />
END;<br />
EXEC SQL PREPARE S1 FROM ’CALL female_employees()’;<br />
EXEC SQL DECLARE C1 CURSOR FOR S1;<br />
EXEC SQL OPEN C1;<br />
for(;;) {
Curseurs<br />
dynamiques pour<br />
les instructions<br />
CALL<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
EXEC SQL FETCH C1 INTO :hv_name;<br />
if( SQLCODE != SQLE_NOERROR ) break;<br />
printf( "%s\\n", hv_name );<br />
}<br />
EXEC SQL CLOSE C1;<br />
Dans cet exemple, la procédure a été appelée avec une instruction OPEN, et<br />
non une instruction EXECUTE. L'instruction OPEN provoque l'exécution <strong>de</strong><br />
la procédure jusqu'à ce que celle-ci rencontre une instruction SELECT. A ce<br />
point, C1 est un curseur pour l'instruction SELECT au sein <strong>de</strong> la procédure<br />
<strong>de</strong> base <strong>de</strong> données. Vous pouvez utiliser toutes les formes <strong>de</strong> la comman<strong>de</strong><br />
FETCH (défilement vers l'arrière et vers l'avant) jusqu'à ce que vous ayez<br />
terminé. L'instruction CLOSE interrompt l'exécution <strong>de</strong> la procédure.<br />
Si l'instruction SELECT avait été suivie d'une autre instruction dans la<br />
procédure, cette autre instruction n'aurait pas été exécutée. Pour pouvoir<br />
exécuter les instructions qui suivent une instruction SELECT, faites appel à<br />
la comman<strong>de</strong> RESUME nom_curseur. Celle-ci renvoie l'avertissement<br />
SQLE_PROCEDURE_COMPLETE ou SQLE_NOERROR pour signaler<br />
l'existence d'un autre curseur. Cet exemple illustre une procédure comportant<br />
<strong>de</strong>ux instructions SELECT :<br />
EXEC SQL CREATE PROCEDURE people()<br />
RESULT( name char(50) )<br />
BEGIN<br />
SELECT emp_fname || emp_lname<br />
FROM employee;<br />
SELECT fname || lname<br />
FROM customer;<br />
END;<br />
EXEC SQL PREPARE S1 FROM ’CALL people()’;<br />
EXEC SQL DECLARE C1 CURSOR FOR S1;<br />
EXEC SQL OPEN C1;<br />
while( SQLCODE == SQLE_NOERROR ) {<br />
for(;;) {<br />
EXEC SQL FETCH C1 INTO :hv_name;<br />
if( SQLCODE != SQLE_NOERROR ) break;<br />
printf( "%s\\n", hv_name );<br />
}<br />
EXEC SQL RESUME C1;<br />
}<br />
EXEC SQL CLOSE C1;<br />
Les exemples précé<strong>de</strong>nts faisaient appel à <strong>de</strong>s curseurs statiques. Il est<br />
également possible d'utiliser <strong>de</strong>s curseurs dynamiques avec l'instruction<br />
CALL.<br />
243
Utilisation <strong>de</strong> procédures stockées<br />
DESCRIBE ALL<br />
Jeux <strong>de</strong> résultats<br />
multiples<br />
244<br />
$ Pour obtenir une <strong>de</strong>scription <strong>de</strong>s curseurs dynamiques, reportez-vous à<br />
la section "Instruction SELECT dynamique", page 224.<br />
L'instruction DESCRIBE est tout à fait adaptée aux appels <strong>de</strong> procédure. Une<br />
instruction DESCRIBE OUTPUT génère une zone SQLDA comportant une<br />
<strong>de</strong>scription pour chaque colonne du jeu <strong>de</strong> résultats.<br />
Si la procédure ne dispose pas d'un jeu <strong>de</strong> résultats, la zone SQLDA inclut<br />
une <strong>de</strong>scription pour chaque paramètre INOUT ou OUT <strong>de</strong> la procédure.<br />
Une instruction DESCRIBE INPUT génère une zone SQLDA comportant<br />
une <strong>de</strong>scription pour chaque paramètre IN ou INOUT.<br />
DESCRIBE ALL décrit les paramètres IN, INOUT, OUT et RESULT set.<br />
Elle fournit <strong>de</strong>s informations supplémentaires à l'ai<strong>de</strong> <strong>de</strong>s variables<br />
indicateur <strong>de</strong> la zone SQLDA.<br />
Les bits DT_PROCEDURE_IN et DT_PROCEDURE_OUT sont définis<br />
dans la variable indicateur lors <strong>de</strong> la <strong>de</strong>scription d'une instruction CALL.<br />
DT_PROCEDURE_IN indique un paramètre IN ou INOUT et<br />
DT_PROCEDURE_OUT, un paramètre INOUT ou OUT. Les colonnes<br />
RESULT mettent à blanc les <strong>de</strong>ux bits.<br />
Après une instruction DESCRIBE OUTPUT, ces bits peuvent servir à<br />
distinguer les instructions comportant <strong>de</strong>s jeux <strong>de</strong> résultats (qui doivent faire<br />
appel à OPEN, à FETCH, à RESUME et à CLOSE) <strong>de</strong> celles qui n'en ont pas<br />
(et qui doivent utiliser EXECUTE).<br />
$ Pour obtenir une <strong>de</strong>scription complète, reportez-vous à la section<br />
"Instruction DESCRIBE [ESQL]", page 414 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
Si une procédure renvoie plusieurs jeux <strong>de</strong> résultats, vous <strong>de</strong>vez indiquer s'ils<br />
changent <strong>de</strong> forme après chaque instruction RESUME.<br />
C'est le curseur que vous <strong>de</strong>vez décrire, et non l'instruction, notamment sa<br />
position courante.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Techniques <strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL<br />
Cette section comporte plusieurs astuces pour les développeurs <strong>de</strong><br />
programmes Embed<strong>de</strong>d SQL.<br />
Mise en oeuvre <strong>de</strong> la gestion <strong>de</strong>s requêtes<br />
Fonctions <strong>de</strong> sauvegar<strong>de</strong><br />
Lorsque le comportement par défaut <strong>de</strong> la DLL d'interface s'applique, les<br />
applications atten<strong>de</strong>nt que chaque requête <strong>de</strong> base <strong>de</strong> données soit terminée<br />
avant d'exécuter d'autres fonctions. Il est toutefois possible <strong>de</strong> modifier ce<br />
comportement à l'ai<strong>de</strong> <strong>de</strong>s fonctions <strong>de</strong> gestion <strong>de</strong>s requêtes. Par exemple,<br />
lors <strong>de</strong> l'utilisation d'Interactive SQL, le système d'exploitation reste actif<br />
pendant que l'utilitaire attend une réponse <strong>de</strong> la base <strong>de</strong> données et qu'il<br />
effectue certaines tâches dans le même temps.<br />
Vous pouvez maintenir une activité sous Windows pendant une requête <strong>de</strong><br />
base <strong>de</strong> données par l'intermédiaire d'une fonction <strong>de</strong> rappel (callback). Dans<br />
cette fonction <strong>de</strong> rappel, vous ne <strong>de</strong>vez pas effectuer d'autres requêtes <strong>de</strong><br />
base <strong>de</strong> données, à l'exception <strong>de</strong> db_cancel_request. Pour savoir si une<br />
requête est en cours d'exécution, vous pouvez utiliser db_is_working dans<br />
les routines <strong>de</strong> gestion <strong>de</strong> messages.<br />
La fonction db_register_a_callback sert à enregistrer les fonctions <strong>de</strong> rappel<br />
(callback) <strong>de</strong> l'application :<br />
$ Pour plus d'informations, reportez-vous aux sections suivantes :<br />
♦ "Fonction db_register_a_callback", page 259<br />
♦ "Fonction db_cancel_request", page 255<br />
♦ "Fonction db_is_working", page 258<br />
La fonction db_backup permet d'effectuer une sauvegar<strong>de</strong> en ligne dans <strong>de</strong>s<br />
applications Embed<strong>de</strong>d SQL. C'est l'utilitaire <strong>de</strong> sauvegar<strong>de</strong> qui exécute cette<br />
fonction. Si ce <strong>de</strong>rnier ne permet pas <strong>de</strong> satisfaire vos besoins en matière <strong>de</strong><br />
sauvegar<strong>de</strong>, il vous suffit d'écrire d'un programme faisant appel à cette<br />
fonction.<br />
245
Techniques <strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL<br />
246<br />
Instruction BACKUP recommandée<br />
Bien que cette fonction permette d'ajouter <strong>de</strong>s fonctionnalités <strong>de</strong><br />
sauvegar<strong>de</strong> dans une application, il est recommandé d'exécuter cette tâche<br />
par l'intermédiaire <strong>de</strong> l'instruction BACKUP. Pour plus d'informations,<br />
reportez-vous à la section "Instruction BACKUP", page 259 du document<br />
ASA Manuel <strong>de</strong> référence SQL.<br />
$ Vous pouvez également accé<strong>de</strong>r directement à l'utilitaire <strong>de</strong> sauvegar<strong>de</strong><br />
par l'intermédiaire <strong>de</strong> la fonction DBBackup <strong>de</strong>s outils <strong>de</strong> base <strong>de</strong> données.<br />
Pour plus d'informations sur cette fonction, reportez-vous à la section<br />
"Fonction DBBackup", page 320.<br />
$ Pour plus d'informations, reportez-vous à la section "Fonction<br />
db_backup", page 252.
Préprocesseur SQL<br />
Syntaxe<br />
Voir aussi<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Le préprocesseur SQL traite un programme C ou C++ contenant le langage<br />
<strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL, avant que le compilateur ne soit exécuté.<br />
sqlpp [ options ] nom_fichier_sql [ nom_fichier_résultat ]<br />
Option Description<br />
–c "mot_clé=valeur;..." Fournit les paramètres <strong>de</strong> connexion à la base <strong>de</strong><br />
données <strong>de</strong> référence [UltraLite].<br />
–d Optimise l'espace alloué aux données.<br />
–e niveau Balise toute syntaxe SQL non conforme en tant<br />
qu’erreur.<br />
–f Place le mot-clé far sur les données statiques générées.<br />
-g N'affiche pas d'avertissement UltraLite.<br />
–h longueur_ligne Limite la longueur maximale <strong>de</strong>s lignes <strong>de</strong> résultat.<br />
–k Inclut la déclaration utilisateur <strong>de</strong> SQLCODE.<br />
-m version Indique le nom <strong>de</strong> version pour les scripts <strong>de</strong><br />
synchronisation générés.<br />
–n Génère le numéro <strong>de</strong>s lignes.<br />
–o sys_exploitation Indique le système d'exploitation cible.<br />
–p projet I<strong>de</strong>ntifie le nom du projet UltraLite.<br />
–q Opère en mo<strong>de</strong> non détaillé. Aucune bannière n'est<br />
imprimée.<br />
–r Génère du co<strong>de</strong> réentrant<br />
–s longueur_chaîne Indique la longueur <strong>de</strong> chaîne maximale pour le<br />
compilateur.<br />
–w niveau Balise toute syntaxe SQL non conforme en tant<br />
qu’avertissement.<br />
–x Modifie les chaînes SQL codées sur plusieurs octets en<br />
séquences d'échappement.<br />
–z classement Spécifie l'ordre <strong>de</strong> classement.<br />
"Introduction", page 178<br />
247
Préprocesseur SQL<br />
Description<br />
Options<br />
248<br />
Le préprocesseur SQL traite un programme C ou C++ contenant le langage<br />
<strong>de</strong> <strong>programmation</strong> Embed<strong>de</strong>d SQL, avant que le compilateur ne soit exécuté.<br />
SQLPP convertit les instructions SQL <strong>de</strong> fichier_entrée en langage C source<br />
et les enregistre dans fichier_résultat. L’extension normale pour les<br />
programmes source en Embed<strong>de</strong>d SQL est .sqc. Le nom du fichier <strong>de</strong><br />
résultat par défaut est nom_fichier_SQL avec l'extension .c. Si<br />
nom_fichier_SQL comporte déjà l'extension .c, l'extension du fichier <strong>de</strong><br />
résultat sera, par défaut, .cc.<br />
–c Cette option est requise lors du prétraitement <strong>de</strong>s fichiers d'une<br />
application UltraLite. La chaîne <strong>de</strong> connexion doit donner au préprocesseur<br />
SQL accès pour lire et modifier votre base <strong>de</strong> données <strong>de</strong> référence.<br />
–d Cette option permet <strong>de</strong> générer du co<strong>de</strong> qui réduit l'espace <strong>de</strong>s données.<br />
Les structures <strong>de</strong> données sont réutilisées et initialisées au moment <strong>de</strong><br />
l'exécution, avant toute utilisation. Cette opération accroît la taille du co<strong>de</strong>.<br />
–e Balise tout élément en Embed<strong>de</strong>d SQL qui ne fait pas partie d'un<br />
ensemble spécifié par la norme SQL/92, en tant qu'erreur.<br />
level accepte les valeurs suivantes :<br />
♦ e Balise la syntaxe non conforme à la norme SQL/92 au niveau <strong>de</strong>s<br />
entrées.<br />
♦ i Balise la syntaxe non conforme à la norme SQL/92 au niveau<br />
intermédiaire.<br />
♦ f Balise la syntaxe non entièrement conforme à la norme SQL/92.<br />
♦ t Balise les types <strong>de</strong> variables hôte non standard.<br />
♦ u Balise la syntaxe qui n'est pas supportée par UltraLite<br />
♦ w Autorise toute syntaxe supportée.<br />
-g N'affiche pas d'avertissement spécifique lors <strong>de</strong> la génération <strong>de</strong> co<strong>de</strong><br />
UltraLite.<br />
–h Limite la longueur maximale <strong>de</strong>s lignes générées par sqlpp à num. La<br />
valeur num doit être suivie d'une barre oblique inversée (\) et ne peut pas être<br />
inférieure à 10.<br />
–k Informe le préprocesseur que le programme à compiler inclut une<br />
déclaration utilisateur <strong>de</strong> SQLCODE.<br />
-m Indique le nom <strong>de</strong> version pour les scripts <strong>de</strong> synchronisation générés.<br />
Les scripts <strong>de</strong> synchronisation générés peuvent être utilisés dans une base <strong>de</strong><br />
données consolidée MobiLink pour une synchronisation simple.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
–n Génère <strong>de</strong>s informations sur les numéros <strong>de</strong> ligne dans le fichier C. Il<br />
s'agit <strong>de</strong> directives #line placées aux endroits appropriés dans le co<strong>de</strong> C<br />
généré. Si le compilateur que vous employez supporte la directive #line, cette<br />
option lui permet <strong>de</strong> signaler les erreurs par les numéros <strong>de</strong> ligne dans le<br />
fichier SQC (celui qui contient les données Embed<strong>de</strong>d SQL) au lieu <strong>de</strong><br />
signaler les erreurs par les numéros <strong>de</strong> ligne dans le fichier C généré par le<br />
préprocesseur SQL. En outre, les directives #line sont utilisées <strong>de</strong> façon<br />
indirecte par le débogueur <strong>de</strong> niveau source afin <strong>de</strong> pouvoir effectuer le<br />
débogage en consultant le fichier SQC.<br />
–o Spécifie le système d'exploitation cible. L'argument spécifié doit<br />
correspondre au système sur lequel vous exécutez le programme. Une<br />
référence à un symbole spécial est générée dans votre programme. Ce<br />
symbole est défini dans la bibliothèque d'interface. Si vous utilisez une<br />
spécification <strong>de</strong> système d'exploitation ou une bibliothèque inappropriée, une<br />
erreur est détectée par le générateur <strong>de</strong> liens. Les systèmes supportés sont :<br />
♦ WINDOWS Microsoft Windows 32 bits (Windows 95/98, Windows CE)<br />
♦ WINNT Microsoft Windows NT/2000<br />
♦ NETWARE Novell NetWare<br />
♦ UNIX UNIX<br />
–p I<strong>de</strong>ntifie le projet UltraLite auquel appartiennent les fichiers<br />
Embed<strong>de</strong>d SQL. Cette option ne s’applique que lors du traitement <strong>de</strong> fichiers<br />
d’une application UltraLite.<br />
–q N'imprime aucune bannière.<br />
–r Pour plus d'informations sur le co<strong>de</strong> réentrant, reportez-vous à la section<br />
"Gestion <strong>de</strong> la zone SQLCA pour le co<strong>de</strong> multi-thread ou réentrant",<br />
page 208.<br />
–s Définit la longueur <strong>de</strong> chaîne maximale que le préprocesseur peut intégrer<br />
au fichier C. Les chaînes supérieures à cette valeur seront initialisées en<br />
fonction d'une liste <strong>de</strong> caractères (’a’,’b’,’c’, etc). La plupart <strong>de</strong>s compilateurs<br />
C ne reconnaissent pas les littéraux <strong>de</strong> chaînes supérieurs à une certaine<br />
limite. Cette option permet <strong>de</strong> définir cette limite. La valeur par défaut<br />
est 500.<br />
–w Balise tout élément en Embed<strong>de</strong>d SQL qui ne fait pas partie d'un<br />
ensemble spécifié par la norme SQL/92, en tant qu'avertissement.<br />
level accepte les valeurs suivantes :<br />
♦ e Balise la syntaxe non conforme à la norme SQL/92 au niveau <strong>de</strong>s<br />
entrées.<br />
249
Préprocesseur SQL<br />
250<br />
♦ i Balise la syntaxe non conforme à la norme SQL/92 au niveau<br />
intermédiaire.<br />
♦ f Balise la syntaxe non entièrement conforme à la norme SQL/92.<br />
♦ t Balise les types <strong>de</strong> variables hôte non standard.<br />
♦ u Balise la syntaxe qui n'est pas supportée par UltraLite<br />
♦ w Autorise toute syntaxe supportée.<br />
–x Modifie les chaînes codées sur plusieurs octets en séquences<br />
d'échappement afin qu'elles soient acceptées par les compilateurs.<br />
–z Spécifie l'ordre <strong>de</strong> classement. Pour obtenir la liste <strong>de</strong>s ordres <strong>de</strong><br />
classement conseillés, tapez dbinit –l à l'invite <strong>de</strong> comman<strong>de</strong>s.<br />
L'ordre <strong>de</strong> classement permet au préprocesseur d'interpréter les caractères<br />
utilisés dans le co<strong>de</strong> source du programme, par exemple pour i<strong>de</strong>ntifier les<br />
caractères alphabétiques admis dans les i<strong>de</strong>ntificateurs. Si l'option -z n'est<br />
pas spécifiée, le préprocesseur tente <strong>de</strong> choisir un classement possible, en<br />
faisant référence au système d'exploitation et à la variable d'environnement<br />
SQLLOCALE.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
Points d'entrée <strong>de</strong><br />
DLL<br />
Fonction alloc_sqlda<br />
Syntaxe<br />
Description<br />
Fonction alloc_sqlda_noind<br />
Syntaxe<br />
Description<br />
Le préprocesseur SQL génère <strong>de</strong>s appels à <strong>de</strong>s fonctions <strong>de</strong> la bibliothèque<br />
d'interface ou <strong>de</strong> la DLL. En plus <strong>de</strong> ces appels, plusieurs fonctions <strong>de</strong><br />
bibliothèque permettent d'effectuer plus facilement les opérations <strong>de</strong> base <strong>de</strong><br />
données. La comman<strong>de</strong> EXEC SQL INCLUDE SQLCA inclut <strong>de</strong>s<br />
prototypes <strong>de</strong> ces fonctions.<br />
La présente section contient une <strong>de</strong>scription <strong>de</strong> ces différentes fonctions.<br />
Les points d'entrée <strong>de</strong> DLL sont les mêmes, si ce n'est que les prototypes<br />
disposent d'un modificateur approprié pour chaque DLL.<br />
Vous pouvez déclarer les points d'entrée <strong>de</strong> façon "portable" en utilisant<br />
_esqlentry_, définie dans sqlca.h. Les valeurs obtenues sont les suivantes :<br />
__stdcall<br />
SQLDA *alloc_sqlda( unsigned numvar );<br />
Alloue une zone SQLDA avec <strong>de</strong>s <strong>de</strong>scripteurs pour les variables numvar.<br />
Le champ sqln <strong>de</strong> la zone SQLDA est initialisé avec la valeur numvar. De<br />
l'espace est alloué aux variables indicateur, les pointeurs indicateur sont<br />
définis <strong>de</strong> façon à pointer sur cet espace et la valeur indicateur est initialisée<br />
à zéro. Un pointeur NULL est renvoyé si l'allocation <strong>de</strong> mémoire est<br />
impossible. Il est conseillé d'utiliser cette fonction <strong>de</strong> préférence à<br />
alloc_sqlda_noind function.<br />
SQLDA *alloc_sqlda_noind( unsigned numvar );<br />
Alloue une zone SQLDA avec <strong>de</strong>s <strong>de</strong>scripteurs pour les variables numvar.<br />
Le champ sqln <strong>de</strong> la zone SQLDA est initialisé avec la valeur numvar.<br />
Aucun espace n'est alloué aux variables indicateur et les pointeurs indicateur<br />
sont définis avec le pointeur NULL. Un pointeur NULL est renvoyé si<br />
l'allocation <strong>de</strong> mémoire est impossible.<br />
251
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
Fonction db_backup<br />
Syntaxe<br />
Autorisation<br />
Description<br />
252<br />
void db_backup(<br />
SQLCA * sqlca,<br />
int op,<br />
int file_num,<br />
unsigned long page_num,<br />
SQLDA * sqlda);<br />
Vous <strong>de</strong>vez être connecté sous un ID utilisateur détenant les droits DBA ou<br />
REMOTE DBA (SQL Remote).<br />
Instruction BACKUP recommandée<br />
Bien que cette fonction permette d'ajouter <strong>de</strong>s fonctionnalités <strong>de</strong><br />
sauvegar<strong>de</strong> dans une application, il est recommandé d'exécuter cette tâche<br />
par l'intermédiaire <strong>de</strong> l'instruction BACKUP. Pour plus d'informations,<br />
reportez-vous à la section "Instruction BACKUP", page 259 du document<br />
ASA Manuel <strong>de</strong> référence SQL.<br />
L'opération effectuée est fonction <strong>de</strong> la valeur du paramètre op :<br />
♦ DB_BACKUP_START Doit être appelé pour qu'une sauvegar<strong>de</strong> puisse<br />
démarrer. Une seule sauvegar<strong>de</strong> peut s'exécuter à un moment donné sur<br />
un serveur <strong>de</strong> base <strong>de</strong> données. Les points <strong>de</strong> reprise <strong>de</strong> la base sont<br />
désactivés jusqu'à la fin <strong>de</strong> la sauvegar<strong>de</strong> (db_backup est appelé avec<br />
une valeur op <strong>de</strong> DB_BACKUP_END). Si la sauvegar<strong>de</strong> ne peut pas<br />
démarrer, le SQLCODE est SQLE_BACKUP_NOT_STARTED. Dans<br />
le cas contraire, le champ SQLCOUNT <strong>de</strong> la sqlca prend la valeur <strong>de</strong> la<br />
taille <strong>de</strong> chaque page <strong>de</strong> la base <strong>de</strong> données. (Les sauvegar<strong>de</strong>s sont<br />
traitées page par page.)<br />
Les paramètres file_num, page_num et sqlda sont ignorés.<br />
♦ DB_BACKUP_OPEN_FILE Ouvre le fichier <strong>de</strong> base <strong>de</strong> données spécifié<br />
par file_num, ce qui permet <strong>de</strong> sauvegar<strong>de</strong>r les pages <strong>de</strong> ce fichier à<br />
l'ai<strong>de</strong> <strong>de</strong> DB_BACKUP_READ_PAGE. Le nombre <strong>de</strong> fichiers admis est<br />
compris entre 0 (zéro) et DB_BACKUP_MAX_FILE pour les fichiers<br />
<strong>de</strong> base <strong>de</strong> données principaux, entre 0 et<br />
DB_BACKUP_TRANS_LOG_FILE pour le journal <strong>de</strong> transactions, et<br />
entre 0 et DB_BACKUP_WRITE_FILE pour l'éventuel fichier d'écriture<br />
<strong>de</strong> base <strong>de</strong> données. Si le fichier spécifié n'existe pas, le SQLCODE est<br />
SQLE_NOTFOUND. Dans le cas contraire, SQLCOUNT contient le<br />
nombre <strong>de</strong> pages du fichier, SQLIOESTIMATE contient une valeur sur<br />
32 bits (POSIX time_t) i<strong>de</strong>ntifiant l'heure <strong>de</strong> création du fichier <strong>de</strong> base<br />
<strong>de</strong> données, et le nom du fichier du système d'exploitation apparaît dans<br />
le champ sqlerrmc <strong>de</strong> la zone SQLCA.<br />
Les paramètres page_num et sqlda sont ignorés.
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ DB_BACKUP_READ_PAGE Lit une page du fichier <strong>de</strong> base <strong>de</strong> données<br />
spécifié par file_num. Le paramètre page_num doit être une valeur<br />
comprise entre 0 et le nombre <strong>de</strong> pages moins une, renvoyé dans<br />
SQLCOUNT par un appel à db_backup dans le cadre <strong>de</strong> l'opération<br />
DB_BACKUP_OPEN_FILE. Sinon, SQLCODE est défini sur<br />
SQLE_NOTFOUND. Le <strong>de</strong>scripteur sqlda doit être défini avec une<br />
variable <strong>de</strong> type DT_BINARY qui pointe sur un buffer. Le buffer doit<br />
être suffisamment grand pour contenir <strong>de</strong>s données binaires <strong>de</strong> la taille<br />
renvoyée dans le champ SQLCOUNT lors <strong>de</strong> l'appel à db_backup dans<br />
le cadre <strong>de</strong> l'opération DB_BACKUP_START.<br />
DT_BINARY contient une indication <strong>de</strong> longueur <strong>de</strong> <strong>de</strong>ux octets suivie<br />
<strong>de</strong>s données binaires proprement dites ; la taille du buffer doit donc être<br />
supérieure <strong>de</strong> <strong>de</strong>ux octets à celle <strong>de</strong> la page.<br />
Sauvegar<strong>de</strong> du buffer par l'application<br />
Cet appel crée une copie <strong>de</strong> la page <strong>de</strong> base <strong>de</strong> données spécifiée dans<br />
le buffer, mais l'application peut sauvegar<strong>de</strong>r ce <strong>de</strong>rnier sur un<br />
support <strong>de</strong> sauvegar<strong>de</strong>.<br />
♦ DB_BACKUP_READ_RENAME_LOG Action i<strong>de</strong>ntique à celle <strong>de</strong><br />
DB_BACKUP_READ_PAGE, hormis le fait que le serveur <strong>de</strong> base <strong>de</strong><br />
données renomme le journal <strong>de</strong> transactions et en démarre un nouveau<br />
une fois la <strong>de</strong>rnière page du journal <strong>de</strong> transactions renvoyée.<br />
S'il ne parvient pas à renommer le journal à l'heure courante (par<br />
exemple, il peut exister <strong>de</strong>s transactions incomplètes dans les bases <strong>de</strong><br />
données <strong>de</strong> la version 7.x ou antérieure), l'erreur<br />
SQLE_BACKUP_CANNOT_RENAME_LOG_YET est générée. Dans<br />
ce cas, n'utilisez pas la page renvoyée, mais relancez la <strong>de</strong>man<strong>de</strong> jusqu'à<br />
ce que vous receviez SQLE_NOERROR, puis enregistrez la page.<br />
Continuez à lire les pages jusqu'à ce que vous receviez l'erreur<br />
SQLE_NOTFOUND.<br />
L'erreur SQLE_BACKUP_CANNOT_RENAME_LOG_YET peut être<br />
renvoyée plusieurs fois sur plusieurs pages. Dans la boucle <strong>de</strong> relance,<br />
ajoutez un intervalle <strong>de</strong> temps afin <strong>de</strong> ne pas ralentir le serveur avec un<br />
trop grand nombre <strong>de</strong> <strong>de</strong>man<strong>de</strong>s.<br />
La condition SQLE_NOTFOUND signifie que la sauvegar<strong>de</strong> du journal<br />
<strong>de</strong> transactions a abouti et que le fichier a été renommé. Le nom <strong>de</strong><br />
l'ancien fichier <strong>de</strong> transactions est renvoyé dans le champ sqlerrmc <strong>de</strong> la<br />
zone SQLCA.<br />
253
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
254<br />
Vous <strong>de</strong>vez vérifier la valeur sqlda->sqlvar[0].sqlind après un appel<br />
db_backup. Si cette valeur est supérieure à zéro, la <strong>de</strong>rnière page du<br />
journal a été écrite et le fichier journal a été renommé. Le nouveau nom<br />
est toujours sqlca.sqlerrmc, mais la valeur SQLCODE est<br />
SQLE_NOERROR.<br />
Après cela, vous ne <strong>de</strong>vez pas rappeler db_backup, sauf pour fermer<br />
<strong>de</strong>s fichiers et terminer la sauvegar<strong>de</strong>. Le cas échéant, vous recevez une<br />
<strong>de</strong>uxième copie <strong>de</strong> votre fichier journal sauvegardé, ainsi que<br />
SQLE_NOTFOUND.<br />
♦ DB_BACKUP_CLOSE_FILE Cette fonction doit être appelée lorsque le<br />
traitement d'un fichier est terminé, pour refermer le fichier <strong>de</strong> base <strong>de</strong><br />
données spécifié par file_num.<br />
Les paramètres page_num et sqlda sont ignorés.<br />
♦ DB_BACKUP_END Cette fonction doit être appelée à la fin <strong>de</strong> la<br />
sauvegar<strong>de</strong>. Aucune autre sauvegar<strong>de</strong> ne peut démarrer tant que la<br />
sauvegar<strong>de</strong> en cours n'est pas terminée. Les points <strong>de</strong> reprise sont <strong>de</strong><br />
nouveau activés.<br />
Les paramètres file_num, page_num et sqlda sont ignorés.<br />
Le programme dbbackup utilise l'algorithme suivant. Notez qu'il ne s'agit pas<br />
<strong>de</strong> co<strong>de</strong> C et qu'aucun contrôle d'erreurs n'est inclus.<br />
db_backup( ... DB_BACKUP_START ... )<br />
alloue <strong>de</strong>s buffers page en fonction <strong>de</strong> la taille <strong>de</strong>s<br />
pages dans SQLCODE<br />
sqlda = alloc_sqlda( 1 )<br />
sqlda->sqld = 1;<br />
sqlda->sqlvar[0].sqltype = DT_BINARY<br />
sqlda->sqlvar[0].sqldata = allocated buffer<br />
for file_num = 0 to DB_BACKUP_MAX_FILE<br />
db_backup( ... DB_BACKUP_OPEN_FILE, file_num ... )<br />
if SQLCODE == SQLE_NO_ERROR<br />
/* Le fichier existe */<br />
num_pages = SQLCOUNT<br />
file_time = SQLE_IO_ESTIMATE<br />
ouvre le fichier <strong>de</strong> backup avec le nom indiqué dans<br />
sqlca.sqlerrmc<br />
for page_num = 0 to num_pages - 1<br />
db_backup( ... DB_BACKUP_READ_PAGE,<br />
file_num, page_num, sqlda )<br />
écrit les buffers page dans le fichier <strong>de</strong><br />
sauvegar<strong>de</strong><br />
next page_num<br />
close backup file<br />
db_backup( ... DB_BACKUP_CLOSE_FILE, file_num ... )<br />
end if<br />
next file_num
Fonction db_cancel_request<br />
Syntaxe<br />
Description<br />
Fonction db_<strong>de</strong>lete_file<br />
Syntaxe<br />
Autorisation<br />
Description<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
backup up file DB_BACKUP_WRITE_FILE as above<br />
backup up file DB_BACKUP_TRANS_LOG_FILE as above<br />
free page buffer<br />
db_backup( ... DB_BACKUP_END ... )<br />
int db_cancel_request( SQLCA *sqlca );<br />
Annule la requête active sur le serveur <strong>de</strong> base <strong>de</strong> données. Cette fonction<br />
vérifie qu'une requête est active sur le serveur <strong>de</strong> base <strong>de</strong> données avant<br />
d'envoyer la <strong>de</strong>man<strong>de</strong> d'annulation. Si la fonction renvoie 1, la <strong>de</strong>man<strong>de</strong><br />
d'annulation a été transmise ; si elle renvoie 0, aucune <strong>de</strong>man<strong>de</strong> n'a été<br />
transmise.<br />
Une valeur renvoyée différente <strong>de</strong> 0 ne signifie pas que la requête a été<br />
annulée. Dans les cas (peu nombreux) où la synchronisation est difficile, la<br />
<strong>de</strong>man<strong>de</strong> d'annulation et la réponse du serveur ou <strong>de</strong> la base "se croisent".<br />
Dans ces cas, l'annulation n'a pas lieu, même si la fonction continue <strong>de</strong><br />
renvoyer TRUE.<br />
Il est possible d'appeler la fonction db_cancel_request <strong>de</strong> façon asynchrone.<br />
Cette fonction ainsi que db_is_working sont les seules fonctions <strong>de</strong> la<br />
bibliothèque d'interface <strong>de</strong> base <strong>de</strong> données qui peuvent être appelées en<br />
mo<strong>de</strong> asynchrone à l'ai<strong>de</strong> d'une zone SQLCA susceptible d'être utilisée par<br />
une autre requête.<br />
Si vous annulez une requête qui exécute une opération avec le curseur, la<br />
position du curseur est indéterminée. Vous <strong>de</strong>vez alors localiser le curseur en<br />
fonction <strong>de</strong> sa position absolue ou le refermer suite à l'annulation.<br />
void db_<strong>de</strong>lete_file(<br />
SQLCA * sqlca,<br />
char * nom_fichier );<br />
Vous <strong>de</strong>vez être connecté sous un ID utilisateur détenant les droits DBA ou<br />
REMOTE DBA (SQL Remote).<br />
La fonction db_<strong>de</strong>lete_file impose au serveur <strong>de</strong> base <strong>de</strong> données <strong>de</strong><br />
supprimer le fichier nom_fichier. Vous pouvez faire appel à cette fonction<br />
pour supprimer l'ancien journal <strong>de</strong> transactions une fois que vous l'avez<br />
sauvegardé et renommé (voir la fonction<br />
DB_BACKUP_READ_RENAME_LOG, à la section "Fonction db_backup",<br />
page 252). Vous <strong>de</strong>vez être connecté sous un ID utilisateur détenant les<br />
droits DBA.<br />
255
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
Fonction db_find_engine<br />
Syntaxe<br />
Description<br />
Fonction db_fini<br />
Syntaxe<br />
Description<br />
Voir aussi<br />
Fonction db_get_property<br />
Syntaxe<br />
256<br />
unsigned short db_find_engine(<br />
SQLCA *sqlca,<br />
char *nom );<br />
Renvoie un entier court, non signé, contenant <strong>de</strong>s informations d'état sur le<br />
serveur <strong>de</strong> base <strong>de</strong> données désigné par nom. Si aucun serveur portant le nom<br />
spécifié n'est trouvé, la valeur 0 (zéro) est renvoyée. Une valeur différente <strong>de</strong><br />
0 indique que le serveur est actif.<br />
Chaque bit <strong>de</strong> la valeur renvoyée véhicule <strong>de</strong>s informations. Les constantes<br />
qui représentent les bits <strong>de</strong>s différents éléments d'information sont définies<br />
dans le fichier d'en-tête sql<strong>de</strong>f.h. Si un pointeur NULL est spécifié pour la<br />
variable nom, <strong>de</strong>s informations sur l'environnement <strong>de</strong> la base <strong>de</strong> données par<br />
défaut sont renvoyées.<br />
unsigned short db_fini( SQLCA *sqlca );<br />
Cette fonction libère les ressources utilisées par l'interface <strong>de</strong> base <strong>de</strong><br />
données ou la DLL. Vous ne <strong>de</strong>vez pas appeler d'autres bibliothèques ni<br />
exécuter <strong>de</strong> comman<strong>de</strong>s Embed<strong>de</strong>d SQL après avoir appelé db_fini. Si une<br />
erreur se produit en cours <strong>de</strong> traitement, le co<strong>de</strong> d'erreur est défini dans la<br />
zone SQLCA et la fonction renvoie 0 (zéro). En l'absence d'erreur, c'est une<br />
valeur différente <strong>de</strong> 0 qui est renvoyée.<br />
Vous <strong>de</strong>vez appeler db_fini pour chaque zone SQLCA utilisée.<br />
Attention<br />
Sous NetWare, si db_fini n'est pas appelé pour chaque db_init, le serveur<br />
<strong>de</strong> base <strong>de</strong> données et le serveur <strong>de</strong> fichiers NetWare risquent <strong>de</strong> s'arrêter.<br />
Pour plus d’informations sur l’utilisation <strong>de</strong> la fonction db_fini dans les<br />
applications UltraLite, reportez-vous à la section "Fonction db_fini",<br />
page 246 du document UltraLite <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur.<br />
unsigned int db_get_property(<br />
SQLCA * sqlca,<br />
a_db_property property,<br />
char * value_buffer,<br />
int value_buffer_size );
Description<br />
Voir aussi<br />
Fonction db_init<br />
Syntaxe<br />
Description<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Cette fonction permet d'obtenir l'adresse du serveur auquel vous êtes<br />
connecté. Elle est employée par l'utilitaire dbping pour imprimer l'adresse du<br />
serveur.<br />
Elle peut également être utilisée pour connaître la valeur <strong>de</strong>s propriétés d'une<br />
base <strong>de</strong> données. Vous pouvez obtenir les propriétés d'une base <strong>de</strong> données<br />
sans recourir à l'interface, en exécutant une instruction SELECT ; cette<br />
opération est définie dans la section "Propriétés <strong>de</strong>s bases <strong>de</strong> données",<br />
page 674 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Les arguments sont les suivants :<br />
♦ a_db_property enum avec la valeur DB_PROP_SERVER_ADDRESS.<br />
DB_PROP_SERVER_ADDRESS permet d'obtenir, sous la forme d'une<br />
chaîne imprimable, l'adresse réseau du serveur pour la connexion en<br />
cours. Les protocoles <strong>de</strong> mémoire partagée et les protocoles Named<br />
Pipes renvoient toujours une chaîne vi<strong>de</strong> comme adresse. Les protocoles<br />
TCP/IP et SPX renvoient les adresses dans une chaîne pleine.<br />
♦ value_buffer Cet argument est renseigné avec la valeur <strong>de</strong> la propriété<br />
sous la forme d'une chaîne terminée par une valeur NULL.<br />
♦ value_buffer_size Longueur maximale <strong>de</strong> la chaîne value_buffer,<br />
incluant le caractère NULL <strong>de</strong> fin.<br />
"Propriétés <strong>de</strong>s bases <strong>de</strong> données", page 674 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration<br />
unsigned short db_init( SQLCA *sqlca );<br />
Cette fonction initialise la bibliothèque d'interface <strong>de</strong> la base <strong>de</strong> données.<br />
Cette fonction doit être appelée avant toute autre appel <strong>de</strong> bibliothèque et<br />
avant toute exécution d'une comman<strong>de</strong> Embed<strong>de</strong>d SQL. Les ressources<br />
requises par la bibliothèque d'interface pour votre programme sont allouées<br />
et initialisées lors <strong>de</strong> cet appel.<br />
Utilisez db_fini pour libérer les ressources en fin d'exécution <strong>de</strong> votre<br />
programme. En cas d'erreurs au cours du traitement, la valeur 0 (zéro) est<br />
renvoyée dans la zone SQLCA. En l'absence d'erreurs, une valeur non nulle<br />
est renvoyée et vous pouvez commencer à utiliser les comman<strong>de</strong>s et les<br />
fonctions Embed<strong>de</strong>d SQL.<br />
257
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
Voir aussi<br />
Fonction db_is_working<br />
Syntaxe<br />
Description<br />
Fonction db_locate_servers<br />
Syntaxe<br />
Description<br />
258<br />
Dans la plupart <strong>de</strong>s cas, cette fonction ne doit être appelée qu'une seule fois<br />
(afin <strong>de</strong> transmettre l'adresse <strong>de</strong> la variable globale sqlca définie dans le<br />
fichier d'en-tête sqlca.h). Si vous créez une DLL ou une application<br />
multithread à l'ai<strong>de</strong> d'Embed<strong>de</strong>d SQL, appelez db_init autant <strong>de</strong> fois qu'il y a<br />
<strong>de</strong> SQLCA.<br />
$ Pour plus d'informations, reportez-vous à la section "Gestion <strong>de</strong> la zone<br />
SQLCA pour le co<strong>de</strong> multi-thread ou réentrant", page 208.<br />
Attention<br />
Sous NetWare, si db_fini n'est pas appelé pour chaque db_init, le serveur<br />
<strong>de</strong> base <strong>de</strong> données et le serveur <strong>de</strong> fichiers NetWare risquent <strong>de</strong> s'arrêter.<br />
Pour plus d’informations sur l’utilisation <strong>de</strong> la fonction db_init dans les<br />
applications UltraLite, reportez-vous à la section "Fonction db_init",<br />
page 246 du document UltraLite <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur.<br />
unsigned db_is_working( SQLCA *sqlca );<br />
Renvoie 1 si votre application comporte une requête <strong>de</strong> base <strong>de</strong> données en<br />
cours qui utilise cette zone SQLCA, et 0 si aucune requête en cours n'utilise<br />
cette zone SQLCA.<br />
Cette fonction peut être appelée en mo<strong>de</strong> asynchrone. Cette fonction ainsi<br />
que db_cancel_request sont les seules fonctions <strong>de</strong> la bibliothèque<br />
d'interface <strong>de</strong> base <strong>de</strong> données qui peuvent être appelées en mo<strong>de</strong> asynchrone<br />
à l'ai<strong>de</strong> d'une zone SQLCA susceptible d'être utilisée par une autre requête.<br />
unsigned int db_locate_servers(<br />
SQLCA *sqlca,<br />
SQL_CALLBACK_PARM adresse_callback,<br />
void *callback_user_data );<br />
Permet un accès par voie <strong>de</strong> <strong>programmation</strong> aux informations affichées par<br />
l'utilitaire dblocate, avec la liste <strong>de</strong> tous les serveurs <strong>de</strong> base <strong>de</strong> données<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> qui, sur le réseau local, sont en réception sur<br />
TCP/IP.<br />
La fonction callback doit avoir la syntaxe suivante :
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
int (*)( SQLCA *sqlca,<br />
a_server_address *adr_serveur,<br />
void *callback_user_data);<br />
Fonction db_register_a_callback<br />
Syntaxe<br />
Description<br />
La fonction callback est appelée pour chaque serveur détecté. Si elle<br />
renvoie 0, db_locate_servers arrête l'itération entre les serveurs.<br />
Les paramètres sqlca et callback_user_data transmis à la fonction callback<br />
sont ceux qui sont transmis dans db_locate_servers. Le second paramètre<br />
est un pointeur sur une structure a_server_address. a_server_address est<br />
définie dans sqlca.h, avec la définition suivante :<br />
type<strong>de</strong>f struct a_server_address {<br />
a_SQL_uint32 type_port;<br />
a_SQL_uint32 num_port;<br />
char *nom;<br />
char *adresse;<br />
} a_server_address;<br />
♦ type_port Toujours égal à PORT_TYPE_TCP à ce moment-là (défini<br />
à 6 dans sqlca.h).<br />
♦ num_port Numéro <strong>de</strong> port TCP sur lequel le serveur est en réception.<br />
♦ nom Pointe sur un buffer contenant le nom du serveur.<br />
♦ adresse Pointe sur un buffer contenant l'adresse IP du serveur.<br />
$ Pour plus d'informations, reportez-vous à "Utilitaire <strong>de</strong> localisation <strong>de</strong><br />
serveurs", page 540 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
void db_register_a_callback(<br />
SQLCA *sqlca,<br />
a_db_callback_in<strong>de</strong>x in<strong>de</strong>x,<br />
( SQL_CALLBACK_PARM ) callback );<br />
Cette fonction enregistre les fonctions <strong>de</strong> rappel (callback).<br />
Si vous n'enregistrez aucune fonction callback DB_CALLBACK_WAIT,<br />
vous n'avez, par défaut, aucune action à entreprendre. Votre application se<br />
bloque en attendant la réponse <strong>de</strong> la base <strong>de</strong> données et Windows transforme<br />
le curseur en sablier.<br />
Pour supprimer un rappel, passez un pointeur NULL en tant que fonction<br />
callback.<br />
Les valeurs admises pour le paramètre in<strong>de</strong>x sont les suivantes :<br />
259
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
260<br />
♦ DB_CALLBACK_DEBUG_MESSAGE La fonction fournie est appelée<br />
une fois pour chaque message <strong>de</strong> débogage et elle reçoit une chaîne<br />
terminée par une valeur NULL contenant le texte du message. La chaîne<br />
contient en général un caractère <strong>de</strong> saut <strong>de</strong> ligne (\n) situé<br />
immédiatement avant le caractère NULL <strong>de</strong> fin. La syntaxe <strong>de</strong> la<br />
fonction callback est la suivante :<br />
void SQL_CALLBACK <strong>de</strong>bug_message_callback(<br />
SQLCA *sqlca,<br />
char * chaîne_message );<br />
♦ DB_CALLBACK_START La syntaxe est la suivante :<br />
void SQL_CALLBACK start_callback( SQLCA *sqlca );<br />
La fonction est appelée immédiatement avant qu'une requête <strong>de</strong> base <strong>de</strong><br />
données ne soit envoyée au serveur. DB_CALLBACK_START n'est<br />
utilisée que sous Windows 95/98, Windows NT/2000 et Windows CE.<br />
♦ DB_CALLBACK_FINISH La syntaxe est la suivante :<br />
void SQL_CALLBACK finish_callback( SQLCA * sqlca );<br />
Cette fonction est appelée après que la réponse à une requête <strong>de</strong> base <strong>de</strong><br />
données a été reçue par la DLL d'interface. DB_CALLBACK_FINISH<br />
n'est utilisée que sous les systèmes d'exploitation Windows.<br />
♦ DB_CALLBACK_CONN_DROPPED La syntaxe est la suivante :<br />
void SQL_CALLBACK conn_dropped_callback (<br />
SQLCA *sqlca,<br />
char *nom_connexion );<br />
Cette fonction est appelée lorsque le serveur <strong>de</strong> base <strong>de</strong> données est sur<br />
le point d'abandonner la connexion en raison du dépassement du délai<br />
d'inactivité, à la suite d'une instruction DROP CONNECTION ou suite à<br />
l'arrêt du serveur. Le nom <strong>de</strong> connexion nom_connexion est transmis<br />
pour vous permettre <strong>de</strong> faire la différence entre les connexions. Si la<br />
connexion n'a pas été nommée, elle a la valeur NULL.<br />
♦ DB_CALLBACK_WAIT La syntaxe est la suivante :<br />
void SQL_CALLBACK wait_callback( SQLCA *sqlca );<br />
Cette fonction est appelée très souvent par la bibliothèque d'interface<br />
pendant que le serveur <strong>de</strong> base <strong>de</strong> données ou la bibliothèque cliente<br />
traite votre requête.<br />
Vous pouvez enregistrer ce rappel (callback) comme suit :<br />
db_register_a_callback( &sqlca,<br />
DBCALLBACK_WAIT,<br />
(SQL_CALLBACK_PARM)&db_wait_request );
Fonction db_start_database<br />
Syntaxe<br />
Arguments<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ DB_CALLBACK_MESSAGE Cette fonction permet à l'application <strong>de</strong><br />
gérer les messages provenant du serveur durant le traitement d'une<br />
requête.<br />
La syntaxe se présente comme suit :<br />
void SQL_CALLBACK message_callback(<br />
SQLCA* sqlca,<br />
unsigned short msg_type,<br />
an_SQL_co<strong>de</strong> co<strong>de</strong>,<br />
unsigned length,<br />
char* msg<br />
);<br />
Le paramètre msg_type spécifie l'importance du message et les<br />
manières dont vous souhaitez gérer les différents types <strong>de</strong> message. Les<br />
types <strong>de</strong> message disponibles sont MESSAGE_TYPE_INFO,<br />
MESSAGE_TYPE_WARNING, MESSAGE_TYPE_ACTION et<br />
MESSAGE_TYPE_STATUS. Ces constantes sont définies dans<br />
sql<strong>de</strong>f.h. Le champ co<strong>de</strong> est un i<strong>de</strong>ntificateur. Le champ length indique<br />
la longueur du message. Le message ne se termine pas par une valeur<br />
NULL.<br />
Par exemple, le rappel (callback) Interactive SQL affiche les messages<br />
STATUS et INFO dans le volet Messages, tandis que <strong>de</strong>s messages <strong>de</strong><br />
type ACTION et WARNING sont présentés dans une boîte <strong>de</strong> dialogue.<br />
Si une application n'enregistre pas ce rappel, il existe un rappel par<br />
défaut qui provoque l'enregistrement <strong>de</strong> tous les messages dans le fichier<br />
<strong>de</strong> trace du serveur (si la fonction <strong>de</strong> débogage est activée et si un fichier<br />
<strong>de</strong> trace est spécifié). En outre, les messages <strong>de</strong> type<br />
MESSAGE_TYPE_WARNING et MESSAGE_TYPE_ACTION sont<br />
affichés <strong>de</strong> façon plus visible, selon les options d'affichage propres au<br />
système d'exploitation.<br />
unsigned int db_start_database( SQLCA * sqlca, char * parms );<br />
sqlca Pointeur sur une structure SQLCA. Pour plus d'informations, reportezvous<br />
à la section "Zone <strong>de</strong> communication SQL (SQLCA)", page 205.<br />
parms Chaîne terminée par la valeur NULL contenant une liste <strong>de</strong> valeurs<br />
<strong>de</strong> paramètres délimitées par points-virgules, chacune d'entre elles ayant la<br />
forme KEYWORD=valeur. Par exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"<br />
261
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
Description<br />
Fonction db_start_engine<br />
Syntaxe<br />
Arguments<br />
Description<br />
262<br />
$ Pour obtenir la liste <strong>de</strong>s paramètres <strong>de</strong> connexion, reportez-vous à la<br />
section "Paramètres <strong>de</strong> connexion", page 176 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
Démarre une base <strong>de</strong> données sur un serveur existant si cette base n'est pas<br />
déjà en cours d'exécution. Les étapes à suivre pour démarrer une base <strong>de</strong><br />
données sont décrites sous "Démarrage d'un serveur personnel", page 84 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
La valeur TRUE est renvoyée si la base <strong>de</strong> données était déjà en cours<br />
d'exécution ou si son démarrage a abouti. Les informations d'erreur sont<br />
renvoyées dans la zone SQLCA.<br />
Si un ID utilisateur et un mot <strong>de</strong> passe sont fournis dans les paramètres, ils<br />
sont ignorés.<br />
$ L'autorisation requise pour le démarrage et l'arrêt d'une base <strong>de</strong> données<br />
est définie sur la ligne <strong>de</strong> comman<strong>de</strong> du serveur. Pour plus d'informations,<br />
reportez-vous à la section "Le serveur <strong>de</strong> base <strong>de</strong> données", page 128 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
unsigned int db_start_engine( SQLCA * sqlca, char * parms );<br />
sqlca Pointeur sur une structure SQLCA. Pour plus d'informations, reportezvous<br />
à la section "Zone <strong>de</strong> communication SQL (SQLCA)", page 205.<br />
parms Chaîne terminée par la valeur NULL contenant une liste <strong>de</strong> valeurs<br />
<strong>de</strong> paramètres délimitées par points-virgules, chacune d'entre elles ayant la<br />
forme KEYWORD=valeur. Par exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"<br />
$ Pour obtenir la liste <strong>de</strong>s paramètres <strong>de</strong> connexion, reportez-vous à la<br />
section "Paramètres <strong>de</strong> connexion", page 176 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
Démarre le serveur <strong>de</strong> base <strong>de</strong> données s'il n'est pas déjà actif. Les opérations<br />
effectuées par cette fonction sont les mêmes que celles décrites dans la<br />
section "Démarrage d'un serveur personnel", page 84 du document ASA<br />
<strong>Gui<strong>de</strong></strong> d’administration.<br />
La valeur TRUE est renvoyée si le serveur est i<strong>de</strong>ntifié ou que son démarrage<br />
a abouti. Les informations d'erreur sont renvoyées dans la zone SQLCA.<br />
La fonction db_start_engine ci-après démarre le serveur <strong>de</strong> base <strong>de</strong> données<br />
qu'elle nomme asa<strong>de</strong>mo, mais la présence du paramètre <strong>de</strong> connexion DBF<br />
n'entraîne pas pour autant le chargement <strong>de</strong> la base <strong>de</strong> données :
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
db_start_engine( &sqlca, "DBF=c:\\asa8\\asa<strong>de</strong>mo.db;<br />
Start=dbeng8" );<br />
Si vous souhaitez démarrer une base <strong>de</strong> données en même temps que le<br />
serveur, vous <strong>de</strong>vez inclure le nom du fichier <strong>de</strong> base <strong>de</strong> données dans le<br />
paramètre <strong>de</strong> connexion START :<br />
db_start_engine( &sqlca,"ENG=eng_name;START=dbeng8<br />
c:\\asa\\asa<strong>de</strong>mo.db" );<br />
Cet appel démarre le serveur, le nomme eng_name et démarre la base <strong>de</strong><br />
données asa<strong>de</strong>mo sur ce serveur.<br />
La fonction db_start_engine tente d'établir une connexion avec un serveur<br />
plutôt que d'en démarrer un, afin d'éviter <strong>de</strong> démarrer un serveur déjà actif.<br />
Le paramètre <strong>de</strong> connexion FORCESTART n'est utilisé que par la fonction<br />
db_start_engine. S'il est défini à YES, aucune connexion à un serveur n'est<br />
tentée tant qu'il n'y a pas eu <strong>de</strong> tentative d'en démarrer un. Ceci permet aux<br />
<strong>de</strong>ux comman<strong>de</strong>s suivantes <strong>de</strong> fonctionner comme prévu :<br />
1 Démarrer un serveur <strong>de</strong> base <strong>de</strong> données nommé serveur_1 :<br />
start dbeng8 -n serveur_1 asa<strong>de</strong>mo.db<br />
2 Imposer le démarrage d'un nouveau serveur et établir la connexion :<br />
db_start_engine( &sqlda, "START=dbeng8 -n serveur_2 asa<strong>de</strong>mo.db;ForceStart=YES" )<br />
Fonction db_stop_database<br />
Syntaxe<br />
Arguments<br />
Description<br />
Si FORCESTART n'est pas employé et sans paramètre ENG, la secon<strong>de</strong><br />
comman<strong>de</strong> tente une connexion à serveur_1. La fonction db_start_engine<br />
ne récupère pas le nom du serveur dans l'option -n du paramètre START.<br />
unsigned int db_stop_database( SQLCA * sqlca, char * parms );<br />
sqlca Pointeur sur une structure SQLCA. Pour plus d'informations, reportezvous<br />
à la section "Zone <strong>de</strong> communication SQL (SQLCA)", page 205.<br />
parms Chaîne terminée par la valeur NULL contenant une liste <strong>de</strong> valeurs<br />
<strong>de</strong> paramètres délimitées par points-virgules, chacune d'entre elles ayant la<br />
forme KEYWORD=valeur. Par exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"<br />
$ Pour obtenir la liste <strong>de</strong>s paramètres <strong>de</strong> connexion, reportez-vous à la<br />
section "Paramètres <strong>de</strong> connexion", page 176 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
Arrête la base <strong>de</strong> données DatabaseName sur le serveur EngineName. Si le<br />
nom EngineName n'est pas spécifié, c'est le serveur par défaut qui est utilisé.<br />
263
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
Fonction db_stop_engine<br />
Syntaxe<br />
Arguments<br />
Description<br />
264<br />
Par défaut, cette fonction n'arrête pas une base <strong>de</strong> données disposant déjà <strong>de</strong><br />
connexions. Toutefois, si Unconditional a la valeur yes, la base <strong>de</strong> données<br />
est arrêtée, qu'elle ait ou non <strong>de</strong>s connexions existantes.<br />
La valeur TRUE est renvoyée si aucune erreur n'est survenue.<br />
$ L'autorisation requise pour le démarrage et l'arrêt d'une base <strong>de</strong> données<br />
est définie sur la ligne <strong>de</strong> comman<strong>de</strong> du serveur. Pour plus d'informations,<br />
reportez-vous à la section "Le serveur <strong>de</strong> base <strong>de</strong> données", page 128 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
unsigned int db_stop_engine( SQLCA * sqlca, char * parms );<br />
sqlca Pointeur sur une structure SQLCA. Pour plus d'informations, reportezvous<br />
à la section "Zone <strong>de</strong> communication SQL (SQLCA)", page 205.<br />
parms Chaîne terminée par la valeur NULL contenant une liste <strong>de</strong> valeurs<br />
<strong>de</strong> paramètres délimitées par points-virgules, chacune d'entre elles ayant la<br />
forme KEYWORD=valeur. Par exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"<br />
$ Pour obtenir la liste <strong>de</strong>s paramètres <strong>de</strong> connexion, reportez-vous à la<br />
section "Paramètres <strong>de</strong> connexion", page 176 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
Arrête le serveur <strong>de</strong> base <strong>de</strong> données. Les étapes ci-<strong>de</strong>ssous sont effectuées<br />
par cette fonction :<br />
♦ Recherche d'un serveur <strong>de</strong> base <strong>de</strong> données local dont le nom correspond<br />
au paramètre EngineName. Si ce paramètre n'est pas spécifié, recherche<br />
le serveur <strong>de</strong> base <strong>de</strong> données local par défaut.<br />
♦ Si aucun serveur n'est trouvé, la fonction échoue.<br />
♦ Envoi d'une requête au serveur lui indiquant d'effectuer un point <strong>de</strong><br />
reprise sur chaque base <strong>de</strong> données puis d'arrêter celles-ci.<br />
♦ Déchargement du serveur <strong>de</strong> base <strong>de</strong> données.<br />
Par défaut, cette fonction n'arrête pas un serveur <strong>de</strong> base <strong>de</strong> données<br />
disposant déjà <strong>de</strong> connexions. Toutefois, si Unconditional a la valeur yes, le<br />
serveur <strong>de</strong> base <strong>de</strong> données est arrêté, qu'il ait ou non <strong>de</strong>s connexions en<br />
cours.<br />
Un programme en langage C peut utiliser cette fonction au lieu <strong>de</strong> générer<br />
DBSTOP. La valeur TRUE est renvoyée si aucune erreur n'est survenue.
Fonction db_string_connect<br />
Syntaxe<br />
Arguments<br />
Description<br />
Fonction db_string_disconnect<br />
Syntaxe<br />
Arguments<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
L’utilisation <strong>de</strong> db_stop_ending est soumise aux autorisations définies dans<br />
l'option <strong>de</strong> serveur -gk.<br />
$ Pour plus d'informations, reportez-vous à la section "Option <strong>de</strong> serveur<br />
-gk", page 151 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
unsigned int db_string_connect( SQLCA * sqlca, char * parms );<br />
sqlca Pointeur sur une structure SQLCA. Pour plus d'informations, reportezvous<br />
à la section "Zone <strong>de</strong> communication SQL (SQLCA)", page 205.<br />
parms Chaîne terminée par la valeur NULL contenant une liste <strong>de</strong> valeurs<br />
<strong>de</strong> paramètres délimitées par points-virgules, chacune d'entre elles ayant la<br />
forme KEYWORD=valeur. Par exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"<br />
$ Pour obtenir la liste <strong>de</strong>s paramètres <strong>de</strong> connexion, reportez-vous à la<br />
section "Paramètres <strong>de</strong> connexion", page 176 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
Offre <strong>de</strong>s fonctionnalités supplémentaires par rapport à la comman<strong>de</strong><br />
Embed<strong>de</strong>d SQL CONNECT. Cette fonction établit une connexion en<br />
utilisant l'algorithme décrit dans la section "Résolution <strong>de</strong>s problèmes <strong>de</strong><br />
connexion", page 78 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Si l'établissement <strong>de</strong> la connexion aboutit, la valeur renvoyée est TRUE<br />
(valeur différente <strong>de</strong> 0); dans le cas contraire, la valeur <strong>de</strong> retour est FALSE<br />
(valeur différente <strong>de</strong> 0). Les informations d'erreur relatives au démarrage du<br />
serveur ou <strong>de</strong> la base <strong>de</strong> données, ou celles relatives à la connexion sont<br />
renvoyées dans la zone SQLCA.<br />
unsigned int db_string_disconnect( SQLCA * sqlca, char * parms );<br />
sqlca Pointeur sur une structure SQLCA. Pour plus d'informations, reportezvous<br />
à la section "Zone <strong>de</strong> communication SQL (SQLCA)", page 205.<br />
parms Chaîne terminée par la valeur NULL contenant une liste <strong>de</strong> valeurs<br />
<strong>de</strong> paramètres délimitées par points-virgules, chacune d'entre elles ayant la<br />
forme KEYWORD=valeur. Par exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"<br />
265
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
Description<br />
Fonction db_string_ping_server<br />
Syntaxe<br />
Description<br />
Fonction fill_s_sqlda<br />
Syntaxe<br />
266<br />
$ Pour obtenir la liste <strong>de</strong>s paramètres <strong>de</strong> connexion, reportez-vous à la<br />
section "Paramètres <strong>de</strong> connexion", page 176 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
Cette fonction met fin à la connexion i<strong>de</strong>ntifiée par le paramètre<br />
ConnectionName. Tous les autres paramètres sont ignorés.<br />
Si aucun paramètre ConnectionName n'est spécifié dans la chaîne, la<br />
connexion non nommée est interrompue. Cette fonction est l'équivalent <strong>de</strong> la<br />
comman<strong>de</strong> Embed<strong>de</strong>d SQL DISCONNECT. Si une connexion est<br />
effectivement interrompue, la valeur booléenne renvoyée est TRUE. Les<br />
informations d'erreur sont renvoyées dans la zone SQLCA.<br />
Cette fonction arrête la base <strong>de</strong> données si celle-ci a été démarrée avec<br />
AutoStop=yes et qu'aucune autre connexion à cette base n'a été établie. Elle<br />
arrête également le moteur si celui-ci a été démarré avec AutoStop=yes et<br />
qu'aucune autre base n'est en cours d'exécution.<br />
unsigned int db_string_ping_server(<br />
SQLCA * sqlca,<br />
char * chaîne_connexion,<br />
unsigned int connexion_à_bd );<br />
chaîne_connexion est une chaîne <strong>de</strong> connexion normale qui peut contenir ou<br />
non <strong>de</strong>s informations sur le serveur et la base <strong>de</strong> données.<br />
Si connexion_à_bd est différent <strong>de</strong> zéro (TRUE), la fonction tente une<br />
connexion à une base <strong>de</strong> données sur un serveur. Elle renvoie une valeur<br />
différente <strong>de</strong> zéro (TRUE) uniquement si la chaîne <strong>de</strong> connexion suffit pour<br />
établir la connexion à la base <strong>de</strong> données nommée sur le serveur nommé.<br />
Si connexion_à_bd a la valeur zéro, la fonction tente uniquement <strong>de</strong> localiser<br />
un serveur. Elle renvoie une valeur différente <strong>de</strong> zéro uniquement si la chaîne<br />
<strong>de</strong> connexion permet <strong>de</strong> localiser un serveur. Elle ne tente pas d'établir la<br />
connexion avec la base.<br />
struct sqlda * fill_s_sqlda(<br />
struct sqlda * sqlda,<br />
unsigned int maxlen );
Description<br />
Fonction fill_sqlda<br />
Syntaxe<br />
Description<br />
Fonction free_filled_sqlda<br />
Syntaxe<br />
Description<br />
Fonction free_sqlda<br />
Syntaxe<br />
Description<br />
Fonction free_sqlda_noind<br />
Syntaxe<br />
Description<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Semblable pour l'essentiel à fill_sqlda, mais convertit tous les types <strong>de</strong><br />
données <strong>de</strong> sqlda en DT_STRING. La conversion requiert l'allocation d'un<br />
espace suffisant, l'espace maximal étant <strong>de</strong> maxlen octets. Les champs<br />
"longueur" <strong>de</strong> la zone SQLDA (sqllen) sont modifiés en conséquence.<br />
Renvoie sqlda en cas <strong>de</strong> succès et le pointeur NULL, si la mémoire<br />
disponible est insuffisante.<br />
struct sqlda * fill_sqlda( struct sqlda * sqlda );<br />
Alloue <strong>de</strong> l'espace à chaque variable décrite dans chaque <strong>de</strong>scripteur <strong>de</strong> sqlda<br />
et affecte l'adresse <strong>de</strong> cette mémoire au champ sqldata du <strong>de</strong>scripteur<br />
correspondant. Un espace suffisant est alloué au type <strong>de</strong> base <strong>de</strong> données et à<br />
la longueur indiqués dans ce <strong>de</strong>scripteur. Renvoie sqlda en cas <strong>de</strong> succès et<br />
le pointeur NULL, si la mémoire disponible est insuffisante.<br />
void free_filled_sqlda( struct sqlda * sqlda );<br />
Libère la mémoire allouée à chaque pointeur sqldata, ainsi que l'espace<br />
alloué à la zone SQLDA. Les pointeurs NULL ne sont pas libérés.<br />
L'appel <strong>de</strong> cette fonction provoque l'appel automatique <strong>de</strong> free_sqlda <strong>de</strong><br />
sorte que les <strong>de</strong>scripteurs alloués par alloc_sqlda sont libérés.<br />
void free_sqlda( struct sqlda * sqlda );<br />
Libère l'espace alloué à cette zone sqlda, et libère l'espace <strong>de</strong> la variable<br />
indicateur qui avait été alloué dans fill_sqlda. Ne libère pas la mémoire<br />
référencée par chaque pointeur sqldata.<br />
void free_sqlda_noind( struct sqlda * sqlda );<br />
Libère l'espace alloué à cette zone sqlda. Ne libère pas la mémoire référencée<br />
par chaque pointeur sqldata. Les pointeurs <strong>de</strong> variable indicateur sont<br />
ignorés.<br />
267
Références <strong>de</strong>s fonctions <strong>de</strong> bibliothèque<br />
Fonction sql_needs_quotes<br />
Syntaxe<br />
Description<br />
Fonction sqlda_storage<br />
Syntaxe<br />
Description<br />
Fonction sqlda_string_length<br />
Syntaxe<br />
Description<br />
Fonction sqlerror_message<br />
Syntaxe<br />
268<br />
"Propriétés <strong>de</strong>s bases <strong>de</strong> données", page 674 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration<br />
"Utilitaire Ping", page 536 du document ASA <strong>Gui<strong>de</strong></strong> d’administration<br />
unsigned int sql_needs_quotes( SQLCA *sqlca, char *str );<br />
Renvoie une valeur booléenne indiquant si la chaîne doit être ou non<br />
encadrée par <strong>de</strong>s guillemets lorsqu'elle est utilisée en tant qu'i<strong>de</strong>ntificateur<br />
SQL. Cette fonction adresse une requête au serveur <strong>de</strong> base <strong>de</strong> données pour<br />
déterminer si les guillemets sont nécessaires. Les informations pertinentes<br />
sont stockées dans le champ sqlco<strong>de</strong>.<br />
Il existe trois combinaisons <strong>de</strong> valeur/co<strong>de</strong> <strong>de</strong> retour :<br />
♦ valeur renvoyée = FALSE, sqlco<strong>de</strong> = 0 Dans ce cas, la chaîne n'a pas<br />
besoin <strong>de</strong> guillemets.<br />
♦ valeur renvoyée = TRUE Ici, sqlco<strong>de</strong> est toujours SQLE_WARNING et<br />
la chaîne requiert <strong>de</strong>s guillemets.<br />
♦ valeur renvoyée = FALSE Si sqlco<strong>de</strong> n’est pas SQLE_WARNING, le<br />
test n’est pas concluant.<br />
unsigned long sqlda_storage( struct sqlda *sqlda, int varno );<br />
Renvoie la quantité <strong>de</strong> mémoire requise pour enregistrer une valeur, quelle<br />
qu'elle soit, <strong>de</strong> la variable décrite dans sqlda->sqlvar[varno].<br />
unsigned long sqlda_string_length( SQLDA *sqlda, int varno );<br />
Renvoie la longueur <strong>de</strong> la chaîne en langage C (<strong>de</strong> type DT_STRING)<br />
requise pour contenir la variable sqlda->sqlvar[varno] (quel que soit son<br />
type).<br />
char *sqlerror_message( SQLCA *sqlca, char * buffer, int max );
Description<br />
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
Renvoie un pointeur sur une chaîne contenant un message d'erreur. Ce<br />
<strong>de</strong>rnier contient le texte du co<strong>de</strong> d'erreur <strong>de</strong> la zone SQLCA. Si aucune<br />
erreur n'a été détectée, un pointeur NULL est renvoyé. Le message d'erreur<br />
est placé dans le buffer fourni, tronqué (si nécessaire) à la longueur max.<br />
269
Récapitulatif <strong>de</strong>s comman<strong>de</strong>s Embed<strong>de</strong>d SQL<br />
Récapitulatif <strong>de</strong>s comman<strong>de</strong>s Embed<strong>de</strong>d SQL<br />
270<br />
EXEC SQL<br />
TOUTES les instructions Embed<strong>de</strong>d SQL doivent être précédées<br />
d'EXEC SQL et se terminer par un point-virgule (;).<br />
Il existe <strong>de</strong>ux groupes <strong>de</strong> comman<strong>de</strong>s Embed<strong>de</strong>d SQL. Les comman<strong>de</strong>s SQL<br />
standard s'utilisent comme suit : il suffit <strong>de</strong> les placer dans un programme en<br />
langage C, en les faisant précé<strong>de</strong>r d'EXEC SQL et suivre d'un pointvirgule<br />
(;). Les instructions CONNECT, DELETE, SELECT, SET et<br />
UPDATE possè<strong>de</strong>nt d'autres formats qui ne sont disponibles qu'avec<br />
Embed<strong>de</strong>d SQL. Ces formats appartiennent à la secon<strong>de</strong> catégorie, celle <strong>de</strong>s<br />
comman<strong>de</strong>s Embed<strong>de</strong>d SQL spécifiques.<br />
$ Pour plus d'informations sur les comman<strong>de</strong>s SQL standard, reportezvous<br />
à la section "Instructions SQL", page 209 du document ASA Manuel <strong>de</strong><br />
référence SQL.<br />
Plusieurs comman<strong>de</strong>s SQL sont spécifiques d'Embed<strong>de</strong>d SQL et peuvent<br />
seulement être utilisées dans les programmes en langage C.<br />
$ Pour plus d'informations sur ces comman<strong>de</strong>s Embed<strong>de</strong>d SQL, reportezvous<br />
à la section "Eléments <strong>de</strong> langage SQL", page 3 du document ASA<br />
Manuel <strong>de</strong> référence SQL.<br />
Les instructions <strong>de</strong> manipulation et <strong>de</strong> définition <strong>de</strong> données standard<br />
peuvent être utilisées à partir <strong>de</strong>s applications Embed<strong>de</strong>d SQL. En outre, les<br />
instructions suivantes sont conçues spécifiquement pour la <strong>programmation</strong><br />
Embed<strong>de</strong>d SQL :<br />
♦ ALLOCATE DESCRIPTOR Alloue <strong>de</strong> la mémoire pour un <strong>de</strong>scripteur.<br />
$ Voir "Instruction ALLOCATE DESCRIPTOR [ESQL]", page 214<br />
du document ASA Manuel <strong>de</strong> référence SQL<br />
♦ CLOSE Ferme un curseur.<br />
$ Voir "Instruction CLOSE [ESQL] [SP]", page 276 du document<br />
ASA Manuel <strong>de</strong> référence SQL<br />
♦ CONNECT Etablit une connexion à la base <strong>de</strong> données.<br />
$ Voir "Instruction CONNECT [ESQL] [Interactive SQL]", page 283<br />
du document ASA Manuel <strong>de</strong> référence SQL<br />
♦ DEALLOCATE DESCRIPTOR Récupère la mémoire d'un <strong>de</strong>scripteur.<br />
$ Voir "Instruction DEALLOCATE DESCRIPTOR [ESQL]",<br />
page 398 du document ASA Manuel <strong>de</strong> référence SQL
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ DECLARATION SECTION Déclare <strong>de</strong>s variables hôte pour<br />
communiquer avec la base <strong>de</strong> données.<br />
$ Voir "Section <strong>de</strong> déclaration [ESQL]", page 399 du document ASA<br />
Manuel <strong>de</strong> référence SQL<br />
♦ DECLARE CURSOR Déclare un curseur.<br />
$ Voir "Instruction DECLARE CURSOR [ESQL] [SP]", page 401<br />
du document ASA Manuel <strong>de</strong> référence SQL<br />
♦ DELETE (positionné) Supprime la ligne à la position courante dans un<br />
curseur.<br />
$ Voir "Instruction DELETE (positionnée) [ESQL] [SP]", page 412<br />
du document ASA Manuel <strong>de</strong> référence SQL<br />
♦ DESCRIBE Décrit les variables hôte pour une instruction SQL donnée.<br />
$ Voir "Instruction DESCRIBE [ESQL]", page 414 du document<br />
ASA Manuel <strong>de</strong> référence SQL<br />
♦ DISCONNECT Interrompt la connexion avec le serveur <strong>de</strong> base <strong>de</strong><br />
données.<br />
$ Voir "Instruction DISCONNECT [ESQL] [Interactive SQL]",<br />
page 418 du document ASA Manuel <strong>de</strong> référence SQL<br />
♦ DROP STATEMENT Libère les ressources utilisées par une instruction<br />
préparée.<br />
$ Voir "Instruction DROP STATEMENT [ESQL]", page 427 du<br />
document ASA Manuel <strong>de</strong> référence SQL<br />
♦ EXECUTE Exécute une instruction SQL donnée.<br />
$ Voir "Instruction EXECUTE [ESQL]", page 437 du document ASA<br />
Manuel <strong>de</strong> référence SQL<br />
♦ EXPLAIN Explique la stratégie d'optimisation associée à un curseur<br />
donné.<br />
$ Voir "Instruction EXPLAIN [ESQL]", page 444 du document ASA<br />
Manuel <strong>de</strong> référence SQL<br />
♦ FETCH Extrait une ligne d’un curseur.<br />
$ Voir "Instruction FETCH [ESQL] [SP]", page 446 du document<br />
ASA Manuel <strong>de</strong> référence SQL<br />
♦ GET DATA Extrait les valeurs longues d’un curseur<br />
$ Voir "Instruction GET DATA [ESQL]", page 459 du document<br />
ASA Manuel <strong>de</strong> référence SQL<br />
271
Récapitulatif <strong>de</strong>s comman<strong>de</strong>s Embed<strong>de</strong>d SQL<br />
272<br />
♦ GET DESCRIPTOR Extrait les informations sur une variables dans une<br />
zone SQLDA.<br />
$ Voir "Instruction GET DESCRIPTOR [ESQL]", page 461 du<br />
document ASA Manuel <strong>de</strong> référence SQL<br />
♦ GET OPTION Obtient la définition d'une option <strong>de</strong> base <strong>de</strong> données<br />
particulière.<br />
$ Voir "Instruction GET OPTION [ESQL]", page 463 du document<br />
ASA Manuel <strong>de</strong> référence SQL<br />
♦ INCLUDE Inclut un fichier pour un prétraitement SQL.<br />
$ Voir "Instruction INCLUDE [ESQL]", page 481 du document ASA<br />
Manuel <strong>de</strong> référence SQL<br />
♦ OPEN Ouvre un curseur.<br />
$ Voir "Instruction OPEN [ESQL] [SP]", page 508 du document ASA<br />
Manuel <strong>de</strong> référence SQL<br />
♦ PREPARE Prépare une instruction SQL donnée.<br />
$ Voir "Instruction PREPARE [ESQL]", page 518 du document ASA<br />
Manuel <strong>de</strong> référence SQL<br />
♦ PUT Insère une ligne dans un curseur.<br />
$ Voir "Instruction PUT [ESQL]", page 523 du document ASA<br />
Manuel <strong>de</strong> référence SQL<br />
♦ SET CONNECTION Change la connexion active.<br />
$ Voir "Instruction SET CONNECTION [Interactive SQL] [ESQL]",<br />
page 563 du document ASA Manuel <strong>de</strong> référence SQL<br />
♦ SET DESCRIPTOR Décrit les variables d'une zone SQLDA et place les<br />
données dans cette zone<br />
$ Voir "Instruction SET DESCRIPTOR [ESQL]", page 564 du<br />
document ASA Manuel <strong>de</strong> référence SQL<br />
♦ SET SQLCA Utilise une zone SQLCA autre que la zone globale par<br />
défaut.<br />
$ Voir "Instruction SET SQLCA [ESQL]", page 572 du document<br />
ASA Manuel <strong>de</strong> référence SQL<br />
♦ UPDATE (positionné) Met à jour la ligne à la position courante dans un<br />
curseur.<br />
$ Voir "Instruction UPDATE (positionnée) [ESQL] [SP]", page 609<br />
du document ASA Manuel <strong>de</strong> référence SQL
Chapitre 6 Programmation avec Embed<strong>de</strong>d SQL<br />
♦ WHENEVER Spécifie les actions à exécuter en cas d'erreur dans <strong>de</strong>s<br />
instructions SQL.<br />
$ Voir "Instruction WHENEVER [ESQL]", page 618 du document<br />
ASA Manuel <strong>de</strong> référence SQL<br />
273
Récapitulatif <strong>de</strong>s comman<strong>de</strong>s Embed<strong>de</strong>d SQL<br />
274
CHAPITRE 7<br />
Programmation avec ODBC<br />
Présentation<br />
Sommaire<br />
Ce chapitre présente <strong>de</strong>s informations relatives au développement<br />
d'applications faisant directement appel à l'interface <strong>de</strong> <strong>programmation</strong><br />
ODBC.<br />
La documentation principale pour le développement d'applications ODBC<br />
s'intitule Microsoft ODBC SDK documentation ; elle fait partie du SDK<br />
Microsoft Data Access Components (MDAC). Ce chapitre fournit une<br />
présentation et décrit <strong>de</strong>s fonctions spécifiques d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>,<br />
mais n'est en aucun cas un gui<strong>de</strong> exhaustif <strong>de</strong> la <strong>programmation</strong><br />
d'applications ODBC.<br />
Certains outils <strong>de</strong> développement d'applications offrant déjà le support<br />
ODBC disposent <strong>de</strong> leur propre interface <strong>de</strong> <strong>programmation</strong> qui masque<br />
l'interface ODBC. Ce chapitre n'est pas <strong>de</strong>stiné aux utilisateurs <strong>de</strong> ces types<br />
d'outil.<br />
Sujet Page<br />
Présentation d'ODBC 276<br />
Création d'applications ODBC 278<br />
Exemples ODBC 283<br />
Descripteurs ODBC 285<br />
Connexion à une source <strong>de</strong> données 288<br />
Exécution d'instructions SQL 292<br />
Jeux <strong>de</strong> résultats 297<br />
Appel <strong>de</strong> procédures stockées 302<br />
Gestion <strong>de</strong>s erreurs 304<br />
275
Présentation d'ODBC<br />
Présentation d'ODBC<br />
Plates-formes<br />
supportées<br />
Conformité à ODBC<br />
Niveaux <strong>de</strong> support<br />
ODBC<br />
Fonctionnalités<br />
supportées par<br />
<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong><br />
276<br />
L’interface ODBC (Open Database Connectivity) est une interface <strong>de</strong><br />
<strong>programmation</strong> d'applications définie par Microsoft Corporation comme<br />
interface standard pour les systèmes <strong>de</strong> gestion <strong>de</strong> bases <strong>de</strong> données dans les<br />
environnements Windows. ODBC est une interface basée sur les appels.<br />
Pour écrire <strong>de</strong>s applications ODBC pour <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, vous<br />
<strong>de</strong>vez disposer <strong>de</strong>s éléments suivants :<br />
♦ <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
♦ Compilateur en langage C capable <strong>de</strong> créer <strong>de</strong>s programmes pour votre<br />
environnement.<br />
♦ SDK (Kit <strong>de</strong> développement logiciel) ODBC <strong>de</strong> Microsoft. Celui-ci est<br />
disponible sur le Microsoft Developer Network ; il fournit <strong>de</strong>s éléments<br />
<strong>de</strong> documentation et <strong>de</strong>s outils complémentaires pour tester les<br />
applications ODBC.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte l'API ODBC sous UNIX et<br />
Windows CE, en plus <strong>de</strong>s environnements Windows. Le support multiplateforme<br />
ODBC facilite le développement d'applications <strong>de</strong> base <strong>de</strong> données<br />
portables.<br />
$ Pour plus d'informations sur l'inscription du pilote ODBC dans <strong>de</strong>s<br />
transactions distribuées, reportez-vous à la section "Transactions distribuées<br />
et architecture à trois niveaux", page 393.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte ODBC 3.52.<br />
Les fonctionnalités ODBC sont classées selon leur niveau <strong>de</strong> conformité.<br />
Elles peuvent être basiques, <strong>de</strong> niveau 1 ou <strong>de</strong> niveau 2, ce <strong>de</strong>rnier niveau<br />
<strong>de</strong> support ODBC étant le plus complet. Ces fonctionnalités sont répertoriées<br />
dans le document ODBC Programmer’s Reference, disponible auprès <strong>de</strong><br />
Microsoft Corporation dans le cadre du kit <strong>de</strong> développement logiciel<br />
ODBC, ou sur le site Web <strong>de</strong> Microsoft à l'adresse suivante :<br />
http://msdn.microsoft.com/library/<strong>de</strong>fault.asp?url=/library/enus/odbc/htm/odbcabout_this_manual.asp.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte la spécification ODBC 3.52.<br />
♦ Conformité basique <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte toutes les<br />
fonctionnalités du niveau principal.
Compatibilité<br />
ODBC<br />
<strong>de</strong>scendante<br />
Gestionnaire <strong>de</strong><br />
pilotes ODBC<br />
Chapitre 7 Programmation avec ODBC<br />
♦ Conformité <strong>de</strong> niveau 1 <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte toutes les<br />
fonctionnalités du niveau 1, à l'exception <strong>de</strong> l'exécution asynchrone <strong>de</strong>s<br />
fonctions ODBC.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte les threads multiples partageant une<br />
connexion unique. Les <strong>de</strong>man<strong>de</strong>s issues <strong>de</strong>s différents threads sont<br />
sérialisées par <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
♦ Conformité <strong>de</strong> niveau 2 <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte toutes les<br />
fonctionnalités du niveau 2, à l'exception <strong>de</strong>s suivantes :<br />
♦ Noms en trois parties <strong>de</strong>s tables et vues. Cela n'est pas applicable<br />
pour <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
♦ Exécution asynchrone <strong>de</strong> fonctions ODBC pour certaines<br />
instructions individuelles spécifiées.<br />
♦ Capacité <strong>de</strong> temporiser les <strong>de</strong>man<strong>de</strong>s <strong>de</strong> login et les requêtes SQL.<br />
Les applications développées avec d'anciennes versions d'ODBC<br />
continueront <strong>de</strong> fonctionner avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> et un<br />
gestionnaire <strong>de</strong> pilotes ODBC récent. Les nouvelles fonctionnalités ODBC<br />
ne sont pas disponibles pour les anciennes applications.<br />
Le gestionnaire <strong>de</strong> pilotes ODBC fait partie <strong>de</strong>s éléments logiciels ODBC<br />
fournis avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Le gestionnaire <strong>de</strong> pilotes ODBC<br />
version 3 dispose d'une nouvelle interface <strong>de</strong> configuration <strong>de</strong>s sources <strong>de</strong><br />
données ODBC.<br />
277
Création d'applications ODBC<br />
Création d'applications ODBC<br />
278<br />
Cette section explique comment compiler et lier <strong>de</strong>s applications ODBC<br />
simples.<br />
Inclusion du fichier d'en-tête ODBC<br />
Tout fichier source en langage C faisant appel à <strong>de</strong>s fonctions ODBC doit<br />
inclure un fichier d'en-tête ODBC spécifique <strong>de</strong> la plate-forme. Tous les<br />
fichiers d'en-tête spécifiques d'une plate-forme comprennent le fichier d'entête<br />
principal ODBC, odbc.h, qui définit toutes les fonctions, tous les types<br />
<strong>de</strong> données et toutes les définitions <strong>de</strong> constantes nécessaires pour l'écriture<br />
d'un programme ODBC.<br />
v Pour inclure le fichier d'en-tête ODBC dans un fichier source en<br />
langage C :<br />
1 Ajoutez une ligne d'inclusion qui référence dans le fichier source le<br />
fichier d'en-tête approprié spécifique <strong>de</strong> la plate-forme. Les lignes à<br />
utiliser sont les suivantes :<br />
Système d'exploitation Ligne d'inclusion<br />
Windows #inclu<strong>de</strong> "ntodbc.h"<br />
UNIX #inclu<strong>de</strong> "unixodbc.h"<br />
Windows CE #inclu<strong>de</strong> "ntodbc.h"<br />
2 Ajoutez dans le chemin d'inclusion <strong>de</strong> votre compilateur le répertoire<br />
contenant le fichier d'en-tête.<br />
Les fichiers d'en-tête spécifiques <strong>de</strong> la plate-forme et le fichier odbc.h<br />
sont installés dans le sous-répertoire h du répertoire SQL <strong>Anywhere</strong>.<br />
Liaison d’applications ODBC sous Windows<br />
Cette section ne s'applique pas à Windows CE. Pour plus d'informations,<br />
reportez-vous à la section "Liaison d'applications ODBC sous Windows CE",<br />
page 279.
Chapitre 7 Programmation avec ODBC<br />
Lorsque vous liez votre application, vous <strong>de</strong>vez la lier au fichier <strong>de</strong><br />
bibliothèque d'importation approprié afin d'avoir accès aux fonctions ODBC.<br />
La bibliothèque d'importation définit les points d'entrée pour le gestionnaire<br />
<strong>de</strong> pilotes ODBC odbc32.dll. A son tour, le gestionnaire <strong>de</strong> pilote charge le<br />
pilote ODBC dbodbc8.dll d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Des bibliothèques d'importation séparées sont fournies pour les compilateurs<br />
Microsoft, Watcom et Borland.<br />
v Pour lier une application ODBC sous Windows :<br />
♦ Ajoutez dans la liste <strong>de</strong>s répertoires <strong>de</strong> bibliothèque le répertoire<br />
contenant la bibliothèque d'importation spécifique <strong>de</strong> la plate-forme.<br />
Les bibliothèques d'importation sont stockées dans le sous-répertoire lib<br />
du répertoire contenant les fichiers exécutables<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> et sont nommées comme suit :<br />
Système<br />
d'exploitation<br />
Compilateur Bibliothèque d'importation<br />
Windows Microsoft odbc32.lib<br />
Windows Watcom<br />
C/C++<br />
wodbc32.lib<br />
Windows Borland bodbc32.lib<br />
Windows CE Microsoft dbodbc8.lib<br />
Liaison d’applications ODBC sous Windows CE<br />
Les systèmes d'exploitation Windows CE ne comportent pas <strong>de</strong> gestionnaire<br />
<strong>de</strong> pilotes ODBC. La bibliothèque d'importation (dbodbc8.lib) définit les<br />
points d'entrée directement dans le pilote ODBC dbodbc8.dll<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Des versions distinctes <strong>de</strong> cette DLL sont fournies pour les différentes puces<br />
avec lesquelles Windows CE fonctionne. Ces fichiers se trouvent dans les<br />
sous-répertoires spécifiques du système d'exploitation, situés eux-mêmes<br />
dans le sous-répertoire ce du répertoire SQL <strong>Anywhere</strong>. Par exemple, le<br />
pilote ODBC pour Windows CE sur la puce SH3 se trouve à l'emplacement<br />
suivant :<br />
C:\Program Files\<strong>Sybase</strong>\SQL <strong>Anywhere</strong> 8\ce\SH3<br />
$ Pour obtenir la liste <strong>de</strong>s versions supportées <strong>de</strong> Windows CE, reportezvous<br />
au chapitre "Systèmes d'exploitation supportés par <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>", page 146 du document Présentation <strong>de</strong> SQL <strong>Anywhere</strong> Studio.<br />
279
Création d'applications ODBC<br />
Windows CE et<br />
Unico<strong>de</strong><br />
280<br />
v Pour lier une application ODBC sous Windows CE :<br />
1 Ajoutez dans la liste <strong>de</strong>s répertoires <strong>de</strong> bibliothèque le répertoire<br />
contenant la bibliothèque d'importation spécifique <strong>de</strong> la plate-forme.<br />
La bibliothèque d'importation est nommée dbodbc8.lib et se trouve dans<br />
un sous-répertoire spécifique du système d'exploitation, se trouvant luimême<br />
dans le sous-répertoire ce du répertoire SQL <strong>Anywhere</strong>. Par<br />
exemple, la bibliothèque d'importation pour Windows CE sur la<br />
puce SH3 se trouve à l'emplacement suivant :<br />
C:\Program Files\<strong>Sybase</strong>\SQL <strong>Anywhere</strong> 8\ce\SH3\lib<br />
2 Spécifiez le paramètre DRIVER= dans la chaîne <strong>de</strong> connexion fournie<br />
pour la fonction SQLDriverConnect.<br />
szConnStrIn =<br />
"driver=chemin_se/dbodbc8.dll;dbf=c:\asa<strong>de</strong>mo.db"<br />
chemin_se correspondant au chemin complet d'accès au sous-répertoire<br />
spécifique <strong>de</strong> la puce, se trouvant lui-même dans le répertoire<br />
SQL <strong>Anywhere</strong> sur le périphérique Windows CE. Par exemple :<br />
\Program Files\<strong>Sybase</strong>\SQL <strong>Anywhere</strong> 8\ce\SH3\lib<br />
Le programme exemple (odbc.c) utilise un fichier source <strong>de</strong> données<br />
(paramètre <strong>de</strong> connexion FileDSN) appelé ASA 8.0 Sample.dsn. Vous<br />
pouvez créer <strong>de</strong>s fichiers source <strong>de</strong> données sur votre système <strong>de</strong> bureau à<br />
partir du gestionnaire <strong>de</strong> pilotes ODBC puis les copier sur votre périphérique<br />
Windows CE.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> utilise UTF-8, qui est un système <strong>de</strong> codage <strong>de</strong>s<br />
caractères sur plusieurs octets, compatible avec Unico<strong>de</strong>.<br />
Le pilote ODBC d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte <strong>de</strong>s chaînes ASCII<br />
(8 bits) ou <strong>de</strong>s chaînes Unico<strong>de</strong> (caractères étendus). La macro UNICODE<br />
contrôle si les fonctions ODBC atten<strong>de</strong>nt <strong>de</strong>s chaînes ASCII ou Unico<strong>de</strong>. Si<br />
votre application doit être créée avec la macro UNICODE définie mais que<br />
vous vouliez utiliser les fonctions ODBC ASCII, la macro<br />
SQL_NOUNICODEMAP doit également être définie.<br />
Le fichier exemple Samples\ASA\C\odbc.c explique comment utiliser les<br />
fonctionnalités ODBC Unico<strong>de</strong>.<br />
Liaison d’applications ODBC sous UNIX<br />
Aucun gestionnaire <strong>de</strong> pilotes ODBC n'est fourni avec<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, mais <strong>de</strong>s gestionnaires tiers sont disponibles.<br />
Cette section explique comment créer <strong>de</strong>s applications ODBC qui n'utilisent<br />
pas un gestionnaire <strong>de</strong> pilotes ODBC.
Pilote ODBC<br />
Informations sur<br />
les sources <strong>de</strong><br />
données<br />
Chapitre 7 Programmation avec ODBC<br />
Le pilote ODBC est un objet partagé ou une bibliothèque partagée. Des<br />
versions distinctes du pilote ODBC d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> sont<br />
fournies pour <strong>de</strong>s applications à threads uniques ou multiples.<br />
Les pilotes ODBC sont les fichiers suivants :<br />
Système<br />
d'exploitation<br />
Modèle <strong>de</strong> thread Pilote ODBC<br />
Solaris/Sparc Thread unique dbodbc8.so (dbodbc8.so.1)<br />
Solaris/Sparc Threads multiples dbodbc_r.so (dbodbc_r.so.1)<br />
Les bibliothèques sont installées en tant que liens symboliques à la<br />
bibliothèque partagée avec un numéro <strong>de</strong> version (entre parenthèses).<br />
v Pour lier une application ODBC sous UNIX :<br />
1 Liez votre application directement au pilote ODBC approprié.<br />
2 Lorsque vous déployez votre application, assurez-vous que le<br />
pilote ODBC approprié est disponible dans le chemin <strong>de</strong> bibliothèque <strong>de</strong><br />
l'utilisateur.<br />
Si <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> ne détecte aucun gestionnaire <strong>de</strong> pilotes<br />
ODBC, il utilise ~/.odbc.ini pour avoir <strong>de</strong>s informations sur les sources <strong>de</strong><br />
données.<br />
Utilisation d’un gestionnaire <strong>de</strong> pilotes ODBC sous UNIX<br />
Il existe <strong>de</strong>s gestionnaires <strong>de</strong> pilotes ODBC tiers pour UNIX. Un<br />
gestionnaire <strong>de</strong> pilotes ODBC comprend les fichiers suivants :<br />
Système<br />
d'exploitation<br />
Fichiers<br />
Solaris/Sparc libodbc.so (libodbc.so.1)<br />
libodbcinst.so (libodbcinst.so.1)<br />
Solaris/Sparc libodbc.so (libodbc.so.1)<br />
libodbcinst.so (libodbcinst.so.1)<br />
Si vous déployez une application qui nécessite un gestionnaire <strong>de</strong> pilotes<br />
ODBC et que vous n'utilisez pas un gestionnaire <strong>de</strong> pilotes tiers, créez <strong>de</strong>s<br />
liens symboliques entre les bibliothèques partagées libodbc et libodbcinst et le<br />
pilote ODBC d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
281
Création d'applications ODBC<br />
282<br />
S’il existe un gestionnaire <strong>de</strong> pilotes ODBC, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
l'interroge plutôt que ~/.odbc.ini pour obtenir <strong>de</strong>s informations sur les sources<br />
<strong>de</strong> données.<br />
Les applications ODBC standard ne se lient pas directement au pilote<br />
ODBC. En fait, les appels <strong>de</strong> fonctions ODBC s'effectuent par l'intermédiaire<br />
du gestionnaire <strong>de</strong> pilotes ODBC. Sous UNIX et Windows CE,<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> n'inclut pas <strong>de</strong> gestionnaire <strong>de</strong> pilotes ODBC.<br />
Vous pouvez toujours créer <strong>de</strong>s applications ODBC en les liant directement<br />
au gestionnaire <strong>de</strong> pilotes <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, mais vous ne pourrez<br />
ensuite accé<strong>de</strong>r qu'aux sources <strong>de</strong> données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.
Exemples ODBC<br />
Chapitre 7 Programmation avec ODBC<br />
Plusieurs exemples ODBC sont fournis avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Vous les trouverez dans le sous-répertoire Samples\ASA du répertoire<br />
SQL <strong>Anywhere</strong>. Le chemin d'accès par défaut est :<br />
C:\Program Files\<strong>Sybase</strong>\SQL <strong>Anywhere</strong> 8\Samples\ASA<br />
Les exemples dans les répertoires commençant par ODBC illustrent <strong>de</strong>s<br />
tâches ODBC distinctes et simples, notamment la connexion à une base <strong>de</strong><br />
données et l'exécution d'instructions. Un programme exemple ODBC est<br />
fourni dans le fichier Samples\ASA\C\odbc.c. Ce programme exécute les<br />
mêmes actions que le programme exemple <strong>de</strong> curseur dynamique<br />
Embed<strong>de</strong>d SQL qui se trouve dans le même répertoire.<br />
$ Pour obtenir la <strong>de</strong>scription du programme Embed<strong>de</strong>d SQL associé,<br />
reportez-vous à la section "Exemples <strong>de</strong> programmes Embed<strong>de</strong>d SQL",<br />
page 186.<br />
Création du programme exemple ODBC<br />
Le programme exemple ODBC dans Samples\ASA\C inclut un fichier batch<br />
(script shell pour UNIX) qui permet <strong>de</strong> compiler et <strong>de</strong> lier l’exemple<br />
d’application.<br />
v Pour créer le programme exemple ODBC :<br />
1 A partir <strong>de</strong> la ligne <strong>de</strong> comman<strong>de</strong>, placez-vous dans le sous-répertoire<br />
Samples\ASA\C du répertoire SQL <strong>Anywhere</strong>.<br />
2 Exécutez le fichier batch ou script shell makeall.<br />
Le format <strong>de</strong> cette comman<strong>de</strong> est le suivant :<br />
makeall api plate-forme compilateur<br />
Les paramètres sont les suivants :<br />
♦ API Spécifiez odbc pour compiler l'exemple ODBC plutôt qu'une<br />
version Embed<strong>de</strong>d SQL <strong>de</strong> l'application.<br />
♦ Plate-forme Spécifiez WINNT pour effectuer la compilation pour<br />
les systèmes d'exploitation Windows.<br />
♦ Compilateur Spécifiez le compilateur à utiliser pour compiler le<br />
programme. Les compilateurs admis sont les suivants :<br />
♦ WC Watcom C/C++<br />
♦ MC Microsoft Visual C++<br />
283
Exemples ODBC<br />
284<br />
♦ BC Borland C++ Buil<strong>de</strong>r<br />
Exécution du programme exemple ODBC<br />
Lorsqu'il est compilé pour les versions <strong>de</strong> Windows qui supportent les<br />
services, le programme exemple odbc.c peut être exploité en tant que service.<br />
Les <strong>de</strong>ux fichiers contenant le co<strong>de</strong> exemple pour Windows sont le fichier<br />
source ntsvc.c et le fichier d'en-tête ntsvc.h. Ce co<strong>de</strong> permet <strong>de</strong> lancer le<br />
fichier exécutable associé en tant qu'exécutable normal ou en tant que service<br />
Windows.<br />
v Pour exécuter l'exemple ODBC :<br />
1 Démarrez le programme :<br />
♦ Exécutez le fichier Samples\ASA\C\odbcwnt.exe.<br />
2 Choisissez une table :<br />
♦ Choisissez une <strong>de</strong>s tables <strong>de</strong> la base <strong>de</strong> données exemple. Ainsi,<br />
vous pouvez saisir Customer ou Employee.<br />
v Pour exécuter l'exemple ODBC en tant que service Windows :<br />
1 Démarrez <strong>Sybase</strong> Central et ouvrez le dossier Services.<br />
2 Cliquez sur Ajouter un service. Suivez les instructions d'ajout du<br />
programme exemple en tant que service.<br />
3 Cliquez avec le bouton droit sur l'icône du service, puis sur Démarrer<br />
pour le lancer.<br />
Lorsque les programmes sont exécutés en tant que services, ils affichent<br />
habituellement l'interface utilisateur normale. Ils écrivent également le<br />
résultat dans le journal d'événements <strong>de</strong> l'application (Application Event<br />
Log). S'il est impossible <strong>de</strong> démarrer l'interface utilisateur, les programmes<br />
enregistrent une page <strong>de</strong> données dans ce journal, puis s'interrompent.
Descripteurs ODBC<br />
Chapitre 7 Programmation avec ODBC<br />
Les applications ODBC font appel à un petit ensemble <strong>de</strong> <strong>de</strong>scripteurs pour<br />
définir <strong>de</strong>s fonctionnalités <strong>de</strong> base telles que les connexions aux bases <strong>de</strong><br />
données et les instructions SQL. Un <strong>de</strong>scripteur est une valeur <strong>de</strong> 32 bits.<br />
Les <strong>de</strong>scripteurs suivants sont utilisés dans pratiquement toutes les<br />
applications ODBC :<br />
♦ Environnement Le <strong>de</strong>scripteur d'environnement fournit un contexte<br />
général pour l'accès aux données. Chaque application ODBC doit allouer<br />
un <strong>de</strong>scripteur d'environnement au démarrage et le libérer à la fin.<br />
Le co<strong>de</strong> suivant indique comment allouer un <strong>de</strong>scripteur<br />
d'environnement :<br />
SQLHENV env;<br />
SQLRETURN rc;<br />
rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL<br />
_NULL_HANDLE, &env );<br />
♦ Connexion Une connexion est spécifiée par un pilote ODBC et une<br />
source <strong>de</strong> données. Plusieurs connexions peuvent être associées à<br />
l'environnement d'une application. Le fait d'allouer un <strong>de</strong>scripteur <strong>de</strong><br />
connexion n'établit pas la connexion ; le <strong>de</strong>scripteur <strong>de</strong> connexion doit<br />
être alloué dans un premier temps, puis utilisé lorsque la connexion est<br />
établie.<br />
Le co<strong>de</strong> suivant indique comment allouer un <strong>de</strong>scripteur <strong>de</strong> connexion :<br />
SQLHDBC dbc;<br />
SQLRETURN rc;<br />
rc = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );<br />
♦ Instruction Un <strong>de</strong>scripteur d'instruction permet d'accé<strong>de</strong>r à une<br />
instruction SQL et à toutes les informations qui lui sont associées,<br />
notamment les jeux <strong>de</strong> résultats et les paramètres. Plusieurs instructions<br />
peuvent être associées à chaque connexion. Les instructions sont<br />
utilisées à la fois pour <strong>de</strong>s opérations <strong>de</strong> curseur (extraction <strong>de</strong> données)<br />
et pour l'exécution d'instructions individuelles (par exemple, INSERT,<br />
UPDATE et DELETE).<br />
Le co<strong>de</strong> suivant indique comment allouer un <strong>de</strong>scripteur d'instruction :<br />
SQLHSTMT stmt;<br />
SQLRETURN rc;<br />
rc = SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );<br />
285
Descripteurs ODBC<br />
Allocation <strong>de</strong> <strong>de</strong>scripteurs ODBC<br />
Exemple<br />
286<br />
Les types <strong>de</strong> <strong>de</strong>scripteur nécessaires pour les programmes ODBC sont les<br />
suivants :<br />
Elément Type <strong>de</strong> <strong>de</strong>scripteur<br />
Environnement SQLHENV<br />
Connexion SQLHDBC<br />
Instruction SQLHSTMT<br />
Descripteur SQLHDESC<br />
v Pour utiliser un <strong>de</strong>scripteur ODBC :<br />
1 Appelez la fonction SQLAllocHandle.<br />
SQLAllocHandle prend trois paramètres :<br />
♦ un i<strong>de</strong>ntificateur pour le type d'élément alloué,<br />
♦ le <strong>de</strong>scripteur <strong>de</strong> l'élément parent,<br />
♦ un pointeur renvoyant vers l'emplacement du <strong>de</strong>scripteur à allouer.<br />
$ Pour plus d'informations, reportez-vous à la section<br />
SQLAllocHandle dans le document ODBC Programmer’s Reference <strong>de</strong><br />
Microsoft.<br />
2 Utilisez le <strong>de</strong>scripteur dans les appels <strong>de</strong> fonction ultérieurs.<br />
3 Libérez l'objet à l'ai<strong>de</strong> <strong>de</strong> SQLFreeHandle.<br />
SQLFreeHandle prend les paramètres suivants :<br />
♦ un i<strong>de</strong>ntificateur pour le type d'élément libéré,<br />
♦ le <strong>de</strong>scripteur <strong>de</strong> l'élément libéré.<br />
$ Pour plus d'informations, reportez-vous à la section<br />
SQLFreeHandle dans le document ODBC Programmer's Reference <strong>de</strong><br />
Microsoft.<br />
Le fragment <strong>de</strong> co<strong>de</strong> suivant alloue et libère un <strong>de</strong>scripteur d'environnement :<br />
SQLHENV env;<br />
SQLRETURN retco<strong>de</strong>;<br />
retco<strong>de</strong> = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env );<br />
if( retco<strong>de</strong> == SQL_SUCCESS || retco<strong>de</strong> == SQL_SUCCESS_WITH_INFO ) {<br />
// succès : co<strong>de</strong> d'application ici<br />
}<br />
SQLFreeHandle( SQL_HANDLE_ENV, env );
Premier exemple ODBC<br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> "ntodbc.h"<br />
Chapitre 7 Programmation avec ODBC<br />
$ Pour plus d’informations sur les co<strong>de</strong>s <strong>de</strong> retour et la gestion <strong>de</strong>s<br />
erreurs, reportez-vous à la section "Gestion <strong>de</strong>s erreurs", page 304.<br />
Voici un exemple <strong>de</strong> programme ODBC simple qui permet <strong>de</strong> se connecter à<br />
la base <strong>de</strong> données exemple d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> et <strong>de</strong> se<br />
déconnecter immédiatement.<br />
$ Cet exemple se trouve dans le fichier<br />
Samples\ASA\ODBCConnect\odbcconnect.cpp du répertoire SQL <strong>Anywhere</strong>.<br />
int main(int argc, char* argv[])<br />
{<br />
SQLHENV env;<br />
SQLHDBC dbc;<br />
SQLRETURN retco<strong>de</strong>;<br />
retco<strong>de</strong> = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env );<br />
if (retco<strong>de</strong> == SQL_SUCCESS || retco<strong>de</strong> == SQL_SUCCESS_WITH_INFO) {<br />
printf( "env alloué\n" );<br />
/* Définit l'attribut d'environnement <strong>de</strong> la version d'ODBC */<br />
retco<strong>de</strong> = SQLSetEnvAttr( env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);<br />
retco<strong>de</strong> = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );<br />
if (retco<strong>de</strong> == SQL_SUCCESS || retco<strong>de</strong> == SQL_SUCCESS_WITH_INFO) {<br />
printf( "dbc alloué\n" );<br />
retco<strong>de</strong> = SQLConnect( dbc,<br />
(SQLCHAR*) "ASA 8.0 Sample", SQL_NTS,<br />
(SQLCHAR* ) "DBA", SQL_NTS,<br />
(SQLCHAR*) "SQL", SQL_NTS );<br />
if (retco<strong>de</strong> == SQL_SUCCESS || retco<strong>de</strong> == SQL_SUCCESS_WITH_INFO) {<br />
printf( "Connexion réussie\n" );<br />
}<br />
SQLDisconnect( dbc );<br />
}<br />
SQLFreeHandle( SQL_HANDLE_DBC, dbc );<br />
}<br />
SQLFreeHandle( SQL_HANDLE_ENV, env );<br />
return 0;<br />
}<br />
287
Connexion à une source <strong>de</strong> données<br />
Connexion à une source <strong>de</strong> données<br />
288<br />
Cette section explique comment utiliser les fonctions ODBC pour établir une<br />
connexion à une base <strong>de</strong> données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Choix d’une fonction <strong>de</strong> connexion ODBC<br />
ODBC offre un ensemble <strong>de</strong> fonctions <strong>de</strong> connexion. Leur utilisation dépend<br />
<strong>de</strong> la manière dot vous souhaitez que votre application soit déployée et<br />
utilisée :<br />
♦ SQLConnect Fonction <strong>de</strong> connexion la plus simple.<br />
SQLConnect prend un nom <strong>de</strong> source <strong>de</strong> données et, éventuellement, un<br />
ID utilisateur et un mot <strong>de</strong> passe. Vous pouvez utiliser SQLConnect si<br />
vous co<strong>de</strong>z en dur un nom <strong>de</strong> source <strong>de</strong> données dans votre application.<br />
$ Pour plus d'informations, reportez-vous à la section SQLConnect<br />
du document ODBC Programmer’s Reference <strong>de</strong> Microsoft.<br />
♦ SQLDriverConnect Etablit une connexion à une source <strong>de</strong> données à<br />
l'ai<strong>de</strong> d'une chaîne <strong>de</strong> connexion.<br />
SQLDriverConnect permet à l'application d'utiliser <strong>de</strong>s informations <strong>de</strong><br />
connexion spécifiques d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> qui sont externes à<br />
la source <strong>de</strong> données. Vous pouvez également utiliser<br />
SQLDriverConnect pour fait en sorte que le pilote<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> <strong>de</strong>man<strong>de</strong> <strong>de</strong>s informations <strong>de</strong> connexion.<br />
SQLDriverConnect permet également d'établir une connexion sans<br />
indiquer <strong>de</strong> source <strong>de</strong> données.<br />
$ Pour plus d'informations, reportez-vous à la section<br />
SQLDriverConnect du document ODBC Programmer’s Reference <strong>de</strong><br />
Microsoft.<br />
♦ SQLBrowseConnect Etablit une connexion à la source <strong>de</strong> données à<br />
partir d'une chaîne <strong>de</strong> connexion, tout comme SQLDriverConnect.<br />
SQLBrowseConnect permet à votre application <strong>de</strong> créer ses propres<br />
boîtes <strong>de</strong> dialogue en vue <strong>de</strong> <strong>de</strong>man<strong>de</strong>r <strong>de</strong>s informations <strong>de</strong> connexion et<br />
<strong>de</strong> rechercher <strong>de</strong>s sources <strong>de</strong> données utilisées par un pilote particulier<br />
(dans le cas présent, le pilote <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>).<br />
$ Pour plus d'informations, reportez-vous à la section<br />
SQLBrowseConnect du document ODBC Programmer’s Reference <strong>de</strong><br />
Microsoft.
Etablissement d’une connexion<br />
Chapitre 7 Programmation avec ODBC<br />
Les exemples <strong>de</strong> ce chapitre font principalement appel à la fonction<br />
SQLDriverConnect.<br />
$ Pour obtenir une liste complète <strong>de</strong>s paramètres <strong>de</strong> connexion qui<br />
peuvent être utilisés dans les chaînes <strong>de</strong> connexion, reportez-vous à la<br />
section "Paramètres <strong>de</strong> connexion", page 176 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
Votre application doit établir une connexion avant d'effectuer <strong>de</strong>s opérations<br />
sur une base <strong>de</strong> données.<br />
v Pour établir une connexion ODBC :<br />
1 Allouez un environnement ODBC.<br />
Par exemple :<br />
SQLHENV env;<br />
SQLRETURN retco<strong>de</strong>;<br />
retco<strong>de</strong> = SQLAllocHandle( SQL_HANDLE_ENV,<br />
SQL_NULL_HANDLE, &env );<br />
2 Déclarez la version d'ODBC.<br />
En déclarant que l'application se base sur ODBC version 3, le<br />
comportement à adopter par les valeurs SQLSTATE ainsi que par<br />
d'autres fonctionnalités reposant sur la version est défini. Par exemple :<br />
retco<strong>de</strong> = SQLSetEnvAttr( env,<br />
SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);<br />
3 Si nécessaire, assemblez la source <strong>de</strong> données ou la chaîne <strong>de</strong><br />
connexion.<br />
En fonction <strong>de</strong> votre application, vous pouvez avoir une chaîne <strong>de</strong><br />
connexion ou une source <strong>de</strong> données codée en dur, ou vous pouvez<br />
choisir <strong>de</strong> la stocker en externe pour garantir une meilleure flexibilité.<br />
4 Allouez un élément <strong>de</strong> connexion ODBC.<br />
Par exemple :<br />
retco<strong>de</strong> = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc<br />
);<br />
5 Définissez tous les attributs <strong>de</strong> connexion qui doivent l'être avant<br />
d'établir une connexion.<br />
289
Connexion à une source <strong>de</strong> données<br />
290<br />
Certains attributs <strong>de</strong> connexion doivent être définis avant d'établir une<br />
connexion, alors que d'autres attributs peuvent être définis soit avant,<br />
soit après la connexion. Par exemple :<br />
retco<strong>de</strong> = SQLSetConnectAttr( dbc, SQL_AUTOCOMMIT,<br />
FALSE );<br />
$ Pour plus d'informations, reportez-vous à la section "Définition <strong>de</strong>s<br />
attributs <strong>de</strong> connexion", page 290.<br />
6 Appelez la fonction <strong>de</strong> connexion ODBC.<br />
Par exemple :<br />
if (retco<strong>de</strong> == SQL_SUCCESS || retco<strong>de</strong> ==<br />
SQL_SUCCESS_WITH_INFO) {<br />
printf( "dbc alloué\n" );<br />
retco<strong>de</strong> = SQLConnect( dbc,<br />
(SQLCHAR*) "ASA 8.0 Sample", SQL_NTS,<br />
(SQLCHAR* ) "DBA", SQL_NTS,<br />
(SQLCHAR*) "SQL", SQL_NTS );<br />
if (retco<strong>de</strong> == SQL_SUCCESS<br />
|| retco<strong>de</strong> == SQL_SUCCESS_WITH_INFO){<br />
// connexion réussie.<br />
$ Vous trouverez un exemple complet dans le fichier<br />
Samples\ASA\ODBCConnect\odbcconnect.cpp du répertoire SQL <strong>Anywhere</strong>.<br />
Définition <strong>de</strong>s attributs <strong>de</strong> connexion<br />
La fonction SQLSetConnectAttr permet <strong>de</strong> contrôler les détails <strong>de</strong> la<br />
connexion. Par exemple, l'instruction suivante désactive le mo<strong>de</strong> autocommit<br />
d'ODBC.<br />
retco<strong>de</strong> = SQLSetConnectAttr( dbc, SQL_AUTOCOMMIT, FALSE<br />
);<br />
$ Pour plus d'informations incluant une liste d'attributs <strong>de</strong> connexion,<br />
reportez-vous à la section SQLSetConnectAttr du document ODBC<br />
Programmer’s Reference <strong>de</strong> Microsoft.<br />
De nombreux aspects <strong>de</strong> la connexion peuvent être contrôlés par<br />
l'intermédiaire <strong>de</strong>s paramètres <strong>de</strong> connexion. Pour plus d'informations,<br />
reportez-vous à la section "Paramètres <strong>de</strong> connexion", page 75 du document<br />
ASA <strong>Gui<strong>de</strong></strong> d’administration.
Threads et connexions dans les applications ODBC<br />
Chapitre 7 Programmation avec ODBC<br />
Vous pouvez développer <strong>de</strong>s applications ODBC multithread pour <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>. Il est recommandé d'utiliser une connexion distincte par<br />
thread.<br />
Vous pouvez utiliser une connexion unique pour plusieurs threads. Toutefois,<br />
le serveur <strong>de</strong> base <strong>de</strong> données n'autorise pas plus d'une requête active<br />
simultanée par connexion. Si un thread exécute une instruction longue, tous<br />
les autres threads doivent attendre la fin <strong>de</strong> la requête.<br />
291
Exécution d'instructions SQL<br />
Exécution d'instructions SQL<br />
292<br />
ODBC inclut plusieurs fonctions pour l'exécution d'instructions SQL :<br />
♦ Exécution directe <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> analyse<br />
l’instruction SQL, prépare un plan d'accès et exécute l'instruction.<br />
L'analyse et la préparation du plan d'accès constituent la phase <strong>de</strong><br />
préparation <strong>de</strong> l’instruction.<br />
♦ Exécution préparée La préparation <strong>de</strong> l'instruction est effectuée<br />
indépendamment <strong>de</strong> l'exécution. Pour les instructions qui doivent être<br />
exécutées <strong>de</strong> manière répétitive, cette fonction évite <strong>de</strong> répéter la<br />
préparation et améliore par conséquent les performances.<br />
$ Pour plus d'informations, reportez-vous à la section "Exécution <strong>de</strong>s<br />
instructions préparées", page 295.<br />
Exécution directe <strong>de</strong>s instructions<br />
La fonction SQLExecDirect prépare et exécute une instruction SQL.<br />
L'instruction peut éventuellement inclure <strong>de</strong>s paramètres.<br />
Le fragment <strong>de</strong> co<strong>de</strong> suivant indique comment exécuter une instruction sans<br />
paramètres. La fonction SQLExecDirect prend un <strong>de</strong>scripteur d'instruction,<br />
une chaîne SQL, et un indicateur <strong>de</strong> longueur ou <strong>de</strong> fin, qui, dans le cas<br />
présent, est un indicateur <strong>de</strong> chaîne terminée par la valeur NULL.<br />
La procédure décrite dans cette section est simple mais stricte. L'application<br />
n'accepte aucune entrée <strong>de</strong> l'utilisateur visant à modifier l'instruction. Pour<br />
connaître une métho<strong>de</strong> plus souple <strong>de</strong> création d'instructions, reportez-vous à<br />
la section "Exécution d'instructions avec <strong>de</strong>s paramètres <strong>de</strong> liaison",<br />
page 293.<br />
v Pour exécuter une instruction SQL dans une application ODBC :<br />
1 Allouez un <strong>de</strong>scripteur d'instruction à l'ai<strong>de</strong> <strong>de</strong> la fonction<br />
SQLAllocHandle.<br />
Par exemple, l'instruction suivante alloue un <strong>de</strong>scripteur <strong>de</strong> type<br />
SQL_HANDLE_STMT portant le nom stmt, sur une connexion avec le<br />
<strong>de</strong>scripteur dbc:<br />
SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );<br />
2 Appelez la fonction SQLExecDirect pour exécuter l'instruction.
Chapitre 7 Programmation avec ODBC<br />
Par exemple, les lignes suivantes déclarent une instruction et l'exécutent.<br />
La déclaration <strong>de</strong> <strong>de</strong>letestmt est effectuée généralement au début <strong>de</strong><br />
la fonction :<br />
SQLCHAR <strong>de</strong>letestmt[ STMT_LEN ] =<br />
"DELETE FROM <strong>de</strong>partment WHERE <strong>de</strong>pt_id = 201";<br />
SQLExecDirect( stmt, <strong>de</strong>letestmt, SQL_NTS) ;<br />
$ Pour obtenir un exemple complet avec le contrôle d'erreurs, consultez le<br />
fichier Samples\ASA\ODBCExecute\odbcexecute.cpp.<br />
$ Pour plus d'informations sur la fonction SQLExecDirect, reportez-vous<br />
à la section SQLExecDirect du document ODBC Programmer’s Reference <strong>de</strong><br />
Microsoft.<br />
Exécution d'instructions avec <strong>de</strong>s paramètres <strong>de</strong> liaison<br />
Cette section explique comment créer et exécuter une instruction SQL en<br />
utilisant <strong>de</strong>s paramètres <strong>de</strong> liaison pour définir les valeurs <strong>de</strong>s paramètres <strong>de</strong><br />
l'instruction lors <strong>de</strong> l'exécution.<br />
v Pour exécuter une instruction SQL avec <strong>de</strong>s paramètres <strong>de</strong> liaison<br />
dans une application ODBC :<br />
1 Allouez un <strong>de</strong>scripteur pour l'instruction à l'ai<strong>de</strong> <strong>de</strong> la fonction<br />
SQLAllocHandle.<br />
Par exemple, l'instruction suivante alloue un <strong>de</strong>scripteur <strong>de</strong> type<br />
SQL_HANDLE_STMT portant le nom stmt, sur une connexion avec le<br />
<strong>de</strong>scripteur dbc:<br />
SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );<br />
2 Effectuez la liaison <strong>de</strong>s paramètres <strong>de</strong> l'instruction avec<br />
SQLBindParameter.<br />
Par exemple, les lignes suivantes déclarent <strong>de</strong>s variables pour contenir<br />
les valeurs <strong>de</strong> l'ID du service, du nom du service, <strong>de</strong> l'ID du responsable<br />
et <strong>de</strong> la chaîne d'instruction elle-même. Ensuite, elles lient les<br />
paramètres aux premier, <strong>de</strong>uxième et troisième paramètre d'une<br />
instruction exécutée à l'ai<strong>de</strong> du <strong>de</strong>scripteur d'instruction stmt.<br />
293
Exécution d'instructions SQL<br />
294<br />
#<strong>de</strong>fined DEPT_NAME_LEN 20<br />
SQLINTEGER cbDeptID = 0,<br />
cbDeptName = SQL_NTS, cbManagerID = 0;<br />
SQLCHAR <strong>de</strong>ptname[ DEPT_NAME_LEN ];<br />
SQLSMALLINT <strong>de</strong>ptID, managerID;<br />
SQLCHAR insertstmt[ STMT_LEN ] =<br />
"INSERT INTO <strong>de</strong>partment "<br />
"( <strong>de</strong>pt_id, <strong>de</strong>pt_name, <strong>de</strong>pt_head_id )"<br />
"VALUES (?, ?, ?,)";<br />
SQLBindParameter( stmt, 1, SQL_PARAM_INPUT,<br />
SQL_C_SSHORT, SQL_INTEGER, 0, 0,<br />
&<strong>de</strong>ptID, 0, &cbDeptID);<br />
SQLBindParameter( stmt, 2, SQL_PARAM_INPUT,<br />
SQL_C_CHAR, SQL_CHAR, DEPT_NAME_LEN, 0,<br />
<strong>de</strong>ptname, 0,&cbDeptName);<br />
SQLBindParameter( stmt, 3, SQL_PARAM_INPUT,<br />
SQL_C_SSHORT, SQL_INTEGER, 0, 0,<br />
&managerID, 0, &cbManagerID);<br />
3 Affectez <strong>de</strong>s valeurs aux paramètres.<br />
Par exemple, les lignes suivantes affectent <strong>de</strong>s valeurs aux paramètres <strong>de</strong><br />
l'exemple <strong>de</strong> l'étape 2.<br />
<strong>de</strong>ptID = 201;<br />
strcpy( (char * ) <strong>de</strong>ptname, "Sales East" );<br />
managerID = 902;<br />
En règle générale, ces variables sont définies en réponse à l'action <strong>de</strong><br />
l'utilisateur.<br />
4 Exécutez l'instruction à l'ai<strong>de</strong> <strong>de</strong> la fonction SQLExecDirect.<br />
Par exemple, la ligne suivante exécute la chaîne d'instruction contenue<br />
dans insertstmt sur le <strong>de</strong>scripteur d'instruction stmt.<br />
SQLExecDirect( stmt, insertstmt, SQL_NTS) ;<br />
Les paramètres <strong>de</strong> liaison sont également utilisés avec <strong>de</strong>s instructions<br />
préparées afin d'améliorer les performances <strong>de</strong>s instructions exécutées à<br />
plusieurs reprises. Pour plus d'informations, reportez-vous à la section<br />
"Exécution <strong>de</strong>s instructions préparées", page 295.<br />
$ Les fragments <strong>de</strong> co<strong>de</strong> ci-<strong>de</strong>ssus n'incluent pas le contrôle d'erreurs.<br />
Pour obtenir un exemple complet incluant le contrôle d'erreurs, consultez le<br />
fichier Samples\ASA\ODBCExecute\odbcexecute.cpp.<br />
$ Pour plus d'informations sur SQLExecDirect, reportez-vous à la<br />
section SQLExecDirect dans le document ODBC Programmer’s Reference<br />
<strong>de</strong> Microsoft.
Exécution <strong>de</strong>s instructions préparées<br />
Chapitre 7 Programmation avec ODBC<br />
Les instructions préparées offrent <strong>de</strong>s avantages en matière <strong>de</strong> performances<br />
pour les instructions répétitives. ODBC offre tout un ensemble <strong>de</strong> fonctions<br />
d'utilisation d'instructions préparées.<br />
$ Pour plus d'informations sur les instructions préparées, reportez-vous à<br />
la section "Préparation <strong>de</strong>s instructions", page 12.<br />
v Pour exécuter une instruction SQL préparée :<br />
1 Préparez l'instruction via SQLPrepare.<br />
Par exemple, le fragment <strong>de</strong> co<strong>de</strong> ci-<strong>de</strong>ssous illustre la préparation d'une<br />
instruction INSERT.<br />
SQLRETURN retco<strong>de</strong>;<br />
SQLHSTMT stmt;<br />
retco<strong>de</strong> = SQLPrepare( stmt,<br />
"INSERT INTO <strong>de</strong>partment<br />
( <strong>de</strong>pt_id, <strong>de</strong>pt_name, <strong>de</strong>pt_head_id )<br />
VALUES (?, ?, ?,)",<br />
SQL_NTS);<br />
Dans cet exemple :<br />
♦ retco<strong>de</strong> Contient un co<strong>de</strong> <strong>de</strong> retour qui doit être testé pour vérifier<br />
la réussite ou l'échec <strong>de</strong> l'opération.<br />
♦ stmt Fournit un <strong>de</strong>scripteur à l'instruction qui servira <strong>de</strong> référence<br />
ultérieurement.<br />
♦ ? Les points d'interrogation sont <strong>de</strong>s marques <strong>de</strong> réservation pour<br />
les paramètres <strong>de</strong> l'instruction.<br />
2 Définissez les valeurs <strong>de</strong>s paramètres <strong>de</strong> l'instruction à l'ai<strong>de</strong> <strong>de</strong> la<br />
fonction SQLBindParameter.<br />
Par exemple, l'appel <strong>de</strong> fonction ci-<strong>de</strong>ssous définit la valeur <strong>de</strong> la<br />
variable <strong>de</strong>pt_id.<br />
SQLBindParameter( stmt,<br />
1,<br />
SQL_PARAM_INPUT,<br />
SQL_C_SSHORT,<br />
SQL_INTEGER,<br />
0,<br />
0,<br />
&sDeptID,<br />
0,<br />
&cbDeptID);<br />
Dans cet exemple :<br />
295
Exécution d'instructions SQL<br />
296<br />
♦ stmt Descripteur d’instruction<br />
♦ 1 Indique que cet appel définit la valeur <strong>de</strong> la première marque <strong>de</strong><br />
réservation.<br />
♦ SQL_PARAM_INPUT Indique que le paramètre est une instruction<br />
en entrée.<br />
♦ SQL_C_SHORT Indique le type <strong>de</strong> données en langage C utilisé<br />
dans l'application.<br />
♦ SQL_INTEGER Indique le type <strong>de</strong> données SQL utilisé dans la base<br />
<strong>de</strong> données.<br />
♦ Les <strong>de</strong>ux paramètres suivants indiquent la précision <strong>de</strong> la colonne et<br />
le nombre <strong>de</strong> chiffres après la virgule : ils sont tous <strong>de</strong>ux égaux à<br />
zéro pour les nombres entiers.<br />
♦ &sDeptID Pointeur sur un buffer pour la valeur du paramètre.<br />
♦ 0 Indique la longueur du buffer en octets.<br />
♦ &cbDeptID Pointeur sur un buffer pour la longueur <strong>de</strong> la valeur du<br />
paramètre.<br />
3 Liez les <strong>de</strong>ux autres paramètres et attribuez <strong>de</strong>s valeurs à sDeptId :<br />
4 Exécutez l'instruction.<br />
retco<strong>de</strong> = SQLExecute( stmt);<br />
Les étapes 2 à 4 peuvent être exécutées à plusieurs reprises.<br />
5 Supprimez l'instruction.<br />
En supprimant l'instruction, vous libérez les ressources qui lui sont<br />
associées. Pour supprimer une instruction, utilisez SQLFreeHandle.<br />
$ Pour obtenir un exemple complet incluant le contrôle d'erreurs,<br />
consultez le fichier Samples\ASA\ODBCPrepare\odbcprepare.cpp.<br />
$ Pour plus d'informations sur SQLPrepare, reportez-vous à la section<br />
SQLPrepare dans le document ODBC Programmer’s Reference <strong>de</strong><br />
Microsoft.
Jeux <strong>de</strong> résultats<br />
Chapitre 7 Programmation avec ODBC<br />
Les applications ODBC utilisent <strong>de</strong>s curseurs pour manipuler et mettre à jour<br />
les jeux <strong>de</strong> résultats. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> offre un support complet<br />
<strong>de</strong>s différents types <strong>de</strong> curseurs et opérations sur curseur.<br />
$ Pour plus d'informations sur les curseurs, reportez-vous à la section<br />
"Utilisation <strong>de</strong>s curseurs", page 20.<br />
Choix <strong>de</strong>s caractéristiques d'un curseur<br />
Les fonctions ODBC qui exécutent <strong>de</strong>s instructions et manipulent <strong>de</strong>s jeux <strong>de</strong><br />
résultats utilisent <strong>de</strong>s curseurs pour accomplir leurs tâches. Les applications<br />
ouvrent un curseur <strong>de</strong> manière implicite chaque fois qu'elles exécutent une<br />
fonction SQLExecute ou SQLExecDirect.<br />
Pour les applications qui parcourent un jeu <strong>de</strong> résultats uniquement vers<br />
l'avant sans le mettre à jour, le comportement <strong>de</strong>s curseurs est relativement<br />
simple. Par défaut, les applications ODBC requièrent ce comportement.<br />
ODBC définit un curseur en lecture seule, à défilement avant uniquement et,<br />
dans ce cas, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> fournit un curseur optimisé du point<br />
<strong>de</strong> vue <strong>de</strong>s performances.<br />
$ Pour avoir un exemple simple <strong>de</strong> curseur à défilement avant<br />
uniquement, reportez-vous à la section "Récupération <strong>de</strong> données", page 298.<br />
Pour les applications ayant besoin <strong>de</strong> parcourir un jeu <strong>de</strong> résultats à la fois<br />
vers l'avant et vers l'arrière (c'est notamment le cas <strong>de</strong> nombreuses<br />
applications à interface graphique), le comportement <strong>de</strong>s curseurs est plus<br />
complexe. Que fait une application lorsqu'elle renvoie vers une ligne qui a<br />
été mise à jour par une autre application ? ODBC définit une variété <strong>de</strong><br />
curseurs avec défilement afin <strong>de</strong> vous permettre <strong>de</strong> générer le<br />
comportement qui convient à votre application. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
offre un jeu complet <strong>de</strong> curseurs qui correspon<strong>de</strong>nt aux types <strong>de</strong><br />
curseur ODBC avec défilement.<br />
La définition <strong>de</strong>s caractéristiques du curseur ODBC s'effectue en appelant la<br />
fonction SQLSetStmtAttr, qui définit les attributs <strong>de</strong> l'instruction. Vous<br />
<strong>de</strong>vez appeler la fonction SQLSetStmtAttr avant d'exécuter une instruction<br />
qui crée un jeu <strong>de</strong> résultats.<br />
Vous pouvez utiliser la fonction SQLSetStmtAttr pour définir les<br />
caractéristiques <strong>de</strong> plusieurs curseurs. Les caractéristiques qui déterminent le<br />
type <strong>de</strong> curseur fourni par <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> sont les suivantes :<br />
297
Jeux <strong>de</strong> résultats<br />
Exemple<br />
Récupération <strong>de</strong> données<br />
298<br />
♦ SQL_ATTR_CURSOR_SCROLLABLE Définie avec la valeur<br />
SQL_SCROLLABLE pour un curseur avec défilement et avec la valeur<br />
SQL_NONSCROLLABLE pour un curseur avec défilement avant<br />
uniquement. SQL_NONSCROLLABLE est la valeur par défaut.<br />
♦ SQL_ATTR_CONCURRENCY Définie avec l'une <strong>de</strong>s valeurs suivantes :<br />
♦ SQL_CONCUR_READ_ONLY Interdit les mises à jour.<br />
SQL_CONCUR_READ_ONLY est la valeur par défaut.<br />
♦ SQL_CONCUR_LOCK Utilise le niveau <strong>de</strong> verrouillage le plus bas<br />
pour garantir que la ligne peut être mise à jour.<br />
♦ SQL_CONCUR_ROWVER Utilise le contrôle <strong>de</strong> concurrence<br />
optimiste en comparant <strong>de</strong>s versions <strong>de</strong> ligne telles que<br />
SQLBase ROWID ou <strong>Sybase</strong> TIMESTAMP.<br />
♦ SQL_CONCUR_VALUES Utilise le contrôle <strong>de</strong> concurrence<br />
optimiste en comparant les valeurs.<br />
$ Pour plus d'informations, reportez-vous à la section SQLSetStmtAttr<br />
dans le document ODBC Programmer’s Reference <strong>de</strong> Microsoft.<br />
Le fragment <strong>de</strong> co<strong>de</strong> suivant définit un curseur en lecture seule et avec<br />
défilement :<br />
SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );<br />
SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_SCROLLABLE,<br />
SQL_SCROLLABLE, 0 );<br />
Pour récupérer <strong>de</strong>s lignes d'une base <strong>de</strong> données, exécutez une instruction<br />
SELECT à l'ai<strong>de</strong> <strong>de</strong> la fonction SQLExecute ou SQLExecDirect. Cette<br />
opération ouvre un curseur sur l'instruction. Utilisez ensuite SQLFetch ou<br />
SQLExten<strong>de</strong>dFetch pour extraire <strong>de</strong>s lignes par l'intermédiaire du curseur.<br />
Lorsqu'une application libère l'instruction à l'ai<strong>de</strong> <strong>de</strong> SQLFreeHandle, elle<br />
ferme le curseur.<br />
Pour extraire les valeurs d'un curseur, l'application peut utiliser SQLBindCol<br />
ou SQLGetData. Avec SQLBindCol, les valeurs sont récupérées<br />
automatiquement à chaque extraction. Avec SQLGetData, vous <strong>de</strong>vez les<br />
appeler pour chaque colonne après chaque extraction.<br />
SQLGetData est utilisé pour extraire <strong>de</strong>s valeurs en plusieurs morceaux<br />
pour <strong>de</strong>s colonnes <strong>de</strong> type LONG VARCHAR ou LONG BINARY. Vous<br />
pouvez également définir l'attribut <strong>de</strong> l'instruction SQL_MAX_LENGTH sur<br />
une valeur suffisamment gran<strong>de</strong> pour contenir la valeur entière <strong>de</strong> la colonne.<br />
La valeur par défaut <strong>de</strong> SQL_ATTR_MAX_LENGTH est 256 Ko.
Chapitre 7 Programmation avec ODBC<br />
Le fragment <strong>de</strong> co<strong>de</strong> suivant ouvre un curseur sur une requête et récupère les<br />
données par l'intermédiaire du curseur. Le contrôle d'erreurs a été<br />
volontairement omis afin <strong>de</strong> faciliter la lecture <strong>de</strong> cet exemple. Ce fragment<br />
est issu d'un exemple complet, que vous trouverez dans le fichier<br />
Samples\ASA\ODBCSelect\odbcselect.cpp.<br />
SQLINTEGER cbDeptID = 0, cbDeptName = SQL_NTS, cbManagerID = 0;<br />
SQLCHAR <strong>de</strong>ptname[ DEPT_NAME_LEN ];<br />
SQLSMALLINT <strong>de</strong>ptID, managerID;<br />
SQLHENV env;<br />
SQLHDBC dbc;<br />
SQLHSTMT stmt;<br />
SQLRETURN retco<strong>de</strong>;<br />
SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env );<br />
SQLSetEnvAttr( env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);<br />
SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );<br />
SQLConnect( dbc,<br />
(SQLCHAR*) "ASA 8.0 Sample", SQL_NTS,<br />
(SQLCHAR*) "DBA", SQL_NTS,<br />
(SQLCHAR*) "SQL", SQL_NTS );<br />
SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );<br />
SQLBindCol( stmt, 1, SQL_C_SSHORT, &<strong>de</strong>ptID, 0, &cbDeptID);<br />
SQLBindCol( stmt, 2, SQL_C_CHAR, <strong>de</strong>ptname, sizeof(<strong>de</strong>ptname),<br />
&cbDeptName);<br />
SQLBindCol( stmt, 3, SQL_C_SSHORT, &managerID, 0, &cbManagerID);<br />
SQLExecDirect( stmt, (SQLCHAR * )<br />
"SELECT <strong>de</strong>pt_id, <strong>de</strong>pt_name, <strong>de</strong>pt_head_id FROM DEPARTMENT "<br />
"ORDER BY <strong>de</strong>pt_id", SQL_NTS );<br />
while( ( retco<strong>de</strong> = SQLFetch( stmt ) ) != SQL_NO_DATA ){<br />
printf( "%d %20s %d\n", <strong>de</strong>ptID, <strong>de</strong>ptname, managerID );<br />
}<br />
SQLFreeHandle( SQL_HANDLE_STMT, stmt );<br />
SQLDisconnect( dbc );<br />
SQLFreeHandle( SQL_HANDLE_DBC, dbc );<br />
SQLFreeHandle( SQL_HANDLE_ENV, env );<br />
Le nombre <strong>de</strong> positions <strong>de</strong> ligne que vous pouvez extraire dans un curseur est<br />
fonction <strong>de</strong> la taille d'un entier. Vous pouvez extraire <strong>de</strong>s lignes numérotées<br />
jusqu'à 2 147 483 646, ce qui correspond à la valeur que peut contenir un<br />
entier, moins un. Lorsque vous utilisez <strong>de</strong>s nombres négatifs (comptage <strong>de</strong>s<br />
lignes à partir <strong>de</strong> la fin), vous pouvez extraire un nombre <strong>de</strong> lignes égal à la<br />
plus gran<strong>de</strong> valeur négative que peut contenir un entier, plus un.<br />
299
Jeux <strong>de</strong> résultats<br />
Mise à jour et suppression <strong>de</strong> lignes par l'intermédiaire d'un<br />
curseur<br />
Utilisation <strong>de</strong> signets<br />
300<br />
Le document ODBC Programmer’s Reference <strong>de</strong> Microsoft recomman<strong>de</strong><br />
d’utiliser l’instruction SELECT... FOR UPDATE pour indiquer qu’une<br />
requête peut être mise à jour à l'ai<strong>de</strong> d'opérations positionnées. Il n'est pas<br />
nécessaire d'utiliser la clause FOR UPDATE dans<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Les instructions SELECT peuvent être mises à<br />
jour automatiquement tant que les conditions suivantes sont respectées :<br />
♦ La requête sous-jacente supporte ce type d'opération.<br />
Cela signifie que tant qu'une instruction modifiant les données <strong>de</strong>s<br />
colonnes du résultat est significative, les instructions <strong>de</strong> modification <strong>de</strong><br />
données positionnées peuvent être exécutées sur le curseur.<br />
L'option <strong>de</strong> base <strong>de</strong> données ANSI_UPDATE_CONSTRAINTS limite<br />
le type <strong>de</strong> requête actualisable.<br />
$ Pour plus d'informations, reportez-vous à la section "Option<br />
ANSI_UPDATE_CONSTRAINTS", page 602 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
♦ Le type <strong>de</strong> curseur supporte les mises à jour.<br />
Si vous utilisez un curseur en lecture seule, vous ne pourrez pas mettre à<br />
jour le jeu <strong>de</strong> résultats.<br />
ODBC offre <strong>de</strong>ux autres moyens d'exécuter les mises à jour et les<br />
suppressions positionnées.<br />
♦ Utilisation <strong>de</strong> la fonction SQLSetPos.<br />
En fonction <strong>de</strong>s paramètres entrés (SQL_POSITION, SQL_REFRESH,<br />
SQL_UPDATE, SQL_DELETE), SQLSetPos définit la position du<br />
curseur et permet à une application d'actualiser les données, ou encore<br />
<strong>de</strong> mettre à jour ou <strong>de</strong> supprimer <strong>de</strong>s données du jeu <strong>de</strong> résultats.<br />
Il s'agit <strong>de</strong> la métho<strong>de</strong> à utiliser avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
♦ Envoi d'instructions UPDATE et DELETE positionnées à l'ai<strong>de</strong> <strong>de</strong> la<br />
fonction SQLExecute. Cette métho<strong>de</strong> ne doit pas être utilisée avec<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
ODBC fournit <strong>de</strong>s signets qui sont <strong>de</strong>s valeurs utilisées pour i<strong>de</strong>ntifier les<br />
lignes d'un curseur. <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> accepte <strong>de</strong>s signets pour tous<br />
les types <strong>de</strong> curseur à l'exception <strong>de</strong>s curseurs dynamiques.
Chapitre 7 Programmation avec ODBC<br />
Dans les versions antérieures à ODBC 3.0, une base <strong>de</strong> données pouvait<br />
seulement spécifier si elle supportait ou non les signets. Il n'existait pas<br />
d'interface pour fournir cette information sur chaque type <strong>de</strong> curseur. De<br />
même, il n'y avait aucun moyen au niveau du serveur <strong>de</strong> base <strong>de</strong> données<br />
d'indiquer quels types <strong>de</strong> signet <strong>de</strong> curseur étaient supportés. Pour les<br />
applications ODBC 2, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> signale qu'il ne supporte<br />
pas les signets. Il n'y a donc rien qui vous empêche <strong>de</strong> tenter d'utiliser <strong>de</strong>s<br />
signets avec <strong>de</strong>s curseurs dynamiques ; mais vous <strong>de</strong>vez néanmoins proscrire<br />
cette combinaison.<br />
301
Appel <strong>de</strong> procédures stockées<br />
Appel <strong>de</strong> procédures stockées<br />
Procédures et jeux<br />
<strong>de</strong> résultats<br />
Exemple<br />
302<br />
La présente section explique comment créer et appeler <strong>de</strong>s procédures<br />
stockées, et traiter <strong>de</strong>s résultats à partir d'une application ODBC.<br />
$ Pour une <strong>de</strong>scription complète <strong>de</strong>s procédures stockées et <strong>de</strong>s triggers,<br />
reportez-vous à la section "Utilisation <strong>de</strong>s procédures, <strong>de</strong>s triggers et <strong>de</strong>s<br />
batchs", page 541 du document ASA <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL.<br />
Il existe <strong>de</strong>ux types <strong>de</strong> procédures : celles qui renvoient <strong>de</strong>s jeux <strong>de</strong> résultats<br />
et celles qui n'en renvoient pas. Vous pouvez utiliser SQLNumResultCols<br />
pour les distinguer. Si la procédure ne renvoie pas <strong>de</strong> jeu <strong>de</strong> résultats, le<br />
nombre <strong>de</strong> colonnes <strong>de</strong> résultats est égal à zéro. Dans le cas contraire, vous<br />
pouvez extraire les valeurs à l'ai<strong>de</strong> <strong>de</strong> SQLFetch ou <strong>de</strong> SQLExten<strong>de</strong>dFetch<br />
comme vous le feriez pour n'importe quel autre curseur.<br />
Les paramètres doivent être transmis aux procédures à l'ai<strong>de</strong> <strong>de</strong> marqueurs <strong>de</strong><br />
paramètre (points d'interrogation). Utilisez SQLBindParameter pour<br />
attribuer une zone <strong>de</strong> stockage à chaque marqueur <strong>de</strong> paramètre, selon qu'il<br />
s'agit d'un paramètre INPUT, OUTPUT ou INOUT.<br />
Pour traiter <strong>de</strong>s jeux <strong>de</strong> résultats multiples, ODBC doit décrire le curseur en<br />
cours d'exécution et pas le jeu <strong>de</strong> résultat <strong>de</strong> la procédure. C'est pourquoi<br />
ODBC ne décrit pas toujours les noms <strong>de</strong> colonnes tels qu'ils sont définis<br />
dans la clause RESULT <strong>de</strong> la définition <strong>de</strong> la procédure stockée. Pour éviter<br />
ce problème, vous pouvez utiliser <strong>de</strong>s alias <strong>de</strong> colonnes dans votre curseur <strong>de</strong><br />
jeu <strong>de</strong> résultats.<br />
L'exemple suivant crée et appelle une procédure qui ne renvoie aucun jeu <strong>de</strong><br />
résultats. Cette procédure prend un paramètre INOUT et incrémente sa<br />
valeur. La valeur <strong>de</strong> variable num_col est ici zéro, car la procédure ne<br />
renvoie pas <strong>de</strong> jeu <strong>de</strong> résultats. Le contrôle d'erreurs a été volontairement<br />
omis afin <strong>de</strong> faciliter la lecture <strong>de</strong> cet exemple.<br />
HDBC dbc;<br />
HSTMT stmt;<br />
long i;<br />
SWORD num_col;<br />
/* Crée une procédure */<br />
SQLAllocStmt( dbc, &stmt );<br />
SQLExecDirect( stmt,<br />
"CREATE PROCEDURE Increment( INOUT a INT )" \<br />
" BEGIN" \<br />
" SET a = a + 1" \<br />
" END", SQL_NTS );<br />
/* Appelle la procédure pour incrémenter "i" */<br />
i = 1;
Exemple<br />
Chapitre 7 Programmation avec ODBC<br />
SQLBindParameter( stmt, 1, SQL_C_LONG, SQL_INTEGER, 0,<br />
0, &i, NULL );<br />
SQLExecDirect( stmt, "CALL Increment( ? )",<br />
SQL_NTS );<br />
SQLNumResultCols( stmt, &num_col );<br />
do_something( i );<br />
L'exemple qui suit appelle une procédure qui renvoie un jeu <strong>de</strong> résultats. La<br />
variable num_col a ici la valeur 2 car la procédure renvoie un jeu <strong>de</strong> résultats<br />
avec <strong>de</strong>ux colonnes. Le contrôle d'erreurs a été volontairement omis afin <strong>de</strong><br />
faciliter la lecture <strong>de</strong> cet exemple.<br />
HDBC dbc;<br />
HSTMT stmt;<br />
SWORD num_col;<br />
RETCODE retco<strong>de</strong>;<br />
char emp_id[ 10 ];<br />
char emp_lame[ 20 ];<br />
/* Crée la procédure */<br />
SQLExecDirect( stmt,<br />
"CREATE PROCEDURE employees()" \<br />
" RESULT( emp_id CHAR(10), emp_lname CHAR(20))"\<br />
" BEGIN" \<br />
" SELECT emp_id, emp_lame FROM employee" \<br />
" END", SQL_NTS );<br />
/* Appelle la procédure - imprime les résultats */<br />
SQLExecDirect( stmt, "CALL employees()", SQL_NTS );<br />
SQLNumResultCols( stmt, &num_col );<br />
SQLBindCol( stmt, 1, SQL_C_CHAR, &emp_id,<br />
sizeof(emp_id), NULL );<br />
SQLBindCol( stmt, 2, SQL_C_CHAR, &emp_lname,<br />
sizeof(emp_lname), NULL );<br />
for( ;; ) {<br />
retco<strong>de</strong> = SQLFetch( stmt );<br />
if( retco<strong>de</strong> == SQL_NO_DATA_FOUND ) {<br />
retco<strong>de</strong> = SQLMoreResults( stmt );<br />
if( retco<strong>de</strong> == SQL_NO_DATA_FOUND ) break;<br />
} else {<br />
do_something( emp_id, emp_lname );<br />
}<br />
}<br />
303
Gestion <strong>de</strong>s erreurs<br />
Gestion <strong>de</strong>s erreurs<br />
304<br />
Les erreurs détectées dans ODBC sont signalées par la valeur renvoyée par<br />
chaque appel <strong>de</strong> fonction ODBC, et soit par la fonction SQLError, soit par<br />
la fonction SQLGetDiagRec. La fonction SQLError était utilisée dans les<br />
versions précé<strong>de</strong>ntes d'ODBC, exceptée la version 3. A partir <strong>de</strong> la version 3,<br />
la fonction SQLError, obsolète, a été remplacée par la fonction<br />
SQLGetDiagRec.<br />
Chaque fonction ODBC renvoie une valeur SQLRETURN, qui est l'un <strong>de</strong>s<br />
co<strong>de</strong>s d'état suivants :<br />
Co<strong>de</strong> d'état Description<br />
SQL_SUCCESS Aucune erreur.<br />
SQL_SUCCESS_WITH_INFO La fonction s'est exécutée en totalité, mais un<br />
appel adressé à SQLError indique un<br />
avertissement.<br />
Le plus souvent, cet état indique qu'une valeur<br />
renvoyée est trop longue pour le buffer fourni par<br />
l'application.<br />
SQL_ERROR La fonction ne s'est pas exécutée en raison d'une<br />
erreur. Vous pouvez appeler SQLError pour<br />
obtenir plus d'informations.<br />
SQL_INVALID_HANDLE Un <strong>de</strong>scripteur d'environnement, <strong>de</strong> connexion ou<br />
d'instruction incorrect a été transmis en tant que<br />
paramètre.<br />
Une erreur <strong>de</strong> ce type se produit souvent lorsqu'un<br />
<strong>de</strong>scripteur est utilisé après avoir été libéré ou<br />
lorsque le <strong>de</strong>scripteur est le pointeur NULL.<br />
SQL_NO_DATA_FOUND Aucune information n'est disponible.<br />
Cet état, qui se rencontre principalement lors <strong>de</strong><br />
l'extraction à partir d'un curseur, indique que le<br />
curseur ne contient plus aucune ligne.<br />
SQL_NEED_DATA Un paramètre requiert <strong>de</strong>s données.<br />
Il s'agit là d'une fonctionnalité avancée dont vous<br />
trouverez la <strong>de</strong>scription dans la<br />
documentation SDK ODBC sous les rubriques<br />
SQLParamData et SQLPutData.
Exemple 1<br />
Chapitre 7 Programmation avec ODBC<br />
A chaque <strong>de</strong>scripteur d’environnement, <strong>de</strong> connexion ou d’instruction<br />
peuvent être associés un(e) ou plusieurs avertissements ou erreurs. Chaque<br />
appel à SQLError ou à SQLGetDiagRec renvoie les informations<br />
correspondant à une erreur donnée, puis supprime ces <strong>de</strong>rnières. Si vous<br />
n'appelez pas SQLError ou SQLGetDiagRec pour supprimer toutes les<br />
erreurs, la suppression s'effectue lors <strong>de</strong> l'appel <strong>de</strong> fonction suivant<br />
transmettant le même <strong>de</strong>scripteur en tant que paramètre.<br />
Chaque appel à SQLError transmet trois <strong>de</strong>scripteurs pour un<br />
environnement, une connexion et une instruction. Le premier appel utilise<br />
SQL_NULL_HSTMT pour obtenir l'erreur associée à une connexion. De<br />
même, SQL_NULL_DBC et SQL_NULL_HSTMT détectent toute erreur<br />
associée au <strong>de</strong>scripteur d'environnement.<br />
Chaque appel à SQLGetDiagRec peut transmettre un <strong>de</strong>scripteur soit pour<br />
un environnement, soit pour une connexion, soit pour une instruction. Le<br />
premier appel transmet un <strong>de</strong>scripteur <strong>de</strong> type SQL_HANDLE_DBC pour<br />
obtenir l'erreur associée à une connexion. Le <strong>de</strong>uxième appel transmet un<br />
<strong>de</strong>scripteur <strong>de</strong> type SQL_HANDLE_STMT pour obtenir l'erreur associée à<br />
l'instruction qui vient d'être exécutée.<br />
SQLError et SQLGetDiagRec renvoient SQL_SUCCESS s'il y a une<br />
erreur à signaler (et non pas SQL_ERROR), et SQL_NO_DATA_FOUND<br />
s'il n'y a plus d'erreurs à signaler.<br />
Ce fragment <strong>de</strong> co<strong>de</strong> utilise SQLError et <strong>de</strong>s co<strong>de</strong>s <strong>de</strong> retour :<br />
/* Déclare les variables requises */<br />
SQLHDBC dbc;<br />
SQLHSTMT stmt;<br />
SQLRETURN retco<strong>de</strong>;<br />
UCHAR errmsg[100];<br />
/* co<strong>de</strong> omis ici */<br />
retco<strong>de</strong> = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt );<br />
if( retco<strong>de</strong> == SQL_ERROR ){<br />
SQLError( env, dbc, SQL_NULL_HSTMT, NULL, NULL,<br />
errmsg, sizeof(errmsg), NULL );<br />
/* Suppose que print_error est défini */<br />
print_error( "Echec <strong>de</strong> l'allocation", errmsg );<br />
return;<br />
}<br />
/* Supprime <strong>de</strong>s articles <strong>de</strong> la comman<strong>de</strong> 2015 */<br />
retco<strong>de</strong> = SQLExecDirect( stmt,<br />
305
Gestion <strong>de</strong>s erreurs<br />
Exemple 2<br />
306<br />
"<strong>de</strong>lete from sales_or<strong>de</strong>r_items where id=2015",<br />
SQL_NTS );<br />
if( retco<strong>de</strong> == SQL_ERROR ) {<br />
SQLError( env, dbc, stmt, NULL, NULL,<br />
errmsg, sizeof(errmsg), NULL );<br />
/* Suppose que print_error est défini */<br />
print_error( "Impossible <strong>de</strong> supprimer les articles",<br />
errmsg );<br />
return;<br />
L’extrait <strong>de</strong> co<strong>de</strong> suivant utilise SQLGetDiagRec et les co<strong>de</strong>s <strong>de</strong> retour:<br />
/* Declare les variables requises */<br />
SQLHDBC dbc;<br />
SQLHSTMT stmt;<br />
SQLRETURN retco<strong>de</strong>;<br />
SQLSMALLINT errmsglen;<br />
SQLINTEGER errnative;<br />
UCHAR errmsg[255];<br />
UCHAR errstate[5];<br />
/* co<strong>de</strong> omis ici */<br />
retco<strong>de</strong> = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt );<br />
if( retco<strong>de</strong> == SQL_ERROR ){<br />
SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, errstate,<br />
&errnative, errmsg, sizeof(errmsg), &errmsglen);<br />
/* Suppose que print_error est défini */<br />
print_error( "Echec <strong>de</strong> l'allocation", errstate,<br />
errnative, errmsg );<br />
return;<br />
}<br />
/* Supprime <strong>de</strong>s articles <strong>de</strong> la comman<strong>de</strong> 2015 */<br />
retco<strong>de</strong> = SQLExecDirect( stmt,<br />
"<strong>de</strong>lete from sales_or<strong>de</strong>r_items where id=2015",<br />
SQL_NTS );
Chapitre 7 Programmation avec ODBC<br />
if( retco<strong>de</strong> == SQL_ERROR ) {<br />
SQLGetDiagRec(SQL_HANDLE_STMT, stmt, recnum,<br />
errstate,<br />
&errnative, errmsg, sizeof(errmsg), &errmsglen);<br />
/* Suppose que print_error est défini */<br />
print_error("Impossible <strong>de</strong> supprimer les articles",<br />
errstate,<br />
errnative, errmsg );<br />
return;<br />
}<br />
307
Gestion <strong>de</strong>s erreurs<br />
308
CHAPITRE 8<br />
Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Présentation<br />
Sommaire<br />
Ce chapitre explique comment utiliser la bibliothèque d'outils <strong>de</strong> base <strong>de</strong><br />
données fournie avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> pour ajouter <strong>de</strong>s<br />
fonctionnalités <strong>de</strong> gestion <strong>de</strong> bases <strong>de</strong> données à <strong>de</strong>s applications en<br />
langage C ou C++.<br />
Sujet Page<br />
Introduction à l'interface Outils <strong>de</strong> base <strong>de</strong> données 310<br />
Utilisation <strong>de</strong> l'interface Outils <strong>de</strong> base <strong>de</strong> données 311<br />
Fonctions DBTools 320<br />
Structures DBTools 332<br />
Types d'énumération DBTools 364<br />
309
Introduction à l'interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Introduction à l'interface Outils <strong>de</strong> base <strong>de</strong><br />
données<br />
Plates-formes<br />
supportées<br />
Windows CE<br />
Fichier d'en-tête<br />
dbtools.h<br />
310<br />
Pour gérer les bases <strong>de</strong> données, <strong>Sybase</strong> <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est livré<br />
avec <strong>Sybase</strong> Central et avec un ensemble d'utilitaires. Ces outils permettent<br />
d'effectuer <strong>de</strong>s tâches telles que la création et la sauvegar<strong>de</strong> <strong>de</strong> bases <strong>de</strong><br />
données, la conversion <strong>de</strong> journaux <strong>de</strong> transactions en SQL, etc.<br />
Tous les utilitaires <strong>de</strong> gestion <strong>de</strong> bases <strong>de</strong> données exploitent une<br />
bibliothèque partagée appelée bibliothèque d'outils <strong>de</strong> base <strong>de</strong> données. Une<br />
version est fournie pour chacun <strong>de</strong>s systèmes d'exploitation suivants :<br />
Windows 95/98 et Windows NT. Le nom <strong>de</strong> cette bibliothèque est<br />
dbtool8.dll.<br />
La bibliothèque d'outils <strong>de</strong> base <strong>de</strong> données vous permet <strong>de</strong> développer vos<br />
propres utilitaires <strong>de</strong> gestion <strong>de</strong> bases <strong>de</strong> données ou d'intégrer <strong>de</strong> telles<br />
fonctionnalités dans vos applications. Ce chapitre décrit l'interface <strong>de</strong> la<br />
bibliothèque d'outils <strong>de</strong> base <strong>de</strong> données. A cet effet, vous <strong>de</strong>vez savoir<br />
comment appeler <strong>de</strong>s DLL à partir <strong>de</strong> votre environnement <strong>de</strong><br />
développement.<br />
La bibliothèque d'outils <strong>de</strong> base <strong>de</strong> données offre <strong>de</strong>s fonctions, ou points<br />
d'entrée, pour chaque utilitaire <strong>de</strong> gestion <strong>de</strong> bases <strong>de</strong> données. Elle contient,<br />
en outre, <strong>de</strong>s fonctions supplémentaires <strong>de</strong>vant être appelées avant ou après<br />
l'utilisation d'autres fonctions d'outils <strong>de</strong> base <strong>de</strong> données.<br />
La bibliothèque dbtool8.dll est fournie pour Windows CE, mais comprend<br />
uniquement <strong>de</strong>s points d'entrée pour DBToolsInit, DBToolsFini,<br />
DBRemoteSQL et DBSynchronizeLog. Les autres outils ne sont pas fournis<br />
pour Windows CE.<br />
Le fichier d'en-tête dbtools fourni avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> répertorie<br />
les points d'entrée <strong>de</strong> la bibliothèque DBTools, ainsi que les structures<br />
servant à échanger <strong>de</strong>s informations avec la bibliothèque. Le fichier dbtools.h<br />
est installé dans le sous-répertoire h du répertoire d'installation. Consultez le<br />
fichier dbtools.h pour obtenir <strong>de</strong>s informations récentes sur les points<br />
d'entrée et le contenu <strong>de</strong> la structure.<br />
Le fichier d'en-tête dbtools.h fait appel à <strong>de</strong>ux autres fichiers :<br />
♦ sqlca.h Ce fichier est inclus pour exploiter certaines macros et non la<br />
zone <strong>de</strong> communication SQL (SQLCA) proprement dite.<br />
♦ dllapi.h Ce fichier définit <strong>de</strong>s macros <strong>de</strong> préprocesseur utilisables dans<br />
<strong>de</strong>s macros propres à un système d'exploitation ou à une langue.<br />
Le fichier d'en-tête sql<strong>de</strong>f.h comporte <strong>de</strong>s valeurs <strong>de</strong> co<strong>de</strong> d'erreur.
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Utilisation <strong>de</strong> l’interface Outils <strong>de</strong> base <strong>de</strong><br />
données<br />
Cette section explique comment développer <strong>de</strong>s applications utilisant<br />
l'interface DBTools pour gérer <strong>de</strong>s bases <strong>de</strong> données.<br />
Utilisation <strong>de</strong>s bibliothèques d'importation<br />
Plates-formes<br />
supportées<br />
Pour pouvoir utiliser les fonctions DBTools, vous <strong>de</strong>vez relier votre<br />
application à une bibliothèque d'importation DBTools contenant la<br />
définition <strong>de</strong>s fonctions requises.<br />
Les bibliothèques d'importation sont spécifiques d'un compilateur et sont<br />
fournies pour les systèmes d'exploitation Windows excepté Windows CE.<br />
Celles <strong>de</strong> l'interface DBTools, fournies avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, se<br />
trouvent dans le sous-répertoire lib <strong>de</strong> chaque répertoire <strong>de</strong> système<br />
d'exploitation (lui-même dans le répertoire d'installation<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>). Les bibliothèques fournies sont les suivantes :<br />
Compilateur Bibliothèque<br />
Watcom win32\dbtlstw.lib<br />
Microsoft win32\dbtlstM.lib<br />
Borland win32\dbtlstB.lib<br />
Démarrage et arrêt <strong>de</strong> la bibliothèque DBTools<br />
Avant d'utiliser toute fonction DBTools, il est nécessaire d'appeler<br />
DBToolsInit. Lorsque vous n'avez plus besoin <strong>de</strong> la bibliothèque, vous <strong>de</strong>vez<br />
appeler DBToolsFini.<br />
Le principal objet <strong>de</strong>s fonctions DBToolsInit et DBToolsFini est <strong>de</strong><br />
permettre à la DLL DBTools <strong>de</strong> charger la DLL <strong>de</strong> langue<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Cette <strong>de</strong>rnière contient la version localisée <strong>de</strong><br />
tous les messages d'erreur et <strong>de</strong> toutes les invites utilisés en interne par<br />
DBTools. Si vous n'appelez pas DBToolsFini, le compteur <strong>de</strong> références <strong>de</strong><br />
la DLL <strong>de</strong> langue n'est pas décrémenté et la DLL n'est pas déchargée. Par<br />
conséquent, veillez à ce que chaque appel <strong>de</strong> DBToolsInit soit suivi d'un<br />
appel <strong>de</strong> DBToolsFini.<br />
La portion <strong>de</strong> co<strong>de</strong> suivante indique comment initialiser et vi<strong>de</strong>r DBTools :<br />
311
Utilisation <strong>de</strong> l'interface Outils <strong>de</strong> base <strong>de</strong> données<br />
312<br />
// Déclarations<br />
a_dbtools_info info;<br />
short ret;<br />
Appel <strong>de</strong>s fonctions DBTools<br />
// Initialisation <strong>de</strong> la structure a_dbtools_info<br />
memset( &info, 0, sizeof( a_dbtools_info) );<br />
info.errorrtn = (MSG_CALLBACK)MaRoutineErreur;<br />
// Initialisation <strong>de</strong> DBTools<br />
ret = DBToolsInit( &info );<br />
if( ret != EXIT_OKAY ) {<br />
// Echec d'initialisation <strong>de</strong> la DLL<br />
…<br />
}<br />
// Appel <strong>de</strong> diverses routines DBTools . . .<br />
…<br />
// Réinitialisation <strong>de</strong> la DLL DBTools<br />
DBToolsFini( &info );<br />
Pour pouvoir exécuter chaque outil, il faut d'abord renseigner une structure,<br />
puis appeler une fonction (ou point d'entrée) <strong>de</strong> la DLL DBTools. Tous les<br />
points d'entrée requièrent un pointeur sur une structure unique comme<br />
argument.<br />
L'exemple ci-<strong>de</strong>ssous indique comment utiliser la fonction DBBackup sous<br />
un système d'exploitation Windows. Il est <strong>de</strong>stiné aux systèmes<br />
d'exploitation Windows 95 ou Windows NT.<br />
// Initialisation <strong>de</strong> la structure<br />
a_backup_db backup_info;<br />
memset( &backup_info, 0, sizeof( backup_info ) );<br />
// Configuration <strong>de</strong> la structure<br />
backup_info.version = DB_TOOLS_VERSION_NUMBER;<br />
backup_info.output_dir = "C:\BACKUP";<br />
backup_info.connectparms<br />
="uid=DBA;pwd=SQL;dbf=asa<strong>de</strong>mo.db";<br />
backup_info.startline = "dbeng8.EXE";<br />
backup_info.confirmrtn = (MSG_CALLBACK) ConfirmRtn ;<br />
backup_info.errorrtn = (MSG_CALLBACK) ErrorRtn ;<br />
backup_info.msgrtn = (MSG_CALLBACK) MessageRtn ;<br />
backup_info.statusrtn = (MSG_CALLBACK) StatusRtn ;<br />
backup_info.backup_database = TRUE;<br />
// Lancement <strong>de</strong> la sauvegar<strong>de</strong><br />
DBBackup( &backup_info );
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
$ Pour plus d'informations sur les éléments <strong>de</strong>s structures DBTools,<br />
reportez-vous à la section "Structures DBTools", page 332.<br />
Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s composants logiciels<br />
Tous les outils <strong>de</strong> base <strong>de</strong> données sont fournis comme point d'entrée dans<br />
une DLL. Ces points d'entrée utilisent les co<strong>de</strong>s <strong>de</strong> retour suivants :<br />
Co<strong>de</strong> Explication<br />
0 Succès<br />
1 Panne générale<br />
2 Format <strong>de</strong> fichier incorrect<br />
3 Fichier introuvable, impossible d'ouvrir<br />
4 Mémoire saturée<br />
5 Terminé par l'utilisateur<br />
6 Echec <strong>de</strong> la communication<br />
7 Nom <strong>de</strong> base <strong>de</strong> données requis manquant<br />
8 Discordance entre les protocoles client et serveur<br />
9 Impossible <strong>de</strong> se connecter au serveur <strong>de</strong> base <strong>de</strong> données<br />
10 Le serveur <strong>de</strong> base <strong>de</strong> données ne fonctionne pas<br />
11 Impossible <strong>de</strong> trouver le serveur <strong>de</strong> base <strong>de</strong> données<br />
254 Temps d'arrêt atteint<br />
Utilisation <strong>de</strong>s fonctions callback<br />
Utilisation <strong>de</strong>s<br />
fonctions callback<br />
255 Paramètres incorrects sur la ligne <strong>de</strong> comman<strong>de</strong><br />
Plusieurs éléments <strong>de</strong>s structures DBTools sont <strong>de</strong> type MSG_CALLBACK.<br />
Il s'agit <strong>de</strong> pointeurs sur <strong>de</strong>s fonctions callback.<br />
Les fonctions callback permettent aux fonctions DBTools <strong>de</strong> rendre le<br />
contrôle <strong>de</strong>s opérations à l'application appelante. La bibliothèque DBTools<br />
s'en sert dans quatre situations précises pour gérer les messages envoyés par<br />
les fonctions DBTools à l'utilisateur :<br />
♦ Confirmation Appelée lorsqu'une opération doit être confirmée par<br />
l'utilisateur. Si, par exemple, le répertoire <strong>de</strong> sauvegar<strong>de</strong> n'existe pas, la<br />
DLL <strong>de</strong>s outils <strong>de</strong>man<strong>de</strong> s'il doit être créé.<br />
313
Utilisation <strong>de</strong> l'interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Affectation d’une<br />
fonction callback à<br />
une structure<br />
Exemple <strong>de</strong><br />
fonction callback<br />
<strong>de</strong> confirmation<br />
Exemple <strong>de</strong><br />
fonction callback<br />
d'erreur<br />
314<br />
♦ Message d’erreur Fonction appelée pour transmettre un message<br />
lorsqu'une erreur se produit (par exemple, un espace disque insuffisant<br />
lors d'une opération d'enregistrement).<br />
♦ Message d’information Fonction appelée pour permettre aux outils<br />
d'afficher un message <strong>de</strong>stiné à l'utilisateur (tel que le nom <strong>de</strong> la table en<br />
cours <strong>de</strong> sauvegar<strong>de</strong>).<br />
♦ Informations d'état Fonction appelée pour permettre aux outils<br />
d'afficher l'état d'une opération (tel que le pourcentage atteint lors du<br />
déchargement d'une table).<br />
Vous pouvez affecter directement une routine callback à une structure.<br />
L'exemple suivant montre une instruction utilisant une structure <strong>de</strong><br />
sauvegar<strong>de</strong> :<br />
backup_info.errorrtn = (MSG_CALLBACK) MaFonction<br />
MSG_CALLBACK est défini dans le fichier d'en-tête dllapi.h fourni avec<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Les routines <strong>de</strong>s outils peuvent renvoyer <strong>de</strong>s<br />
messages à l'application appelante pour que celle-ci les affiche dans<br />
l'interface utilisateur adéquate (qu'il s'agisse d'un environnement interface<br />
utilisateur, <strong>de</strong> l'affichage standard sur <strong>de</strong>s systèmes en mo<strong>de</strong> caractère ou <strong>de</strong><br />
toute autre interface utilisateur).<br />
L'exemple <strong>de</strong> routine <strong>de</strong> confirmation suivant invite l'utilisateur à<br />
sélectionner OUI ou NON et renvoie son choix :<br />
extern short _callback ConfirmRtn(<br />
char far * question )<br />
{<br />
int ret;<br />
if( question != NULL ) {<br />
ret = MessageBox( HwndParent, question,<br />
"Confirmez", MB_ICONEXCLAMTION|MB_YESNO );<br />
}<br />
return( 0 );<br />
}<br />
Exemple <strong>de</strong> routine <strong>de</strong> gestion <strong>de</strong>s messages d'erreur affichant les messages<br />
dans une boîte <strong>de</strong> message.<br />
extern short _callback ErrorRtn(<br />
char far * errorstr )<br />
{<br />
if( errorstr != NULL ) {<br />
ret = MessageBox( HwndParent, errorstr,<br />
"Erreur <strong>de</strong> sauvegar<strong>de</strong>", MB_ICONSTOP|MB_OK );<br />
}<br />
return( 0 );<br />
}
Exemple <strong>de</strong><br />
fonction callback<br />
<strong>de</strong> message<br />
Exemple <strong>de</strong><br />
fonction callback<br />
d'état<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Exemple <strong>de</strong> mise en oeuvre courante d’une fonction callback affichant un<br />
message à l'écran :<br />
extern short _callback MessageRtn(<br />
char far * errorstr )<br />
{<br />
if( messagestr != NULL ) {<br />
OutputMessageToWindow( messagestr );<br />
}<br />
return( 0 );<br />
}<br />
Une routine callback d'état est appelée lorsque les outils doivent afficher<br />
l'état d'une opération (tel que le pourcentage atteint lors du déchargement<br />
d'une table). Ici encore, une mise en oeuvre courante affiche simplement le<br />
message à l'écran :<br />
extern short _callback StatusRtn(<br />
char far * statusstr )<br />
{<br />
if( statusstr == NULL ) {<br />
return FALSE;<br />
}<br />
OutputMessageToWindow( statustr );<br />
return TRUE;<br />
}<br />
Numéros <strong>de</strong> version et compatibilité<br />
Compatibilité<br />
Chaque structure possè<strong>de</strong> un élément indiquant le numéro <strong>de</strong> version. Il est<br />
recommandé <strong>de</strong> l'employer pour indiquer la version <strong>de</strong> la bibliothèque<br />
DBTools avec laquelle votre application a été développée. La version<br />
actuelle <strong>de</strong> la bibliothèque est incluse sous la forme d'une constante dans le<br />
fichier d'en-tête dbtools.h.<br />
v Pour affecter le numéro <strong>de</strong> version courant à une structure :<br />
♦ Avant d'appeler la fonction DBTools, affectez la constante <strong>de</strong> version à<br />
l'élément <strong>de</strong> version <strong>de</strong> la structure. L'instruction suivante affecte la<br />
version courante à une structure <strong>de</strong> sauvegar<strong>de</strong> :<br />
backup_info.version = DB_TOOLS_VERSION_NUMBER;<br />
Le numéro <strong>de</strong> version permet à votre application <strong>de</strong> continuer à fonctionner<br />
avec <strong>de</strong>s versions plus récentes <strong>de</strong> la bibliothèque DBTools. Les fonctions<br />
DBTools utilisent le numéro fourni par l'application pour assurer la bonne<br />
exécution <strong>de</strong> celle-ci, même si <strong>de</strong> nouveaux éléments ont été ajoutés dans la<br />
structure DBTools.<br />
315
Utilisation <strong>de</strong> l'interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Utilisation <strong>de</strong> champs <strong>de</strong> bits<br />
Exemple DBTools<br />
316<br />
Les applications ne fonctionneront pas avec <strong>de</strong>s versions antérieures <strong>de</strong> la<br />
bibliothèque DBTools.<br />
De nombreuses structures DBTools utilisent <strong>de</strong>s champs <strong>de</strong> bits pour stocker<br />
<strong>de</strong>s informations booléennes <strong>de</strong> façon compacte. Par exemple, la structure <strong>de</strong><br />
sauvegar<strong>de</strong> comporte les champs <strong>de</strong> bits suivants :<br />
a_bit_field backup_database : 1;<br />
a_bit_field backup_logfile : 1;<br />
a_bit_field backup_writefile: 1;<br />
a_bit_field no_confirm : 1;<br />
a_bit_field quiet : 1;<br />
a_bit_field rename_log : 1;<br />
a_bit_field truncate_log : 1;<br />
a_bit_field rename_local_log: 1;<br />
Dans cet exemple, chaque champ <strong>de</strong> bits a une longueur d'un seul bit, comme<br />
l'indique le chiffre 1, à gauche du point-virgule, dans la déclaration <strong>de</strong> la<br />
structure. Le type <strong>de</strong> données spécifique utilisé dépend <strong>de</strong> la valeur affectée à<br />
a_bit_field, qui est définie au début du fichier dbtools.h et dépend du<br />
système d'exploitation.<br />
Pour transmettre <strong>de</strong>s informations booléennes à la structure, il faut affecter la<br />
valeur entière 0 ou 1 à un champ <strong>de</strong> bits.<br />
Cet exemple, ainsi que les instructions <strong>de</strong> compilation, sont disponibles dans<br />
le sous-répertoire Samples\ASA\DBTools du répertoire SQL <strong>Anywhere</strong>. Le<br />
programme exemple s'intitule Samples\ASA\DBTools\main.c. Il indique<br />
comment utiliser la bibliothèque DBTools pour effectuer une sauvegar<strong>de</strong> <strong>de</strong><br />
la base <strong>de</strong> données.<br />
#<strong>de</strong>fine WINNT
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> "windows.h"<br />
#inclu<strong>de</strong> "string.h"<br />
#inclu<strong>de</strong> "dbtools.h"<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
extern short _callback ConfirmCallBack(char far * str){<br />
if( MessageBox( NULL, str, "Backup",<br />
MB_YESNO|MB_ICONQUESTION ) == IDYES ) {<br />
return 1;<br />
}<br />
return 0;<br />
}<br />
extern short _callback MessageCallBack( char far * str){<br />
if( str != NULL ) {<br />
fprintf( stdout, "%s", str );<br />
fprintf( stdout, "\n" );<br />
fflush( stdout );<br />
}<br />
return 0;<br />
}<br />
extern short _callback StatusCallBack( char far * str ){<br />
if( str != NULL ) {<br />
fprintf( stdout, "%s", str );<br />
fprintf( stdout, "\n" );<br />
fflush( stdout );<br />
}<br />
return 0;<br />
}<br />
extern short _callback ErrorCallBack( char far * str ){<br />
if( str != NULL ) {<br />
fprintf( stdout, "%s", str );<br />
fprintf( stdout, "\n" );<br />
fflush( stdout );<br />
}<br />
return 0;<br />
}<br />
// Point d'entrée principal dans le programme.<br />
int main( int argc, char * argv[] ){<br />
a_backup_db backup_info;<br />
a_dbtools_info dbtinfo;<br />
char dir_name[ _MAX_PATH + 1];<br />
char connect[ 256 ];<br />
HINSTANCE hinst;<br />
FARPROC dbbackup;<br />
FARPROC dbtoolsinit;<br />
FARPROC dbtoolsfini;<br />
317
Utilisation <strong>de</strong> l'interface Outils <strong>de</strong> base <strong>de</strong> données<br />
318<br />
// Toujours initialiser à 0 pour que les<br />
//nouvelles versions <strong>de</strong> la structure soient<br />
compatibles.<br />
memset( &backup_info, 0, sizeof( a_backup_db ) );<br />
backup_info.version = DB_TOOLS_VERSION_8_0_00;<br />
backup_info.quiet = 0;<br />
backup_info.no_confirm = 0;<br />
backup_info.confirmrtn =<br />
(MSG_CALLBACK)ConfirmCallBack;<br />
backup_info.errorrtn = (MSG_CALLBACK)ErrorCallBack;<br />
backup_info.msgrtn = (MSG_CALLBACK)MessageCallBack;<br />
backup_info.statusrtn = (MSG_CALLBACK)StatusCallBack;<br />
if( argc > 1 ) {<br />
strncpy( dir_name, argv[1], _MAX_PATH );<br />
} else {<br />
// DBTools n'accepte pas la barre<br />
// oblique en fin <strong>de</strong> chaîne<br />
strcpy( dir_name, "c:\\temp" );<br />
}<br />
backup_info.output_dir = dir_name;<br />
if( argc > 2 ) {<br />
strncpy( connect, argv[2], 255 );<br />
} else {<br />
// Suppose que le moteur s'exécute déjà.<br />
strcpy( connect, "DSN=ASA 8.0 Sample" );<br />
}<br />
backup_info.connectparms = connect;<br />
backup_info.startline = "";<br />
backup_info.quiet = 0;<br />
backup_info.no_confirm = 0;<br />
backup_info.backup_database = 1;<br />
backup_info.backup_logfile = 1;<br />
backup_info.backup_writefile = 1;<br />
backup_info.rename_log = 0;<br />
backup_info.truncate_log = 0;<br />
hinst = LoadLibrary( "dbtool8.dll" );<br />
if( hinst == NULL ) {<br />
// Echec<br />
return 0;<br />
}
}<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
dbtinfo.errorrtn = (MSG_CALLBACK)ErrorCallBack;<br />
dbbackup = GetProcAddress( (HMODULE)hinst,<br />
"_DBBackup@4" );<br />
dbtoolsinit = GetProcAddress( (HMODULE)hinst,<br />
"_DBToolsInit@4" );<br />
dbtoolsfini = GetProcAddress( (HMODULE)hinst,<br />
"_DBToolsFini@4" );<br />
(*dbtoolsinit)( &dbtinfo );<br />
(*dbbackup)( &backup_info );<br />
(*dbtoolsfini)( &dbtinfo );<br />
FreeLibrary( hinst );<br />
return 0;<br />
319
Fonctions DBTools<br />
Fonctions DBTools<br />
Fonction DBBackup<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
320<br />
La présente section décrit les fonctions disponibles dans la bibliothèque<br />
DBTools. Elles sont répertoriées dans l'ordre alphabétique.<br />
Sauvegar<strong>de</strong> <strong>de</strong> base <strong>de</strong> données. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong> dbbackup.<br />
short DBBackup ( const a_backup_db * bd_sauvegar<strong>de</strong> );<br />
Paramètre Description<br />
bd_sauvegar<strong>de</strong> Pointeur sur "Structure a_backup_db", page 332<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
La fonction DBBackup gère toutes les tâches <strong>de</strong> sauvegar<strong>de</strong> <strong>de</strong> base <strong>de</strong><br />
données.<br />
$ Pour plus d'informations sur ces tâches, reportez-vous à la section<br />
"Utilitaire <strong>de</strong> sauvegar<strong>de</strong> d'une base <strong>de</strong> données", page 470 du document<br />
ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure a_backup_db", page 332<br />
Fonction DBChangeLogName<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Modifie le nom <strong>de</strong> fichier du journal <strong>de</strong> transactions. Employée par l'utilitaire<br />
<strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dblog.<br />
short DBChangeLogName ( const a_change_log * journal_transactions );<br />
Paramètre Description<br />
journal_transactions Pointeur sur "Structure a_change_log", page 334<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
L'option -t <strong>de</strong> l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dblog permet <strong>de</strong> changer le<br />
nom du journal <strong>de</strong> transactions. DBChangeLogName fournit une interface <strong>de</strong><br />
<strong>programmation</strong> pour cette fonction.
Voir aussi<br />
Fonction DBChangeWriteFile<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBCollate<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
$ Pour une <strong>de</strong>scription <strong>de</strong> l’utilitaire dblog, reportez-vous à la section<br />
"Utilitaire <strong>de</strong> gestion <strong>de</strong>s journaux <strong>de</strong> transactions", page 550 du document<br />
ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure a_change_log", page 334<br />
Modifie un fichier d'écriture pour qu'il fasse référence à un autre fichier <strong>de</strong><br />
base <strong>de</strong> données. Cette fonction est employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong> dbwrite lorsque l'option -d est appliquée.<br />
short DBChangeWriteFile ( const a_writefile * fichier_écriture );<br />
Paramètre Description<br />
fichier_écriture Pointeur sur "Structure a_writefile", page 361<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> création <strong>de</strong> fichiers d'écriture<br />
et sur ses fonctionnalités, reportez-vous à la section "Utilitaire <strong>de</strong> création<br />
d'un fichier d'écriture", page 578 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Fonction DBCreateWriteFile", page 323<br />
"Fonction DBStatusWriteFile", page 326<br />
"Structure a_writefile", page 361<br />
Extrait un ordre <strong>de</strong> classement d'une base <strong>de</strong> données.<br />
short DBCollate ( const a_db_collation * classement_bd );<br />
Paramètre Description<br />
classement_bd Pointeur sur "Structure a_db_collation", page 341<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> classement et sur ses<br />
fonctionnalités, reportez-vous à la section "Utilitaire <strong>de</strong> classement",<br />
page 475 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
321
Fonctions DBTools<br />
Voir aussi<br />
Fonction DBCompress<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBCreate<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
322<br />
"Structure a_db_collation", page 341<br />
Compacte un fichier <strong>de</strong> base <strong>de</strong> données. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong> dbshrink.<br />
short DBCompress ( const a_compress_db * bd_compactée );<br />
Paramètre Description<br />
bd_compactée Pointeur sur "Structure a_compress_db", page 336<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> compactage et sur ses<br />
fonctionnalités, reportez-vous à la section "Utilitaire <strong>de</strong> compactage d'une<br />
base <strong>de</strong> données", page 481 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure a_compress_db", page 336<br />
Crée une base <strong>de</strong> données. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong><br />
dbinit.<br />
short DBCreate ( const a_create_db * bd_créée );<br />
Paramètre Description<br />
bd_créée Pointeur sur "Structure a_create_db", page 338<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> création, reportez-vous à la<br />
section "Utilitaire <strong>de</strong> création d'une base <strong>de</strong> données", page 501 du document<br />
ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure a_create_db", page 338
Fonction DBCreateWriteFile<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBCrypt<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBErase<br />
Fonction<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Crée un fichier d'écriture. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong><br />
dbwrite lorsque l'option -c est appliquée.<br />
short DBCreateWriteFile ( const a_writefile * fichier_écriture );<br />
Paramètre Description<br />
fichier_écriture Pointeur sur "Structure a_writefile", page 361<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> création <strong>de</strong> fichiers d'écriture<br />
et sur ses fonctionnalités, reportez-vous à la section "Utilitaire <strong>de</strong> création<br />
d'un fichier d'écriture", page 578 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Fonction DBChangeWriteFile", page 321<br />
"Fonction DBStatusWriteFile", page 326<br />
"Structure a_writefile", page 361<br />
Crypte un fichier <strong>de</strong> base <strong>de</strong> données. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong> dbinit lorsque les options -e sont appliquées.<br />
short DBCrypt ( const a_crypt_db * bd_cryptée );<br />
Paramètre Description<br />
bd_cryptée Pointeur sur "Structure a_crypt_db", page 340<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur le cryptage <strong>de</strong>s bases <strong>de</strong> données, reportezvous<br />
à la section "Création d'une base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> l'utilitaire<br />
dbinit", page 502 du document ASA <strong>Gui<strong>de</strong></strong> d’administration<br />
"Structure a_crypt_db", page 340<br />
Supprime un fichier <strong>de</strong> base <strong>de</strong> données et/ou un fichier <strong>de</strong> journal <strong>de</strong><br />
transactions. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dberase.<br />
323
Fonctions DBTools<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBExpand<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBInfo<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
324<br />
short DBErase ( const an_erase_db * bd_supprimée );<br />
Paramètre Description<br />
bd_supprimée Pointeur sur "Structure an_erase_db", page 347<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> suppression et sur ses<br />
fonctionnalités, reportez-vous à la section "Utilitaire <strong>de</strong> suppression d'une<br />
base <strong>de</strong> données", page 494 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure an_erase_db", page 347<br />
Décompacte un fichier <strong>de</strong> base <strong>de</strong> données. Employée par l'utilitaire <strong>de</strong> ligne<br />
<strong>de</strong> comman<strong>de</strong> dbexpand.<br />
short DBExpand ( const an_expand_db * bd_décompactée );<br />
Paramètre Description<br />
bd_décompactée Pointeur sur "Structure an_expand_db", page 348<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> décompactage et sur ses<br />
fonctionnalités, reportez-vous à la section "Utilitaire <strong>de</strong> décompactage d'une<br />
base <strong>de</strong> données", page 555 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure an_expand_db", page 348<br />
Renvoie <strong>de</strong>s informations relatives à un fichier <strong>de</strong> base <strong>de</strong> données.<br />
Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dbinfo.<br />
short DBInfo ( const a_db_info * infos_bd );<br />
Paramètre Description<br />
infos_bd Pointeur sur "Structure a_db_info", page 343
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBInfoDump<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBInfoFree<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire d'information et sur ses<br />
fonctionnalités, reportez-vous à la section "Utilitaire Informations", page 499<br />
du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Fonction DBInfoDump", page 325<br />
"Fonction DBInfoFree", page 325<br />
"Structure a_db_info", page 343<br />
Renvoie <strong>de</strong>s informations relatives à un fichier <strong>de</strong> base <strong>de</strong> données.<br />
Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dbinfo lorsque l'option -u est<br />
utilisée.<br />
short DBInfoDump ( const a_db_info * infos_bd );<br />
Paramètre Description<br />
infos_bd Pointeur sur "Structure a_db_info", page 343<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire d'information et sur ses<br />
fonctionnalités, reportez-vous à la section "Utilitaire Informations", page 499<br />
du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Fonction DBInfo", page 324<br />
"Fonction DBInfoFree", page 325<br />
"Structure a_db_info", page 343<br />
Libère les ressources après un appel <strong>de</strong> la fonction DBInfoDump.<br />
short DBInfoFree ( const a_db_info * infos_bd );<br />
Paramètre Description<br />
infos_bd Pointeur sur "Structure a_db_info", page 343<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
325
Fonctions DBTools<br />
Utilisation<br />
Voir aussi<br />
Fonction DBLicense<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBStatusWriteFile<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
326<br />
$ Pour plus d’informations sur l’utilitaire d’information et sur ses<br />
fonctionnalités, reportez-vous à la section "Utilitaire Informations", page 499<br />
du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Fonction DBInfo", page 324<br />
"Fonction DBInfoDump", page 325<br />
"Structure a_db_info", page 343<br />
Appelée pour modifier ou afficher les informations <strong>de</strong> licence du serveur <strong>de</strong><br />
base <strong>de</strong> données.<br />
short DBLicense ( const a_db_lic_info * infos_lic_bd );<br />
Paramètre Description<br />
infos_lic_bd Pointeur sur "Structure a_dblic_info", page 346<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire d'information et sur ses<br />
fonctionnalités, reportez-vous à la section "Utilitaire Informations", page 499<br />
du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure a_dblic_info", page 346<br />
Lit l'état d'un fichier d'écriture. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong> dbwrite lorsque l'option -s est utilisée.<br />
short DBStatusWriteFile ( const a_writefile * fichier_écriture );<br />
Paramètre Description<br />
fichier_écriture Pointeur sur "Structure a_writefile", page 361<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> création <strong>de</strong> fichiers d'écriture<br />
et sur ses fonctionnalités, reportez-vous à la section "Utilitaire <strong>de</strong> création<br />
d'un fichier d'écriture", page 578 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.
Voir aussi<br />
Fonction DBSynchronizeLog<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Fonction DBToolsFini<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
"Fonction DBChangeWriteFile", page 321<br />
"Fonction DBCreateWriteFile", page 323<br />
"Structure a_writefile", page 361<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Synchronise une base <strong>de</strong> données avec un serveur <strong>de</strong> synchronisation<br />
MobiLink.<br />
short DBSynchronizeLog( const a _sync_db * bd_sync );<br />
Paramètre Description<br />
bd_sync Pointeur sur "Structure a_sync_db", page 350<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur les fonctionnalités accessibles, reportezvous<br />
à la section "Lancement <strong>de</strong> la synchronisation", page 150 du document<br />
Synchronisation MobiLink <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur.<br />
Décrémente le compteur et libère les ressources lorsqu'une application a<br />
terminé d'utiliser la bibliothèque DBTools.<br />
short DBToolsFini ( const a_dbtools_info * infos_dbtools );<br />
Paramètre Description<br />
infos_dbtools Pointeur sur "Structure a_dbtools_info", page 347<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
La fonction DBToolsFini doit être appelée à la fin <strong>de</strong> toute application<br />
utilisant l'interface DBTools. Dans le cas contraire, vous risquez <strong>de</strong> perdre<br />
<strong>de</strong>s ressources mémoire.<br />
"Fonction DBToolsInit", page 328<br />
"Structure a_dbtools_info", page 347<br />
327
Fonctions DBTools<br />
Fonction DBToolsInit<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Exemple<br />
Voir aussi<br />
Fonction DBToolsVersion<br />
Fonction<br />
Syntaxe<br />
328<br />
Prépare l'utilisation <strong>de</strong> la bibliothèque DBTools.<br />
short DBToolsInit t( const a_dbtools_info * infos_dbtools );<br />
Paramètre Description<br />
infos_dbtools Pointeur sur "Structure a_dbtools_info", page 347<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
Le principal objet <strong>de</strong> la fonction DBToolsInit est <strong>de</strong> charger la DLL <strong>de</strong><br />
langue d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Cette <strong>de</strong>rnière contient la version<br />
localisée <strong>de</strong>s messages d'erreur et <strong>de</strong> toutes les invites utilisées en interne par<br />
DBTools.<br />
La fonction DBToolsInit doit être appelée au début <strong>de</strong> chaque application<br />
utilisant l'interface DBTools, avant toute autre fonction DBTools.<br />
♦ L'exemple <strong>de</strong> co<strong>de</strong> suivant montre comment initialiser et vi<strong>de</strong>r<br />
DBTools :<br />
a_dbtools_info info;<br />
short ret;<br />
memset( &info, 0, sizeof( a_dbtools_info) );<br />
info.errorrtn = (MSG_CALLBACK)MakeProcInstance(<br />
(FARPROC)MyErrorRtn, hInst );<br />
// Initialisation <strong>de</strong> DBTools<br />
ret = DBToolsInit( &info );<br />
if( ret != EXIT_OKAY ) {<br />
// Echec d’initialisation <strong>de</strong> la DLL<br />
…<br />
}<br />
// Appel <strong>de</strong> diverses routines DBTools . . .<br />
…<br />
// Réinitialisation <strong>de</strong> la DLL DBTools<br />
DBToolsFini( &info );<br />
"Fonction DBToolsFini", page 327<br />
"Structure a_dbtools_info", page 347<br />
Renvoie le numéro <strong>de</strong> version <strong>de</strong> la bibliothèque DBTools.<br />
short DBToolsVersion ( void );
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBTranslateLog<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBTruncateLog<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Un entier court indiquant le numéro <strong>de</strong> version <strong>de</strong> la bibliothèque DBTools.<br />
Employez la fonction DBToolsVersion pour vérifier que la bibliothèque<br />
DBTools n'est pas plus ancienne que celle avec laquelle l'application a été<br />
développée. Les applications ne peuvent s'exécuter qu'avec <strong>de</strong>s versions <strong>de</strong><br />
DBTools i<strong>de</strong>ntiques ou plus récentes.<br />
"Numéros <strong>de</strong> version et compatibilité", page 315<br />
Convertit un fichier <strong>de</strong> journal <strong>de</strong> transactions en SQL. Employée par<br />
l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dbtran.<br />
short DBTranslateLog ( const a_translate_log * journal_transactions );<br />
Paramètre Description<br />
journal_transactions Pointeur sur "Structure a_translate_log", page 354<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> conversion, reportez-vous à la<br />
section "Utilitaire <strong>de</strong> conversion du journal <strong>de</strong> transactions", page 529 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure a_translate_log", page 354<br />
Tronque le journal <strong>de</strong> transactions. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong> dbbackup.<br />
short DBTruncateLog ( const a_truncate_log * journal_tronqué );<br />
Paramètre Description<br />
journal_tronqué Pointeur sur "Structure a_truncate_log", page 356<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> sauvegar<strong>de</strong>, reportez-vous à<br />
la section "Utilitaire <strong>de</strong> sauvegar<strong>de</strong> d'une base <strong>de</strong> données", page 470 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
329
Fonctions DBTools<br />
Voir aussi<br />
Fonction DBUnload<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Fonction DBUpgra<strong>de</strong><br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
330<br />
"Structure a_truncate_log", page 356<br />
Décharge une base <strong>de</strong> données. Employée par l'utilitaire <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong> dbunload, ainsi que par l'utilitaire dbxtract pour SQL Remote.<br />
short DBUnload ( const an_unload_db * bd_déchargée );<br />
Paramètre Description<br />
bd_déchargée Pointeur sur "Structure an_unload_db", page 357<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> déchargement, reportez-vous<br />
à la section "Utilitaire <strong>de</strong> déchargement d'une base <strong>de</strong> données", page 558 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure an_unload_db", page 357<br />
Met à niveau un fichier <strong>de</strong> base <strong>de</strong> données. Employée par l'utilitaire <strong>de</strong> ligne<br />
<strong>de</strong> comman<strong>de</strong> dbupgra<strong>de</strong>.<br />
short DBUpgra<strong>de</strong> ( const an_upgra<strong>de</strong>_db * bd_mise_à_niveau );<br />
Paramètre Description<br />
bd_mise_à_niveau Pointeur sur "Structure an_upgra<strong>de</strong>_db", page 359<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> mise à niveau, reportez-vous<br />
à la section "Utilitaire <strong>de</strong> mise à niveau d'une base <strong>de</strong> données", page 568 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure an_upgra<strong>de</strong>_db", page 359
Fonction DBValidate<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Valeur renvoyée<br />
Utilisation<br />
Voir aussi<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Vali<strong>de</strong> une base <strong>de</strong> données entièrement ou partiellement. Employée par<br />
l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dbvalid.<br />
short DBValidate ( const a_validate_db * bd_validée );<br />
Paramètre Description<br />
bd_validée Pointeur sur "Structure a_validate_db", page 360<br />
Un co<strong>de</strong> <strong>de</strong> retour, tel qu'il apparaît dans la liste "Co<strong>de</strong>s <strong>de</strong> retour <strong>de</strong>s<br />
composants logiciels", page 313.<br />
$ Pour plus d'informations sur l'utilitaire <strong>de</strong> validation, reportez-vous à la<br />
section "Utilitaire <strong>de</strong> validation d'une base <strong>de</strong> données", page 574 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
"Structure a_validate_db", page 360<br />
331
Structures DBTools<br />
Structures DBTools<br />
Structure a_backup_db<br />
Fonction<br />
Syntaxe<br />
332<br />
Cette section répertorie les structures utilisées pour échanger <strong>de</strong>s<br />
informations avec la bibliothèque DBTools. Les structures sont répertoriées<br />
dans l'ordre alphabétique.<br />
De nombreux éléments <strong>de</strong> structure correspon<strong>de</strong>nt à <strong>de</strong>s options <strong>de</strong> ligne <strong>de</strong><br />
comman<strong>de</strong> <strong>de</strong> l'utilitaire équivalent. Par exemple, plusieurs structures<br />
comprennent un élément appelé "quiet", qui accepte les valeurs 0 ou 1. Cet<br />
élément correspond à l'option <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> opération non<br />
détaillée (-q), utilisée par un grand nombre d'utilitaires.<br />
Contient les informations requises pour exécuter <strong>de</strong>s tâches <strong>de</strong> sauvegar<strong>de</strong> à<br />
l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
type<strong>de</strong>f struct a_backup_db {<br />
unsigned short version;<br />
const char * output_dir;<br />
const char * connectparms;<br />
const char * startline;<br />
MSG_CALLBACK confirmrtn;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK statusrtn;<br />
a_bit_field backup_database: 1;<br />
a_bit_field backup_logfile : 1;<br />
a_bit_field backup_writefile : 1;<br />
a_bit_field no_confirm : 1;<br />
a_bit_field quiet : 1;<br />
a_bit_field rename_log : 1;<br />
a_bit_field truncate_log : 1;<br />
a_bit_field rename_local_log: 1;<br />
const char * hotlog_filename;<br />
char backup_interrupted;<br />
} a_backup_db;
Paramètres<br />
Voir aussi<br />
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
output_dir Chemin d'accès du répertoire <strong>de</strong> sauvegar<strong>de</strong>. Par exemple :<br />
"c:\backup"<br />
connectparms Paramètres requis pour la connexion à la base <strong>de</strong> données.<br />
Ils se présentent sous la forme <strong>de</strong> chaînes <strong>de</strong> connexion.<br />
Exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\asa\asa<strong>de</strong>mo.db"<br />
$ Pour obtenir l'ensemble <strong>de</strong>s options <strong>de</strong> chaîne <strong>de</strong><br />
connexion, reportez-vous à la section "Paramètres <strong>de</strong><br />
connexion", page 75 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
startline Ligne <strong>de</strong> comman<strong>de</strong> utilisée pour démarrer le moteur <strong>de</strong><br />
bases <strong>de</strong> données. Exemple :<br />
"c:\asa\win32\dbeng8.exe"<br />
Si cet élément est NULL, la ligne <strong>de</strong> démarrage par défaut<br />
est utilisée.<br />
confirmrtn Routine callback <strong>de</strong> confirmation d'une action.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
statusrtn Routine callback <strong>de</strong> gestion d'un message d'état.<br />
backup_database Sauvegar<strong>de</strong> (1) ou non (0) du fichier <strong>de</strong> base <strong>de</strong> données.<br />
backup_logfile Sauvegar<strong>de</strong> (1) ou non (0) du journal <strong>de</strong> transactions.<br />
backup_writefile Sauvegar<strong>de</strong> (1) ou non (0) du fichier d'écriture <strong>de</strong> la base<br />
<strong>de</strong> données, s'il existe.<br />
no_confirm Exécution avec (0) ou sans (1) confirmation.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong><br />
messages.<br />
rename_log Changement <strong>de</strong> nom du journal <strong>de</strong> transactions.<br />
truncate_log Suppression du journal <strong>de</strong> transactions.<br />
rename_local_log Changement <strong>de</strong> nom <strong>de</strong> la sauvegar<strong>de</strong> locale du journal <strong>de</strong><br />
transactions.<br />
hotlog_filename Nom du fichier <strong>de</strong> sauvegar<strong>de</strong> à la volée.<br />
backup_interrupted Indique que l'opération a été interrompue.<br />
"Fonction DBBackup", page 320<br />
333
Structures DBTools<br />
Structure a_change_log<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
334<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour exécuter <strong>de</strong>s tâches dblog à l'ai<strong>de</strong> <strong>de</strong><br />
la bibliothèque DBTools.<br />
type<strong>de</strong>f struct a_change_log {<br />
unsigned short version;<br />
const char * dbname;<br />
const char * logname;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
a_bit_field query_only : 1;<br />
a_bit_field quiet : 1;<br />
a_bit_field mirrorname_present : 1;<br />
a_bit_field change_mirrorname : 1;<br />
a_bit_field change_logname : 1;<br />
a_bit_field ignore_ltm_trunc : 1;<br />
a_bit_field ignore_remote_trunc : 1;<br />
a_bit_field set_generation_number : 1;<br />
a_bit_field ignore_dbsync_trunc : 1;<br />
const char * mirrorname;<br />
unsigned short generation_number;<br />
const char * key_file;<br />
char * zap_current_offset;<br />
char * sap_starting_offset;<br />
char * encryption_key;<br />
} a_change_log;<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
dbname Nom du fichier <strong>de</strong> base <strong>de</strong> données.<br />
logname Nom du journal <strong>de</strong> transactions. Si cet élément est<br />
NULL, aucun journal n'est généré.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message<br />
d'information.<br />
query_only Si 1, affiche simplement le nom du journal <strong>de</strong><br />
transactions. Si 0, permet <strong>de</strong> changer le nom du<br />
journal.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong><br />
messages.
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
mirrorname_present Si 1, indique que la version <strong>de</strong> DBTools est<br />
suffisamment récente pour prendre en charge le champ<br />
mirrorname.<br />
change_mirrorname Si 1, permet <strong>de</strong> changer le nom du fichier miroir du<br />
journal.<br />
change_logname Si 1, permet <strong>de</strong> changer le nom du journal <strong>de</strong><br />
transactions.<br />
ignore_ltm_trunc Lors <strong>de</strong> l'utilisation du gestionnaire <strong>de</strong> transfert <strong>de</strong><br />
journal (LTM), cet élément joue le même rôle que la<br />
fonction dbcc settrunc( 'ltm', 'gen_id', n ) <strong>de</strong><br />
Replication <strong>Server</strong>.<br />
$ Pour obtenir <strong>de</strong>s informations sur dbcc, consultez<br />
la documentation <strong>de</strong> Replication <strong>Server</strong>.<br />
ignore_remote_trunc S'applique à SQL Remote. Remet à zéro l'offset<br />
conservé pour les besoins <strong>de</strong> l'option<br />
DELETE_OLD_LOGS, permettant ainsi la<br />
suppression <strong>de</strong>s journaux <strong>de</strong> transactions lorsqu'ils ne<br />
sont plus nécessaires.<br />
set_generation_number Lors <strong>de</strong> l'utilisation du LTM, cet élément est employé<br />
pour définir le numéro <strong>de</strong> génération après chargement<br />
d'une version <strong>de</strong> sauvegar<strong>de</strong>.<br />
ignore_dbsync_trunc Lors <strong>de</strong> l'utilisation <strong>de</strong> dbmlsync, remet à zéro l'offset<br />
conservé pour les besoins <strong>de</strong> l'option<br />
DELETE_OLD_LOGS, permettant ainsi la<br />
suppression <strong>de</strong>s journaux <strong>de</strong> transactions lorsqu'ils ne<br />
sont plus nécessaires.<br />
mirrorname Nouveau nom du fichier miroir du journal <strong>de</strong><br />
transactions.<br />
335
Structures DBTools<br />
Voir aussi<br />
Structure a_compress_db<br />
Fonction<br />
Syntaxe<br />
336<br />
Elément Description<br />
generation_number Nouveau numéro <strong>de</strong> génération. Utilisé conjointement<br />
à set_generation_number.<br />
key_file Fichier contenant la clé <strong>de</strong> cryptage.<br />
zap_current_offset Modifie l'offset courant en lui attribuant la valeur<br />
spécifiée. Utilisé uniquement pour réinitialiser un<br />
journal <strong>de</strong> transactions après un déchargement et un<br />
rechargement afin qu'il correspon<strong>de</strong> aux paramètres <strong>de</strong><br />
dbremote ou dbmlsync.<br />
zap_starting_offset Modifie l'offset <strong>de</strong> départ en lui attribuant la valeur<br />
spécifiée. Utilisé uniquement pour réinitialiser un<br />
journal <strong>de</strong> transactions après un déchargement et un<br />
rechargement afin qu'il correspon<strong>de</strong> aux paramètres <strong>de</strong><br />
dbremote ou dbmlsync.<br />
encryption_key Clé <strong>de</strong> cryptage du fichier <strong>de</strong> base <strong>de</strong> données.<br />
"Fonction DBChangeLogName", page 320<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour exécuter <strong>de</strong>s tâches <strong>de</strong> compactage à<br />
l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
type<strong>de</strong>f struct a_compress_db {<br />
unsigned short version;<br />
const char * dbname;<br />
const char * compress_name;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK statusrtn;<br />
a_bit_field display_free_pages : 1;<br />
a_bit_field quiet : 1;<br />
a_bit_field record_unchanged : 1;<br />
a_compress_stats * stats;<br />
MSG_CALLBACK confirmrtn;<br />
a_bit_field noconfirm : 1;<br />
const char * encryption_key<br />
} a_compress_db;
Paramètres<br />
Voir aussi<br />
Structure a_compress_stats<br />
Fonction<br />
Syntaxe<br />
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
dbname Nom du fichier <strong>de</strong> la base <strong>de</strong> données à compacter.<br />
compress_name Nom du fichier <strong>de</strong> la base <strong>de</strong> données compacté.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
statusrtn Routine callback <strong>de</strong> gestion d'un message d'état.<br />
display_free_pages Affichage <strong>de</strong>s informations sur les pages disponibles.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong><br />
messages.<br />
record_unchanged Si 1, indique que la structure a_compress_stats est<br />
suffisamment récente pour comporter un élément<br />
unchanged.<br />
a_compress_stats Pointeur sur une structure <strong>de</strong> type a_compress_stats. Cet<br />
élément est renseigné s'il n'est pas NULL et si<br />
display_free_pages est différent <strong>de</strong> zéro.<br />
confirmrtn Routine callback <strong>de</strong> confirmation d'une action.<br />
noconfirm Exécution avec (0) ou sans (1) confirmation.<br />
encryption_key Clé <strong>de</strong> cryptage du fichier <strong>de</strong> base <strong>de</strong> données.<br />
"Fonction DBCompress", page 322<br />
"Structure a_compress_stats", page 337<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient la <strong>de</strong>scription <strong>de</strong>s statistiques relatives au fichier <strong>de</strong> base <strong>de</strong> données<br />
compacté.<br />
type<strong>de</strong>f struct a_compress_stats {<br />
a_stats_line tables;<br />
a_stats_line indices;<br />
a_stats_line other;<br />
a_stats_line free;<br />
a_stats_line total;<br />
a_sql_int32 free_pages;<br />
a_sql_int32 unchanged;<br />
} a_compress_stats;<br />
337
Structures DBTools<br />
Paramètres<br />
Voir aussi<br />
Structure a_create_db<br />
Fonction<br />
338<br />
Elément Description<br />
tables Contient les informations <strong>de</strong> compactage relatives aux tables.<br />
indices Contient les informations <strong>de</strong> compactage relatives aux in<strong>de</strong>x.<br />
other Contient d’autres informations relatives au compactage.<br />
free Contient les informations relatives à l'espace libre.<br />
total Contient les informations globales relatives au compactage.<br />
free_pages Contient les informations relatives aux pages libres.<br />
unchanged Nombre <strong>de</strong> pages que l'algorithme <strong>de</strong> compactage n'est pas<br />
parvenu à réduire.<br />
"Fonction DBCompress", page 322<br />
"Structure a_compress_db", page 336<br />
Contient les informations requises pour créer une base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong><br />
la bibliothèque DBTools.
Syntaxe<br />
Paramètres<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
type<strong>de</strong>f struct a_create_db {<br />
unsigned short version;<br />
const char * dbname;<br />
const char * logname;<br />
const char * startline;<br />
short page_size;<br />
const char * <strong>de</strong>fault_collation;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
short database_version;<br />
char verbose;<br />
a_bit_field blank_pad : 2;<br />
a_bit_field respect_case : 1;<br />
a_bit_field encrypt : 1;<br />
a_bit_field <strong>de</strong>bug : 1;<br />
a_bit_field dbo_avail : 1;<br />
a_bit_field mirrorname_present : 1;<br />
a_bit_field avoid_view_collisions : 1;<br />
short collation_id;<br />
const char * dbo_username;<br />
const char * mirrorname;<br />
const char * encryption_dllname;<br />
a_bit_field java_classes : 1;<br />
a_bit_field jconnect : 1;<br />
const char * data_store_type<br />
const char * encryption_key;<br />
const char * encryption_algorithm;<br />
const char * jdK_version;<br />
} a_create_db;<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
dbname Nom du fichier <strong>de</strong> base <strong>de</strong> données.<br />
logname Nouveau nom du journal <strong>de</strong> transactions.<br />
startline Ligne <strong>de</strong> comman<strong>de</strong> utilisée pour démarrer le moteur <strong>de</strong><br />
bases <strong>de</strong> données. Exemple :<br />
"c:\asa\win32\dbeng8.exe"<br />
Si cet élément est NULL, la ligne <strong>de</strong> démarrage par<br />
défaut est utilisée.<br />
page_size Taille <strong>de</strong>s pages <strong>de</strong> la base <strong>de</strong> données.<br />
<strong>de</strong>fault_collation Ordre <strong>de</strong> classement <strong>de</strong> la base <strong>de</strong> données.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
database_version Numéro <strong>de</strong> version <strong>de</strong> la base <strong>de</strong> données.<br />
339
Structures DBTools<br />
Voir aussi<br />
Structure a_crypt_db<br />
Fonction<br />
340<br />
Elément Description<br />
verbose Exécution en mo<strong>de</strong> détaillé.<br />
blank_pad Les blancs sont considérés comme significatifs dans les<br />
comparaisons <strong>de</strong> chaînes et les in<strong>de</strong>x sont générés en<br />
conséquence.<br />
respect_case Les comparaisons <strong>de</strong> chaînes font la distinction<br />
majuscules/minuscules et les in<strong>de</strong>x sont générés en<br />
conséquence.<br />
encrypt Crypte la base <strong>de</strong> données.<br />
<strong>de</strong>bug Réservée.<br />
dbo_avail Si 1, l'utilisateur dbo est disponible dans cette base <strong>de</strong><br />
données.<br />
mirrorname_present Si 1, indique que la version <strong>de</strong> DBTools est<br />
suffisamment récente pour prendre en charge le champ<br />
mirrorname.<br />
avoid_view_collisions Ne génère pas les vues SYS.SYSCOLUMNS et<br />
SYS.SYSINDEXES assurant la compatibilité avec<br />
Watcom SQL.<br />
collation_id I<strong>de</strong>ntificateur <strong>de</strong> l'ordre <strong>de</strong> classement.<br />
dbo_username N'est plus utilisé : défini avec la valeur NULL.<br />
mirrorname Nom du fichier miroir du journal <strong>de</strong> transactions.<br />
encryption_dllname DLL utilisée pour crypter la base <strong>de</strong> données<br />
java_classes Crée une base <strong>de</strong> données configurée pour Java.<br />
jconnect Inclut les procédures système requises pour jConnect<br />
data_store_type Réservé. Défini avec la valeur NULL.<br />
encryption_key Clé <strong>de</strong> cryptage du fichier <strong>de</strong> base <strong>de</strong> données.<br />
encryption_algorithm Soit AES, soit MDSR.<br />
jdk_version Une <strong>de</strong>s valeurs <strong>de</strong> l'option –jdk <strong>de</strong> dbinit.<br />
"Fonction DBCreate", page 322<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations nécessaires pour crypter un fichier <strong>de</strong> base <strong>de</strong><br />
données utilisées par l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dbinit.
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
Structure a_db_collation<br />
Fonction<br />
type<strong>de</strong>f struct a_crypt_db {<br />
const char _fd_ * dbname;<br />
const char _fd_ * dllname;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK statusrtn;<br />
char verbose;<br />
a_bit_field quiet : 1;<br />
a_bit_field <strong>de</strong>bug : 1;<br />
} a_crypt_db;<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Elément Description<br />
dbname Nom du fichier <strong>de</strong> base <strong>de</strong> données.<br />
dllname Nom <strong>de</strong> la DLL utilisée pour effectuer le cryptage.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
statusrtn Routine callback <strong>de</strong> gestion d'un message d'état.<br />
verbose Fonctionnement en mo<strong>de</strong> détaillé.<br />
quiet Fonctionnement sans messages.<br />
<strong>de</strong>bug Réservée.<br />
"Fonction DBCrypt", page 323<br />
"Création d'une base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> l'utilitaire dbinit", page 502 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration<br />
Contient les informations requises pour extraire un ordre <strong>de</strong> classement d'une<br />
base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
341
Structures DBTools<br />
Syntaxe<br />
Paramètres<br />
342<br />
type<strong>de</strong>f struct a_db_collation {<br />
unsigned short version;<br />
const char * connectparms;<br />
const char * startline;<br />
const char * collation_label;<br />
const char * filename;<br />
MSG_CALLBACK confirmrtn;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
a_bit_field inclu<strong>de</strong>_empty : 1;<br />
a_bit_field hex_for_exten<strong>de</strong>d : 1;<br />
a_bit_field replace : 1;<br />
a_bit_field quiet : 1;<br />
const char * input_filename;<br />
const char _fd_ * mapping_filename;<br />
} a_db_collation;<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
connectparms Paramètres requis pour la connexion à la base <strong>de</strong> données.<br />
Ils se présentent sous la forme <strong>de</strong> chaînes <strong>de</strong> connexion.<br />
Exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\asa\asa<strong>de</strong>mo.db"<br />
$ Pour obtenir l'ensemble <strong>de</strong>s options <strong>de</strong> chaîne <strong>de</strong><br />
connexion, reportez-vous à la section "Paramètres <strong>de</strong><br />
connexion", page 75 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration<br />
startline Ligne <strong>de</strong> comman<strong>de</strong> utilisée pour démarrer le moteur <strong>de</strong><br />
bases <strong>de</strong> données. Exemple :<br />
"c:\asa\win32\dbeng8.exe"<br />
Si cet élément est NULL, la ligne <strong>de</strong> démarrage par défaut<br />
est utilisée.<br />
confirmrtn Routine callback <strong>de</strong> confirmation d'une action.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
inclu<strong>de</strong>_empty Ecriture <strong>de</strong> mappages <strong>de</strong> blancs pour <strong>de</strong>s discontinuités<br />
dans l'ordre <strong>de</strong> classement.
Voir aussi<br />
Structure a_db_info<br />
Fonction<br />
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
hex_for_exten<strong>de</strong>d Utilisation <strong>de</strong> nombres hexadécimaux sur <strong>de</strong>ux chiffres<br />
pour représenter les caractères ASCII étendus.<br />
replace Fonctionnement sans confirmation <strong>de</strong>s actions.<br />
quiet Fonctionnement sans messages.<br />
input_filename Entrée <strong>de</strong> la définition du classement<br />
mapping_filename Sortie syscollationmapping.<br />
"Fonction DBCollate", page 321<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour renvoyer <strong>de</strong>s données dbinfo à l'ai<strong>de</strong><br />
<strong>de</strong> la bibliothèque DBTools.<br />
343
Structures DBTools<br />
Syntaxe<br />
Paramètres<br />
344<br />
type<strong>de</strong>f struct a_db_info {<br />
unsigned short version;<br />
MSG_CALLBACK errorrtn;<br />
const char * dbname;<br />
unsigned short dbbufsize;<br />
char * dbnamebuffer;<br />
unsigned short logbufsize;<br />
char * lognamebuffer;<br />
unsigned short wrtbufsize;<br />
char * wrtnamebuffer;<br />
a_bit_field quiet : 1;<br />
a_bit_field mirrorname_present : 1;<br />
a_sysinfo sysinfo;<br />
unsigned long free_pages;<br />
a_bit_field compressed : 1;<br />
const char * connectparms;<br />
const char * startline;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK statusrtn;<br />
a_bit_field page_usage : 1;<br />
a_table_info * totals;<br />
unsigned long file_size;<br />
unsigned long unused_pages;<br />
unsigned long other_pages;<br />
unsigned short mirrorbufsize;<br />
char * mirrornamebuffer;<br />
char * unused_field;<br />
char * collationnamebuffer;<br />
unsigned short collationnamebufsize;<br />
char * classesversionbuffer;<br />
unsigned short classesversionbufsize;<br />
} a_db_info;<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
errortrn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
dbname Nom du fichier <strong>de</strong> base <strong>de</strong> données.<br />
dbbufsize Longueur <strong>de</strong> l'élément dbnamebuffer.<br />
dbnamebuffer Nom du fichier <strong>de</strong> base <strong>de</strong> données.<br />
logbufsize Longueur <strong>de</strong> l'élément lognamebuffer.<br />
lognamebuffer Nom du fichier <strong>de</strong> journal <strong>de</strong> transactions.<br />
wrtbufsize Longueur <strong>de</strong> l'élément wrtnamebuffer.<br />
wrtnamebuffer Nom du fichier d'écriture.<br />
quiet Fonctionnement sans messages <strong>de</strong> confirmation.
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
mirrorname_present Si 1, indique que la version <strong>de</strong> DBTools est suffisamment<br />
récente pour prendre en charge le champ mirrorname.<br />
sysinfo Pointeur sur la structure a_sysinfo.<br />
free_pages Nombre <strong>de</strong> pages disponibles.<br />
compressed 1 si compacté ; 0 dans le cas contraire.<br />
connectparms Paramètres requis pour la connexion à la base <strong>de</strong> données.<br />
Ils se présentent sous la forme <strong>de</strong> chaînes <strong>de</strong> connexion.<br />
Exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\Program<br />
Files\<strong>Sybase</strong>\SQL <strong>Anywhere</strong> 8\asa<strong>de</strong>mo.db"<br />
$ Pour obtenir l'ensemble <strong>de</strong>s options <strong>de</strong> chaîne <strong>de</strong><br />
connexion, reportez-vous à la section "Paramètres <strong>de</strong><br />
connexion", page 75 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
startline Ligne <strong>de</strong> comman<strong>de</strong> utilisée pour démarrer le moteur <strong>de</strong><br />
bases <strong>de</strong> données. Exemple :<br />
"c:\asa\win32\dbeng8.exe"<br />
Si cet élément est NULL, la ligne <strong>de</strong> démarrage par<br />
défaut est utilisée.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
statusrtn Routine callback <strong>de</strong> gestion d'un message d'état.<br />
page_usage Si 1, affiche les statistiques d'utilisation <strong>de</strong>s pages. Dans<br />
le cas contraire, 0.<br />
totals Pointeur sur la structure a_table_info.<br />
file_size Taille du fichier <strong>de</strong> base <strong>de</strong> données.<br />
unused_pages Nombre <strong>de</strong> pages non utilisées.<br />
other_pages Nombre <strong>de</strong> pages ne correspondant ni à <strong>de</strong>s tables ni à <strong>de</strong>s<br />
in<strong>de</strong>x.<br />
mirrorbufsize Longueur <strong>de</strong> l'élément mirrornamebuffer.<br />
345
Structures DBTools<br />
Voir aussi<br />
Structure a_dblic_info<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
346<br />
Elément Description<br />
mirrornamebuffer Nom du fichier miroir du journal <strong>de</strong> transactions.<br />
collationnamebuffer Nom et libellé <strong>de</strong> classement <strong>de</strong> la base <strong>de</strong> données (taille<br />
maximale 128+1).<br />
collationnamebufsize Longueur <strong>de</strong> l'élément collationnamebuffer.<br />
classesversionbuffer Version JDK <strong>de</strong>s classes Java installées, comme 1.1.3,<br />
1.1.8, 1.3, ou une chaîne vi<strong>de</strong> si les classes Java ne sont<br />
pas installées dans la base <strong>de</strong> données (la taille maximale<br />
étant 10+1).<br />
classesversionbufsize Longueur <strong>de</strong> l'élément classesversionbuffer<br />
"Fonction DBInfo", page 324<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations <strong>de</strong> licence. Vous <strong>de</strong>vez utiliser ces informations<br />
conformément à votre contrat <strong>de</strong> licence.<br />
type<strong>de</strong>f struct a_dblic_info {<br />
unsigned short version;<br />
char * exename;<br />
char * username;<br />
char * compname;<br />
char * platform_str;<br />
a_sql_int32 no<strong>de</strong>count;<br />
a_sql_int32 conncount;<br />
a_license_type type;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
a_bit_field quiet : 1;<br />
a_bit_field query_only : 1;<br />
} a_dblic_info;<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
exename Nom du fichier exécutable.<br />
username Nom d'utilisateur pour la licence.<br />
compname Nom <strong>de</strong> la société pour la licence.<br />
platform_str Système d'exploitation : WinNT, NLM ou UNIX.<br />
no<strong>de</strong>count Nombre <strong>de</strong> noeuds sous licence.
Structure a_dbtools_info<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
Structure an_erase_db<br />
Fonction<br />
Syntaxe<br />
Elément Description<br />
conncount Doit être 1000000L.<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
type Voir le fichier lictype.h pour connaître les valeurs.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong> messages.<br />
query_only Si 1, affiche uniquement les informations <strong>de</strong> licence. Si 0, permet<br />
<strong>de</strong> modifier les informations.<br />
Contient les informations requises pour initialiser et réinitialiser la<br />
bibliothèque DBTools.<br />
type<strong>de</strong>f struct a_dbtools_info {<br />
MSG_CALLBACK errorrtn;<br />
} a_dbtools_info;<br />
Elément Description<br />
errorrtn Routine callback <strong>de</strong> gestion d’un message d’erreur.<br />
"Fonction DBToolsFini", page 327<br />
"Fonction DBToolsInit", page 328<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour supprimer une base <strong>de</strong> données à<br />
l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
type<strong>de</strong>f struct an_erase_db {<br />
unsigned short version;<br />
const char * dbname;<br />
MSG_CALLBACK confirmrtn;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
a_bit_field quiet : 1;<br />
a_bit_field erase : 1;<br />
const char * encryption_key;<br />
} an_erase_db;<br />
347
Structures DBTools<br />
Paramètres<br />
Voir aussi<br />
Structure an_expand_db<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
348<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
dbname Nom du fichier <strong>de</strong> base <strong>de</strong> données à supprimer.<br />
confirmrtn Routine callback <strong>de</strong> confirmation d'une action.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong> messages.<br />
erase Suppression avec (0) ou sans (1) confirmation.<br />
encryption_key Clé <strong>de</strong> cryptage du fichier <strong>de</strong> base <strong>de</strong> données.<br />
"Fonction DBErase", page 323<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour décompacter la base <strong>de</strong> données à<br />
l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
type<strong>de</strong>f struct an_expand_db {<br />
unsigned short version;<br />
const char * compress_name;<br />
const char * dbname;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK statusrtn;<br />
a_bit_field quiet : 1;<br />
MSG_CALLBACK confirmrtn;<br />
a_bit_field noconfirm : 1;<br />
const char * key_file;<br />
const char * encryption_key;<br />
} an_expand_db;<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
compress_name Nom du fichier <strong>de</strong> base <strong>de</strong> données compacté.<br />
dbname Nom du fichier <strong>de</strong> base <strong>de</strong> données.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.
Voir aussi<br />
Structure a_name<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
Structure a_stats_line<br />
Fonction<br />
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
statusrtn Routine callback <strong>de</strong> gestion d'un message d'état.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong> messages.<br />
confirmrtn Routine callback <strong>de</strong> confirmation d'une action.<br />
noconfirm Exécution avec (0) ou sans (1) confirmation.<br />
key_file Fichier contenant la clé <strong>de</strong> cryptage.<br />
encryption_key Clé <strong>de</strong> cryptage du fichier <strong>de</strong> base <strong>de</strong> données.<br />
"Fonction DBExpand", page 324<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient une liste chaînée <strong>de</strong> noms. Employée par d'autres structures<br />
nécessitant <strong>de</strong>s listes <strong>de</strong> noms.<br />
type<strong>de</strong>f struct a_name {<br />
struct a_name * next;<br />
char name[1];<br />
} a_name, * p_name;<br />
Elément Description<br />
next Pointeur sur la structure a_name suivante dans la liste.<br />
name Nom.<br />
p_name Pointeur sur la structure a_name précé<strong>de</strong>nte<br />
"Structure a_translate_log", page 354<br />
"Structure a_validate_db", page 360<br />
"Structure an_unload_db", page 357<br />
Contient les informations requises pour compacter et décompacter une base<br />
<strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
349
Structures DBTools<br />
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
Structure a_sync_db<br />
Fonction<br />
Syntaxe<br />
350<br />
type<strong>de</strong>f struct a_stats_line {<br />
long pages;<br />
long bytes;<br />
long compressed_bytes;<br />
} a_stats_line;<br />
Elément Description<br />
pages Nombre <strong>de</strong> pages.<br />
bytes Nombre d'octets réservés pour la base <strong>de</strong> données<br />
décompactée.<br />
compressed_bytes Nombre d'octets réservés pour la base <strong>de</strong> données<br />
compactée.<br />
"Structure a_compress_stats", page 337<br />
Contient les informations nécessaires à l'utilitaire dbmlsync qui utilise la<br />
bibliothèque DBTools.<br />
type<strong>de</strong>f struct a_sync_db {<br />
unsigned short version;<br />
char _fd_ * connectparms;<br />
char _fd_ * publication;<br />
const char _fd_ * offline_dir;<br />
char _fd_ * exten<strong>de</strong>d_options;<br />
char _fd_ * script_full_path;<br />
const char _fd_ * inclu<strong>de</strong>_scan_range;<br />
const char _fd_ * raw_file;<br />
MSG_CALLBACK confirmrtn;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK logrtn;<br />
a_SQL_uint32 <strong>de</strong>bug_dump_size;<br />
a_SQL_uint32 dl_insert_width;<br />
a_bit_field verbose : 1;<br />
a_bit_field <strong>de</strong>bug : 1;<br />
a_bit_field <strong>de</strong>bug_dump_hex : 1;<br />
a_bit_field <strong>de</strong>bug_dump_char : 1;<br />
a_bit_field <strong>de</strong>bug_page_offsets : 1;<br />
a_bit_field use_hex_offsets : 1;<br />
a_bit_field use_relative_offsets : 1;<br />
a_bit_field output_to_file : 1;<br />
a_bit_field output_to_mobile_link : 1;<br />
a_bit_field dl_use_put : 1;<br />
a_bit_field dl_use_upsert : 1;
Paramètres<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
a_bit_field kill_other_connections : 1;<br />
a_bit_field retry_remote_behind : 1;<br />
a_bit_field ignore_<strong>de</strong>bug_interrupt : 1;<br />
SET_WINDOW_TITLE_CALLBACK set_window_title_rtn;<br />
char * <strong>de</strong>fault_window_title;<br />
MSG_QUEUE_CALLBACK msgqueuertn;<br />
MSG_CALLBACK progress_msg_rtn;<br />
SET_PROGRESS_CALLBACK progress_in<strong>de</strong>x_rtn;<br />
char ** argv;<br />
char ** ce_argv;<br />
a_bit_field connectparms_allocated : 1;<br />
a_bit_field entered_dialog : 1;<br />
a_bit_field used_dialog_allocation : 1;<br />
a_bit_field ignore_scheduling : 1;<br />
a_bit_field ignore_hook_errors : 1;<br />
a_bit_field changing_pwd : 1;<br />
a_bit_field prompt_again : 1;<br />
a_bit_field retry_remote_ahead : 1;<br />
a_bit_field rename_log : 1;<br />
a_bit_field hi<strong>de</strong>_conn_str : 1;<br />
a_bit_field hi<strong>de</strong>_ml_pwd : 1;<br />
a_bit_field <strong>de</strong>lay_ml_disconn : 1;<br />
a_SQL_uint32 dlg_launch_focus;<br />
char _fd_ * mlpassword;<br />
char _fd_ * new_mlpassword;<br />
char _fd_ * verify_mlpassword;<br />
a_SQL_uint32 pub_name_cnt;<br />
char ** pub_name_list;<br />
USAGE_CALLBACK usage_rtn;<br />
a_sql_uint32 hovering_frequency;<br />
a_bit_short ignore_hovering : 1;<br />
a_bit_short verbose_upload : 1;<br />
a_bit_short verbose_upload_data : 1;<br />
a_bit_short verbose_download : 1;<br />
a_bit_short verbose_download_data : 1;<br />
a_bit_short autoclose : 1;<br />
a_bit_short ping : 1;<br />
a_bit_short _unused : 9;<br />
char _fd_ * encryption_key;<br />
a_syncpub _fd_ * upload_<strong>de</strong>fs;<br />
char _fd_ * log_file_name;<br />
char _fd_ * user_name;<br />
} a_sync_db;<br />
Les paramètres correspon<strong>de</strong>nt aux fonctionnalités accessibles <strong>de</strong>puis<br />
l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dbmlsync.<br />
Pour <strong>de</strong>s commentaires supplémentaires, reportez-vous au fichier d'en-tête<br />
dbtools.h.<br />
351
Structures DBTools<br />
Voir aussi<br />
Structure a_syncpub<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Structure a_sysinfo<br />
Fonction<br />
352<br />
$ Pour plus d'informations, reportez-vous à la section "Client <strong>de</strong><br />
synchronisation MobiLink", page 436 du document Synchronisation<br />
MobiLink <strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur.<br />
"Fonction DBSynchronizeLog", page 327<br />
Contient les informations nécessaires à l'utilitaire dbmlsync.<br />
type<strong>de</strong>f struct a_syncpub {<br />
struct a_syncpub _fd_ * next;<br />
char _fd_ * pub_name;<br />
char _fd_ * ext_opt;<br />
a_bit_field alloced_by_dbsync: 1;<br />
} a_syncpub;<br />
Elément Description<br />
a_syncpub Pointeur sur le noeud suivant dans la liste, NULL pour<br />
le <strong>de</strong>rnier noeud<br />
pub_name Nom(s) <strong>de</strong> publication spécifié(s) pour l'option -n. Il<br />
s'agit <strong>de</strong> la chaîne exacte suivant -n sur la ligne <strong>de</strong><br />
comman<strong>de</strong>.<br />
ext_opt Options étendues spécifiées à l'ai<strong>de</strong> <strong>de</strong> l'option –eu.<br />
encryption 1 si la base <strong>de</strong> données est cryptée, 0 dans le cas<br />
contraire.<br />
alloced_by_dbsync FALSE, à l'exception <strong>de</strong>s noeuds créés dans<br />
dbtool8.dll.<br />
Contient les informations requises par les utilitaires dbinfo et dbunload<br />
employant la bibliothèque DBTools.<br />
type<strong>de</strong>f struct a_sysinfo {<br />
a_bit_field valid_data : 1;<br />
a_bit_field blank_padding : 1;<br />
a_bit_field case_sensitivity : 1;<br />
a_bit_field encryption : 1;<br />
char <strong>de</strong>fault_collation[11];<br />
unsigned short page_size;<br />
} a_sysinfo;
Paramètres<br />
Voir aussi<br />
Structure a_table_info<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
valid_date Champ <strong>de</strong> bits indiquant si les valeurs qui suivent sont<br />
définies.<br />
blank_padding 1 si le remplissage avec <strong>de</strong>s blancs est utilisé dans la base <strong>de</strong><br />
données, 0 dans le cas contraire.<br />
case_sensitivity 1 si la base <strong>de</strong> données fait la distinction<br />
majuscules/minuscules, 0 dans le cas contraire.<br />
encryption 1 si la base <strong>de</strong> données est cryptée, 0 dans le cas contraire.<br />
<strong>de</strong>fault_collation Ordre <strong>de</strong> classement <strong>de</strong> la base <strong>de</strong> données.<br />
page_size Taille <strong>de</strong>s pages <strong>de</strong> la base <strong>de</strong> données.<br />
"Structure a_db_info", page 343<br />
Contient les informations relatives à une table requise par la structure<br />
a_db_info.<br />
type<strong>de</strong>f struct a_table_info {<br />
struct a_table_info * next;<br />
unsigned short table_id;<br />
unsigned long table_pages;<br />
unsigned long in<strong>de</strong>x_pages;<br />
unsigned long table_used;<br />
unsigned long in<strong>de</strong>x_used;<br />
char * table_name;<br />
a_sql_uint32 table_used_pct;<br />
a_sql_uint32 in<strong>de</strong>x_used_pct;<br />
} a_table_info;<br />
Elément Description<br />
next Table suivante <strong>de</strong> la liste.<br />
table_id Numéro d'ID <strong>de</strong> la table.<br />
table_pages Nombre <strong>de</strong> pages <strong>de</strong> la table.<br />
in<strong>de</strong>x_pages Nombre <strong>de</strong> pages d'in<strong>de</strong>x.<br />
353
Structures DBTools<br />
Voir aussi<br />
Structure a_translate_log<br />
Fonction<br />
354<br />
Elément Description<br />
table_used Nombre d'octets utilisés dans les pages <strong>de</strong> la table.<br />
in<strong>de</strong>x_used Nombre d'octets utilisés dans les pages d'in<strong>de</strong>x.<br />
table_name Nom <strong>de</strong> la table.<br />
table_used_pct Utilisation <strong>de</strong> l'espace <strong>de</strong> table en pourcentage.<br />
in<strong>de</strong>x_used_pct Utilisation <strong>de</strong> l'espace d'in<strong>de</strong>x en pourcentage.<br />
"Structure a_db_info", page 343<br />
Contient les informations requises pour convertir un journal <strong>de</strong> transactions à<br />
l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.
Syntaxe<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
type<strong>de</strong>f struct a_translate_log {<br />
unsigned short version;<br />
const char * logname;<br />
const char * sqlname;<br />
p_name userlist;<br />
MSG_CALLBACK confirmrtn;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
char userlisttype;<br />
a_bit_field remove_rollback : 1;<br />
a_bit_field ansi_SQL : 1;<br />
a_bit_field since_checkpoint: 1;<br />
a_bit_field omit_comments : 1;<br />
a_bit_field replace : 1;<br />
a_bit_field <strong>de</strong>bug : 1;<br />
a_bit_field inclu<strong>de</strong>_trigger_trans : 1;<br />
a_bit_field comment_trigger_trans : 1;<br />
unsigned long since_time;<br />
const char _fd_ * reserved_1;<br />
const char _fd_ * reserved_2;<br />
a_sql_uint32 <strong>de</strong>bug_dump_size;<br />
a_bit_field <strong>de</strong>bug_sql_remote : 1;<br />
a_bit_field <strong>de</strong>bug_dump_hex : 1;<br />
a_bit_field <strong>de</strong>bug_dump_char : 1;<br />
a_bit_field <strong>de</strong>bug_page_offsets : 1;<br />
a_bit_field reserved_3 : 1;<br />
a_bit_field use_hex_offsets : 1;<br />
a_bit_field use_relative_offsets : 1;<br />
a_bit_field inclu<strong>de</strong>_audit : 1;<br />
a_bit_field chronological_or<strong>de</strong>r : 1;<br />
a_bit_field force_recovery : 1;<br />
a_bit_field inclu<strong>de</strong>_subsets : 1;<br />
a_bit_field force_chaining : 1;<br />
a_sql_uint32 recovery_ops;<br />
a_sql_uint32 recovery_bytes;<br />
const char _fd_ * inclu<strong>de</strong>_source_sets;<br />
const char _fd_ * inclu<strong>de</strong>_<strong>de</strong>stination_sets;<br />
const char _fd_ * inclu<strong>de</strong>_scan_range;<br />
const char _fd_ * repserver_users;<br />
const char _fd_ * inclu<strong>de</strong>_tables;<br />
const char _fd_ * inclu<strong>de</strong>_publications;<br />
const char _fd_ * queueparms;<br />
a_bit_field generate_reciprocals :1;<br />
a_bit_field match_mo<strong>de</strong> :1;<br />
const char _fd_ * match_pos;<br />
MSG_CALLBACK statusrtn;<br />
const char _fd_ * encryption_key;<br />
a_bit_field show_undo :1;<br />
const char _fd_ * logs_dir;<br />
} a_translate_log;<br />
355
Structures DBTools<br />
Paramètres<br />
Voir aussi<br />
Structure a_truncate_log<br />
Fonction<br />
Syntaxe<br />
356<br />
Les paramètres correspon<strong>de</strong>nt aux fonctionnalités accessibles <strong>de</strong>puis<br />
l'utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dbtran.<br />
Pour <strong>de</strong>s commentaires supplémentaires, reportez-vous au fichier d'en-tête<br />
dbtools.h.<br />
"Fonction DBTranslateLog", page 329<br />
"Structure a_name", page 349<br />
"Enumération dbtran_userlist_type", page 365<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour tronquer un journal <strong>de</strong> transactions à<br />
l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
type<strong>de</strong>f struct a_truncate_log {<br />
unsigned short version;<br />
const char * connectparms;<br />
const char * startline;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
a_bit_field quiet : 1;<br />
char truncate_interrupted;<br />
} a_truncate_log;
Paramètres<br />
Voir aussi<br />
Structure an_unload_db<br />
Fonction<br />
Syntaxe<br />
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
connectparms Paramètres requis pour la connexion à la base <strong>de</strong> données.<br />
Ils se présentent sous la forme <strong>de</strong> chaînes <strong>de</strong> connexion.<br />
Exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\asa\asa<strong>de</strong>mo.db"<br />
$ Pour obtenir l'ensemble <strong>de</strong>s options <strong>de</strong> chaîne <strong>de</strong><br />
connexion, reportez-vous à la section "Paramètres <strong>de</strong><br />
connexion", page 75 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
startline Ligne <strong>de</strong> comman<strong>de</strong> utilisée pour démarrer le moteur <strong>de</strong><br />
bases <strong>de</strong> données. Exemple :<br />
"c:\asa\win32\dbeng8.exe"<br />
Si cet élément est NULL, la ligne <strong>de</strong> démarrage par défaut<br />
est utilisée.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong><br />
messages.<br />
truncate_interrupted Indique que l'opération a été interrompue<br />
"Fonction DBTruncateLog", page 329<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour décharger une base <strong>de</strong> données à<br />
l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools ou pour extraire une base <strong>de</strong> données<br />
distante pour SQL Remote. Les champs utilisés par l'utilitaire d'extraction<br />
SQL Remote dbxtract sont indiqués.<br />
type<strong>de</strong>f struct an_unload_db {<br />
unsigned short version;<br />
const char * connectparms;<br />
const char * startline;<br />
const char * temp_dir;<br />
const char * reload_filename;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK statusrtn;<br />
357
Structures DBTools<br />
Paramètres<br />
358<br />
MSG_CALLBACK confirmrtn;<br />
char unload_type;<br />
char verbose;<br />
a_bit_field unor<strong>de</strong>red : 1;<br />
a_bit_field no_confirm : 1;<br />
a_bit_field use_internal_unload : 1;<br />
a_bit_field dbo_avail : 1;<br />
a_bit_field extract : 1;<br />
a_bit_field table_list_provi<strong>de</strong>d : 1;<br />
a_bit_field exclu<strong>de</strong>_tables : 1;<br />
a_bit_field more_flag_bits_present : 1;<br />
a_sysinfo sysinfo;<br />
const char * remote_dir;<br />
const char * dbo_username;<br />
const char * subscriber_username;<br />
const char * publisher_address_type;<br />
const char * publisher_address;<br />
unsigned short isolation_level;<br />
a_bit_field start_subscriptions : 1;<br />
a_bit_field exclu<strong>de</strong>_foreign_keys : 1;<br />
a_bit_field exclu<strong>de</strong>_procedures : 1;<br />
a_bit_field exclu<strong>de</strong>_triggers : 1;<br />
a_bit_field exclu<strong>de</strong>_views : 1;<br />
a_bit_field isolation_set : 1;<br />
a_bit_field inclu<strong>de</strong>_where_subscribe : 1;<br />
a_bit_field <strong>de</strong>bug : 1;<br />
p_name table_list;<br />
a_bit_short escape_char_present : 1;<br />
a_bit_short view_iterations_present : 1;<br />
unsigned short view_iterations;<br />
char escape_char;<br />
char _fd_ * reload_connectparms;<br />
char _fd_ * reload_db_filename;<br />
a_bit_field output_connections:1;<br />
char unload_interrupted;<br />
a_bit_field replace_db:1;<br />
const char _fd_ * locale;<br />
const char _fd_ * site_name;<br />
const char _fd_ * template_name;<br />
a_bit_field preserve_ids:1;<br />
a_bit_field exclu<strong>de</strong>_hooks:1;<br />
char _fd_ * reload_db_logname;<br />
const char _fd_ * encryption_key;<br />
const char _fd_ * encryption_algorithm;<br />
a_bit_field syntax_version_7:1;<br />
a_bit_field remove_java:1;<br />
} an_unload_db;<br />
Les paramètres correspon<strong>de</strong>nt aux fonctionnalités accessibles <strong>de</strong>puis les<br />
utilitaires <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> dbunload, dbxtract et mlxtract.
Voir aussi<br />
Structure an_upgra<strong>de</strong>_db<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Pour <strong>de</strong>s commentaires supplémentaires, reportez-vous au fichier d'en-tête<br />
dbtools.h.<br />
"Fonction DBUnload", page 330<br />
"Structure a_name", page 349<br />
"Enumération dbunload_type", page 365<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour mettre à niveau une base <strong>de</strong> données<br />
à l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
type<strong>de</strong>f struct an_upgra<strong>de</strong>_db {<br />
unsigned short version;<br />
const char * connectparms;<br />
const char * startline;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK statusrtn;<br />
a_bit_field quiet : 1;<br />
a_bit_field dbo_avail : 1;<br />
const char * dbo_username;<br />
a_bit_field java_classes : 1;<br />
a_bit_field jconnect : 1;<br />
a_bit_field remove_java : 1;<br />
a_bit_field java_switch_specified : 1;<br />
const char * jdk_version;<br />
} an_upgra<strong>de</strong>_db;<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
connectparms Paramètres requis pour la connexion à la base <strong>de</strong> données. Ils se<br />
présentent sous la forme <strong>de</strong> chaînes <strong>de</strong> connexion. Exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\asa\asa<strong>de</strong>mo.db"<br />
$ Pour obtenir l'ensemble <strong>de</strong>s options <strong>de</strong> chaîne <strong>de</strong><br />
connexion, reportez-vous à la section "Paramètres <strong>de</strong><br />
connexion", page 75 du document ASA <strong>Gui<strong>de</strong></strong> d’administration<br />
startline Ligne <strong>de</strong> comman<strong>de</strong> utilisée pour démarrer le moteur <strong>de</strong> bases<br />
<strong>de</strong> données. Exemple :<br />
"c:\asa\win32\dbeng8.exe"<br />
Si cet élément est NULL, la ligne <strong>de</strong> démarrage par défaut est<br />
utilisée.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
359
Structures DBTools<br />
Voir aussi<br />
Structure a_validate_db<br />
Fonction<br />
Syntaxe<br />
360<br />
Elément Description<br />
msgrtn Routine callback <strong>de</strong> gestion d’un message d’information.<br />
statusrtn Routine callback <strong>de</strong> gestion d'un message d'état.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong> messages.<br />
dbo_avail Si 1, indique que la version <strong>de</strong> DBTools est suffisamment<br />
récente pour supporter le champ dbo_username.<br />
dbo_username Nom d'utilisateur du dbo.<br />
java_classes Met à niveau la base <strong>de</strong> données afin qu'elle soit configurée<br />
pour Java.<br />
jconnect Met à niveau la base <strong>de</strong> données afin qu'elle inclue les<br />
procédures jConnect.<br />
remove_java Met à niveau la base <strong>de</strong> données en supprimant les<br />
fonctionnalités Java.<br />
jdk_version Une <strong>de</strong>s valeurs <strong>de</strong> l'option -jdk <strong>de</strong> dbinit.<br />
"Fonction DBUpgra<strong>de</strong>", page 330<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour vali<strong>de</strong>r la base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong><br />
la bibliothèque DBTools.<br />
type<strong>de</strong>f struct a_validate_db {<br />
unsigned short version;<br />
const char * connectparms;<br />
const char * startline;<br />
p_name tables;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
MSG_CALLBACK statusrtn;<br />
a_bit_field quiet : 1;<br />
a_bit_field in<strong>de</strong>x : 1;<br />
a_validate_type type;<br />
} a_validate_db;
Paramètres<br />
Voir aussi<br />
Structure a_writefile<br />
Fonction<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
connectparms Paramètres requis pour la connexion à la base <strong>de</strong> données. Ils se<br />
présentent sous la forme <strong>de</strong> chaînes <strong>de</strong> connexion. Exemple :<br />
"UID=DBA;PWD=SQL;DBF=c:\asa\asa<strong>de</strong>mo.db"<br />
$ Pour obtenir l'ensemble <strong>de</strong>s options <strong>de</strong> chaîne <strong>de</strong> connexion,<br />
reportez-vous à la section "Paramètres <strong>de</strong> connexion", page 75 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
startline Ligne <strong>de</strong> comman<strong>de</strong> utilisée pour démarrer le moteur <strong>de</strong> bases <strong>de</strong><br />
données. Exemple :<br />
"c:\Program Files\<strong>Sybase</strong>\SA\win32\dbeng8.exe"<br />
Si cet élément est NULL, la ligne <strong>de</strong> démarrage par défaut est<br />
utilisée.<br />
tables Pointeur sur une liste chaînée <strong>de</strong> noms <strong>de</strong> tables.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
statusrtn Routine callback <strong>de</strong> gestion d'un message d'état.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong> messages.<br />
in<strong>de</strong>x Validation <strong>de</strong>s in<strong>de</strong>x<br />
type Reportez-vous à la section "Enumération a_validate_type",<br />
page 366.<br />
"Fonction DBValidate", page 331<br />
"Structure a_name", page 349<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à la<br />
section "Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
Contient les informations requises pour gérer les fichiers d'écriture <strong>de</strong> base<br />
<strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> la bibliothèque DBTools.<br />
361
Structures DBTools<br />
Syntaxe<br />
Paramètres<br />
362<br />
type<strong>de</strong>f struct a_writefile {<br />
unsigned short version;<br />
const char * writename;<br />
const char * wlogname;<br />
const char * dbname;<br />
const char * forcename;<br />
MSG_CALLBACK confirmrtn;<br />
MSG_CALLBACK errorrtn;<br />
MSG_CALLBACK msgrtn;<br />
char action;<br />
a_bit_field quiet : 1;<br />
a_bit_field erase : 1;<br />
a_bit_field force : 1;<br />
a_bit_field mirrorname_present : 1;<br />
const char * wlogmirrorname;<br />
a_bit_field make_log_and_mirror_names: 1;<br />
const char * encryption_key;<br />
} a_writefile;<br />
Elément Description<br />
version Numéro <strong>de</strong> version <strong>de</strong> DBTools.<br />
writename Nom du fichier d'écriture.<br />
wlogname Utilisé uniquement lors <strong>de</strong> la création <strong>de</strong> fichiers<br />
d'écriture.<br />
dbname Utilisé lors <strong>de</strong> la création et <strong>de</strong> la modification <strong>de</strong> fichiers<br />
d'écriture.<br />
forcename Référence <strong>de</strong> nom <strong>de</strong> fichier forcée.<br />
confirmrtn Routine callback <strong>de</strong> confirmation d'une action. Utilisé<br />
uniquement lors <strong>de</strong> la création <strong>de</strong> fichiers d'écriture.<br />
errorrtn Routine callback <strong>de</strong> gestion d'un message d'erreur.<br />
msgrtn Routine callback <strong>de</strong> gestion d'un message d'information.<br />
action Réservé à l'usage <strong>de</strong> <strong>Sybase</strong>.<br />
quiet Fonctionnement avec (0) ou sans (1) impression <strong>de</strong><br />
messages.<br />
erase Utilisé pour la création <strong>de</strong> fichiers d'écriture uniquement.<br />
Suppression avec (0) ou sans (1) confirmation.
Voir aussi<br />
Elément Description<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
force Si 1, impose que le fichier d'écriture pointe sur un fichier<br />
nommé.<br />
mirrorname_present Utilisé en cas <strong>de</strong> création uniquement. Si 1, indique que la<br />
version <strong>de</strong> DBTools est suffisamment récente pour<br />
prendre en charge le champ mirrorname.<br />
wlogmirrorname Nom du fichier miroir du journal <strong>de</strong> transactions.<br />
make_log_and_mirro<br />
r_names<br />
Si TRUE, utilise les valeurs <strong>de</strong> wlogname et<br />
wlogmirrorname pour déterminer les noms <strong>de</strong> fichier.<br />
encryption_key Clé <strong>de</strong> cryptage du fichier <strong>de</strong> base <strong>de</strong> données.<br />
"Fonction DBChangeWriteFile", page 321<br />
"Fonction DBCreateWriteFile", page 323<br />
"Fonction DBStatusWriteFile", page 326<br />
$ Pour plus d'informations sur les fonctions callback, reportez-vous à<br />
"Utilisation <strong>de</strong>s fonctions callback", page 313.<br />
363
Types d'énumération DBTools<br />
Types d'énumération DBTools<br />
Enumération du mo<strong>de</strong> <strong>de</strong> sortie<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
364<br />
La présente section répertorie les types d'énumération utilisés par la<br />
bibliothèque DBTools. Les énumérations sont répertoriées dans l'ordre<br />
alphabétique.<br />
Spécifie le mo<strong>de</strong> <strong>de</strong> sortie.<br />
enum {<br />
VB_QUIET,<br />
VB_NORMAL,<br />
VB_VERBOSE<br />
};<br />
Valeur Description<br />
VB_QUIET Pas <strong>de</strong> sortie.<br />
VB_NORMAL Sortie normale.<br />
VB_VERBOSE Sortie détaillée, utilisée à <strong>de</strong>s fins <strong>de</strong> débogage.<br />
"Structure a_create_db", page 338<br />
"Structure an_unload_db", page 357<br />
Enumération du remplissage avec <strong>de</strong>s blancs<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
Utilisée dans "Structure a_create_db", page 338 pour spécifier la valeur <strong>de</strong><br />
blank_pad.<br />
enum {<br />
NO_BLANK_PADDING,<br />
BLANK_PADDING<br />
};<br />
Valeur Description<br />
NO_BLANK_PADDING N’utilise pas le remplissage avec <strong>de</strong>s blancs en<br />
fin <strong>de</strong> chaîne.<br />
BLANK_PADDING Utilise le remplissage avec <strong>de</strong>s blancs.<br />
"Structure a_create_db", page 338
Enumération dbtran_userlist_type<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
Enumération dbunload_type<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
Chapitre 8 Interface Outils <strong>de</strong> base <strong>de</strong> données<br />
Type d'une liste d'utilisateurs, employé par "Structure a_translate_log",<br />
page 354.<br />
type<strong>de</strong>f enum dbtran_userlist_type {<br />
DBTRAN_INCLUDE_ALL,<br />
DBTRAN_INCLUDE_SOME,<br />
DBTRAN_EXCLUDE_SOME<br />
} dbtran_userlist_type;<br />
Valeur Description<br />
DBTRAN_INCLUDE_ALL Inclut les opérations <strong>de</strong> tous les utilisateurs.<br />
DBTRAN_INCLUDE_SOME Inclut uniquement les opérations exécutées par<br />
les utilisateurs figurant dans la liste fournie.<br />
DBTRAN_EXCLUDE_SOME Exclut uniquement les opérations exécutées<br />
par les utilisateurs figurant dans la liste<br />
fournie.<br />
"Structure a_translate_log", page 354<br />
Type du déchargement en cours d'exécution, utilisé par "Structure<br />
an_unload_db", page 357.<br />
enum {<br />
UNLOAD_ALL,<br />
UNLOAD_DATA_ONLY,<br />
UNLOAD_NO_DATA<br />
};<br />
Valeur Description<br />
UNLOAD_ALL Décharge les données et le schéma.<br />
UNLOAD_DATA_ONLY Décharge les données. Pas <strong>de</strong> déchargement<br />
du schéma.<br />
UNLOAD_NO_DATA Décharge le schéma uniquement.<br />
"Structure an_unload_db", page 357<br />
365
Types d'énumération DBTools<br />
Enumération a_validate_type<br />
Fonction<br />
Syntaxe<br />
Paramètres<br />
Voir aussi<br />
366<br />
Type <strong>de</strong> validation en cours d'exécution, utilisé par "Structure<br />
a_validate_db", page 360.<br />
type<strong>de</strong>f enum {<br />
VALIDATE_NORMAL = 0,<br />
VALIDATE_DATA,<br />
VALIDATE_INDEX,<br />
VALIDATE_EXPRESS,<br />
VALIDATE_FULL<br />
} a_validate_type;<br />
Valeur Description<br />
VALIDATE_NORMAL Validation avec vérification par défaut uniquement.<br />
VALIDATE_DATA Validation avec vérification <strong>de</strong>s données en plus <strong>de</strong> la<br />
vérification par défaut.<br />
VALIDATE_INDEX Validation avec vérification <strong>de</strong>s in<strong>de</strong>x en plus <strong>de</strong> la<br />
vérification par défaut.<br />
VALIDATE_EXPRESS Validation avec vérification express en plus <strong>de</strong> la<br />
vérification par défaut et <strong>de</strong> la vérification <strong>de</strong>s<br />
données.<br />
VALIDATE_FULL Validation avec vérification <strong>de</strong>s données et <strong>de</strong>s in<strong>de</strong>x<br />
en plus <strong>de</strong> la vérification par défaut.<br />
"Validation d'une base <strong>de</strong> données à l'ai<strong>de</strong> <strong>de</strong> l'utilitaire dbvalid", page 575<br />
du document ASA <strong>Gui<strong>de</strong></strong> d’administration<br />
"Instruction VALIDATE TABLE", page 615 du document ASA Manuel <strong>de</strong><br />
référence SQL.
CHAPITRE 9<br />
Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB<br />
et ADO<br />
Présentation<br />
Sommaire<br />
Ce chapitre explique comment utiliser l’interface OLE DB avec <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>.<br />
De nombreuses applications passent par l'intermédiaire du modèle <strong>de</strong><br />
<strong>programmation</strong> ADO (ActiveX Data Objects) <strong>de</strong> Microsoft pour utiliser<br />
l'interface OLE DB. Ce chapitre décrit également la <strong>programmation</strong> ADO<br />
avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Sujet Page<br />
Introduction à OLE DB 368<br />
Programmation ADO avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> 370<br />
Interfaces OLE DB supportées 378<br />
367
Introduction à OLE DB<br />
Introduction à OLE DB<br />
Plates-formes supportées<br />
368<br />
OLE DB est un modèle d'accès aux données proposé par Microsoft. Se<br />
servant <strong>de</strong>s interfaces COM (Component Object Mo<strong>de</strong>l), le modèle OLE DB,<br />
contrairement à ODBC, ne présuppose pas que la source <strong>de</strong> données utilise<br />
un processeur <strong>de</strong> requêtes SQL.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> inclut un fournisseur OLE DB appelé<br />
ASAProv. Ce fournisseur est disponible pour les plates-formes Windows<br />
actuelles ainsi que pour Windows CE.<br />
Vous pouvez également accé<strong>de</strong>r à <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> à l'ai<strong>de</strong> du<br />
fournisseur OLE DB pour ODBC (MSDASQL) <strong>de</strong> Microsoft, conjugué au<br />
pilote ODBC d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
L'utilisation du fournisseur OLE DB d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> procure<br />
plusieurs avantages :<br />
♦ Certaines fonctionnalités, dont la mise à jour à l'ai<strong>de</strong> d'un curseur, ne<br />
sont pas disponibles via la passerelle OLE DB/ODBC.<br />
♦ Si vous avez recours au fournisseur OLE DB d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>, le déploiement ne nécessite pas ODBC.<br />
♦ MSDASQL permet aux clients OLE DB <strong>de</strong> travailler avec n'importe<br />
quel pilote ODBC, mais sans garantir que toute la gamme <strong>de</strong>s<br />
fonctionnalités <strong>de</strong> chaque pilote ODBC soit exploitée. En utilisant le<br />
fournisseur d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, vous pouvez accé<strong>de</strong>r à toutes<br />
les fonctionnalités d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> à partir <strong>de</strong>s<br />
environnements <strong>de</strong> <strong>programmation</strong> OLE DB.<br />
Le fournisseur OLE DB d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est conçu pour<br />
fonctionner avec OLE DB version 2.5 et ultérieure. Pour Windows CE et ses<br />
prochaines extensions, le fournisseur OLE DB est conçu pour ADOCE<br />
version 3.0 et ultérieure.<br />
ADOCE, qui est l'ADO <strong>de</strong> Microsoft pour le SDK <strong>de</strong> Windows CE, apporte<br />
une fonctionnalité <strong>de</strong> base <strong>de</strong> données aux applications développées avec les<br />
Toolkits Windows CE pour Visual Basic 5.0 et Visual Basic 6.0.<br />
$ Pour obtenir une liste <strong>de</strong>s plates-formes supportées, reportez-vous à la<br />
rubrique "Versions <strong>de</strong>s systèmes d'exploitation", page 144 du document<br />
Présentation <strong>de</strong> SQL <strong>Anywhere</strong> Studio.
Transactions distribuées<br />
Chapitre 9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et ADO<br />
Il est possible d’utiliser le gestionnaire OLE DB comme gestionnaire <strong>de</strong><br />
ressources dans un environnement <strong>de</strong> transactions distribuées.<br />
$ Pour plus d'informations, reportez-vous au chapitre "Transactions<br />
distribuées et architecture à trois niveaux", page 393.<br />
369
Programmation ADO avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Programmation ADO avec <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong><br />
370<br />
ADO (ActiveX Data Objects) est un modèle d'accès objet aux données<br />
présenté par le biais d'une interface Automation, qui permet aux applications<br />
clientes <strong>de</strong> découvrir les métho<strong>de</strong>s et propriétés <strong>de</strong>s objets lors <strong>de</strong> l'exécution<br />
sans connaissance préalable <strong>de</strong> ces <strong>de</strong>rniers. Automation permet aux<br />
langages <strong>de</strong> script comme Visual Basic d'utiliser un modèle d'accès objet aux<br />
données standard. ADO a recours à OLE DB pour fournir l'accès aux<br />
données.<br />
Si vous utilisez le fournisseur OLE DB d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, vous<br />
avez un accès complet aux fonctionnalités d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> à<br />
partir d'un environnement <strong>de</strong> <strong>programmation</strong> ADO.<br />
Cette section décrit comment exécuter les tâches élémentaires en utilisant<br />
ADO à partir <strong>de</strong> Visual Basic. Il ne s'agit pas d'un gui<strong>de</strong> complet <strong>de</strong><br />
<strong>programmation</strong> à l'ai<strong>de</strong> d'ADO.<br />
Les exemples <strong>de</strong> co<strong>de</strong> issus <strong>de</strong> cette section se trouvent dans les fichiers<br />
suivants :<br />
Outil <strong>de</strong><br />
développement<br />
Microsoft Visual Basic<br />
6.0<br />
Microsoft eMbed<strong>de</strong>d<br />
Visual Basic 3.0<br />
Exemple<br />
Samples\ASA\VBSampler\vbsampler.vbp<br />
Samples\ASA\ADOCE\OLEDB_PocketPC.ebp<br />
$ Pour plus d’informations sur la <strong>programmation</strong> avec ADO, reportezvous<br />
à la documentation relative à votre outil <strong>de</strong> développement.<br />
$ Pour plus <strong>de</strong> détails sur l'utilisation d'ADO et <strong>de</strong> Visual Basic pour<br />
accé<strong>de</strong>r aux données d'une base <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, reportez-vous<br />
au livre blanc Accessing Data in <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> Using ADO and<br />
Visual Basic, disponible à l'adresse<br />
http://www.sybase.com/<strong>de</strong>tail?id=1017429.<br />
Connexion à une base <strong>de</strong> données avec l'objet Connection<br />
Cette section décrit une routine Visual Basic simple pour une connexion à<br />
une base <strong>de</strong> données.
Co<strong>de</strong> exemple<br />
Remarques<br />
Chapitre 9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et ADO<br />
Pour essayer cette routine, placez un bouton <strong>de</strong> comman<strong>de</strong> intitulé<br />
Command1 dans un formulaire et collez la routine dans son événement<br />
Click. Lancez le programme et cliquez sur le bouton pour établir une<br />
connexion puis effectuer une déconnexion.<br />
Private Sub cmdTestConnection_Click()<br />
' Déclare les variables<br />
Dim myConn As New ADODB.Connection<br />
Dim myCommand As New ADODB.Command<br />
Dim cAffected As Long<br />
On Error GoTo HandleError<br />
' Etablit la connexion<br />
myConn.Provi<strong>de</strong>r = "ASAProv"<br />
myConn.ConnectionString = _<br />
"Data Source=ASA 8.0 Sample"<br />
myConn.Open<br />
MsgBox "Réussite connexion"<br />
myConn.Close<br />
Exit Sub<br />
HandleError:<br />
MsgBox "Echec connexion"<br />
Exit Sub<br />
End Sub<br />
Voici le déroulement <strong>de</strong>s tâches exécutées :<br />
♦ Les variables utilisées dans la routine sont déclarées.<br />
♦ Une connexion à la base <strong>de</strong> données exemple est établie à l'ai<strong>de</strong> du<br />
fournisseur OLE DB d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
♦ Un objet Command est utilisé pour exécuter une instruction simple, qui<br />
affiche un message dans la fenêtre du serveur <strong>de</strong> base <strong>de</strong> données.<br />
♦ La connexion est fermée.<br />
Le fournisseur ASAProv s'enregistre automatiquement lorsqu'il est installé.<br />
Le processus d'enregistrement consiste à créer <strong>de</strong>s entrées <strong>de</strong> registre dans la<br />
section COM du registre <strong>de</strong> sorte qu'ADO puisse localiser le fichier DLL en<br />
cas d'appel du fournisseur ASAProv. Si vous modifiez l'emplacement <strong>de</strong><br />
votre fichier DLL, vous <strong>de</strong>vez l'enregistrer à nouveau.<br />
v Pour enregistrer le fournisseur OLE DB :<br />
1 Ouvrez une fenêtre <strong>de</strong> comman<strong>de</strong>s.<br />
2 Placez-vous dans le répertoire d'installation du fournisseur OLE DB.<br />
371
Programmation ADO avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
372<br />
3 Entrez la comman<strong>de</strong> suivante pour enregistrer le fournisseur :<br />
regsvr32 dboledb8.dll<br />
$ Pour plus d'informations sur la connexion à une base <strong>de</strong> données à l'ai<strong>de</strong><br />
d'OLE DB, reportez-vous à la section "Connexion à une base <strong>de</strong> données<br />
avec OLE DB", page 73 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Exécution d'instructions avec l'objet Command<br />
Co<strong>de</strong> exemple<br />
Remarques<br />
Cette section décrit une routine simple qui envoie une instruction SQL<br />
simple à la base <strong>de</strong> données.<br />
Pour essayer cette routine, placez un bouton <strong>de</strong> comman<strong>de</strong> intitulé<br />
Command2 dans un formulaire et collez la routine dans son événement<br />
Click. Lancez le programme et cliquez sur le bouton pour établir une<br />
connexion, afficher un message dans la fenêtre du serveur <strong>de</strong> base <strong>de</strong><br />
données, puis effectuer une déconnexion.<br />
Private Sub cmdUpdate_Click()<br />
' Déclare les variables<br />
Dim myConn As New ADODB.Connection<br />
Dim myCommand As New ADODB.Command<br />
Dim cAffected As Long<br />
' Etablit la connexion<br />
myConn.Provi<strong>de</strong>r = "ASAProv"<br />
myConn.ConnectionString = _<br />
"Data Source=ASA 8.0 Sample"<br />
myConn.Open<br />
'Exécute une comman<strong>de</strong><br />
myCommand.CommandText = _<br />
"update customer set fname='Liz' where id=102"<br />
Set myCommand.ActiveConnection = myConn<br />
myCommand.Execute cAffected<br />
MsgBox CStr(cAffected) +<br />
" lignes affectées.", vbInformation<br />
myConn.Close<br />
End Sub<br />
Après avoir établi une connexion, le co<strong>de</strong> exemple crée un objet Command,<br />
définit sa propriété CommandText à une instruction <strong>de</strong> mise à jour et sa<br />
propriété ActiveConnection à la connexion en cours. Il exécute ensuite<br />
l'instruction <strong>de</strong> mise à jour et affiche le nombre <strong>de</strong> lignes affectées par la<br />
mise à jour dans une boîte <strong>de</strong> message.<br />
Dans cet exemple, la mise à jour est envoyée à la base <strong>de</strong> données puis<br />
validée dès son exécution.
Chapitre 9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et ADO<br />
$ Pour plus d’informations sur l’utilisation <strong>de</strong>s transactions au sein<br />
d'ADO, reportez-vous à la section "Utilisation <strong>de</strong>s transactions", page 377.<br />
Vous pouvez également effectuer les mises à jour à l'ai<strong>de</strong> d'un curseur.<br />
$ Pour plus d'informations, reportez-vous à la section "Mise à jour <strong>de</strong><br />
données à l'ai<strong>de</strong> d'un curseur", page 375.<br />
Interrogation <strong>de</strong> la base <strong>de</strong> données avec l'objet Recordset<br />
Co<strong>de</strong> exemple<br />
L’objet Recordset d'ADO représente le jeu <strong>de</strong> résultats d'une requête. Vous<br />
pouvez l'utiliser pour visualiser les données d'une base <strong>de</strong> données.<br />
Pour essayer cette routine, placez un bouton <strong>de</strong> comman<strong>de</strong> intitulé<br />
cmdQuery dans un formulaire et collez la routine dans son événement<br />
Click. Lancez le programme et cliquez sur le bouton pour établir une<br />
connexion, afficher un message dans la fenêtre du serveur <strong>de</strong> base <strong>de</strong><br />
données, exécuter une requête et afficher les premières lignes <strong>de</strong>s boîtes <strong>de</strong><br />
message, puis effectuer une déconnexion.<br />
373
Programmation ADO avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Remarques<br />
374<br />
Private Sub cmdQuery_Click()<br />
' Déclare les variables<br />
Dim myConn As New ADODB.Connection<br />
Dim myCommand As New ADODB.Command<br />
Dim myRS As New ADODB.Recordset<br />
On Error GoTo ErrorHandler:<br />
' Etablit la connexion<br />
myConn.Provi<strong>de</strong>r = "ASAProv"<br />
myConn.ConnectionString = _<br />
"Data Source=ASA 8.0 Sample"<br />
myConn.CursorLocation = adUse<strong>Server</strong><br />
myConn.Mo<strong>de</strong> = adMo<strong>de</strong>ReadWrite<br />
myConn.IsolationLevel = adXactCursorStability<br />
myConn.Open<br />
'Exécute une requête<br />
Set myRS = New Recordset<br />
myRS.CacheSize = 50<br />
myRS.Source = "Select * from customer"<br />
myRS.ActiveConnection = myConn<br />
myRS.CursorType = adOpenKeyset<br />
myRS.LockType = adLockOptimistic<br />
myRS.Open<br />
'Fait défiler les premiers résultats<br />
myRS.MoveFirst<br />
For i = 1 To 5<br />
MsgBox myRS.Fields("company_name"), vbInformation<br />
myRS.MoveNext<br />
Next<br />
myRS.Close<br />
myConn.Close<br />
Exit Sub<br />
ErrorHandler:<br />
MsgBox Error(Err)<br />
Exit Sub<br />
End Sub<br />
L’objet Recordset <strong>de</strong> cet exemple contient les résultats d'une requête portant<br />
sur la table Customer. La boucle For fait défiler les premières lignes et<br />
affiche la valeur company_name correspondant à chaque ligne.<br />
Il s'agit d'un exemple simple d'utilisation d'un curseur à partir d'ADO.<br />
$ Pour <strong>de</strong>s exemples plus élaborés sur l'utilisation d'un curseur à partir<br />
d'ADO, reportez-vous à la section "Utilisation d'un objet Recordset",<br />
page 375.
Utilisation d’un objet Recordset<br />
Types <strong>de</strong> curseur<br />
Co<strong>de</strong> exemple<br />
Chapitre 9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et ADO<br />
Dans son fonctionnement avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, l’objet Recordset<br />
d'ADO représente un curseur. Vous pouvez choisir le type <strong>de</strong> curseur en<br />
déclarant une propriété CursorType <strong>de</strong> l'objet Recordset avant d'ouvrir ce<br />
<strong>de</strong>rnier. En fonction du type <strong>de</strong> curseur choisi, diverses actions sont possibles<br />
sur l'objet Recordset et les performances sont différentes.<br />
Vous trouverez une <strong>de</strong>scription <strong>de</strong> l'ensemble <strong>de</strong>s types <strong>de</strong> curseur supportés<br />
par <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> à la section "Propriétés <strong>de</strong> curseur", page 25.<br />
ADO possè<strong>de</strong> ses propres conventions <strong>de</strong> dénomination <strong>de</strong>s types <strong>de</strong> curseur.<br />
Les types <strong>de</strong> curseur disponibles, les constantes correspondant à chaque type<br />
et les types équivalents pour <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> sont les suivants :<br />
Type <strong>de</strong> curseur<br />
ADO<br />
Constante ADO Type <strong>de</strong> curseur<br />
<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong><br />
Curseur dynamique adOpenDynamic Curseur avec défilement<br />
dynamique<br />
Curseur keyset adOpenKeyset Curseur avec défilement<br />
Curseur statique adOpenStatic Curseur insensible<br />
(insensitive)<br />
Curseur à<br />
défilement avant<br />
uniquement<br />
adOpenForwardOnly Curseur sans défilement<br />
$ Pour plus d'informations sur le choix d'un type <strong>de</strong> curseur adapté à votre<br />
application, reportez-vous à la section "Choix d'un type <strong>de</strong> curseur", page 25.<br />
Le co<strong>de</strong> suivant définit le type <strong>de</strong> curseur pour un objet Recordset d'ADO :<br />
Dim myRS As New ADODB.Recordset<br />
myRS.CursorType = adOpenDynamic<br />
Mise à jour <strong>de</strong> données à l'ai<strong>de</strong> d'un curseur<br />
Mise à jour <strong>de</strong> jeux<br />
d'enregistrements<br />
Le fournisseur OLE DB d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> permet <strong>de</strong> mettre à<br />
jour un jeu <strong>de</strong> résultats à l'ai<strong>de</strong> d'un curseur. Cette possibilité n'est pas offerte<br />
par le fournisseur MSDASQL.<br />
Vous pouvez mettre à jour la base <strong>de</strong> données à l'ai<strong>de</strong> d'un jeu<br />
d'enregistrements.<br />
375
Programmation ADO avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
Remarques<br />
376<br />
Private Sub Command6_Click()<br />
Dim myConn As New ADODB.Connection<br />
Dim myRS As New ADODB.Recordset<br />
Dim SQLString As String<br />
’ Connexion<br />
myConn.Provi<strong>de</strong>r = "ASAProv"<br />
myConn.ConnectionString = _<br />
"Data Source=ASA 8.0 Sample"<br />
myConn.Open<br />
myConn.BeginTrans<br />
SQLString = "Select * from customer"<br />
myRS.Open SQLString, _<br />
myConn, adOpenDynamic, adLockBatchOptimistic<br />
_<br />
If myRS.BOF And myRS.EOF Then<br />
MsgBox "Jeu <strong>de</strong> résultat vi<strong>de</strong> !", _<br />
16, "Empty Recordset"<br />
Else<br />
MsgBox "Type <strong>de</strong> curseur : " + _<br />
CStr(myRS.CursorType), vbInformation<br />
myRS.MoveFirst<br />
For i = 1 To 3<br />
MsgBox "Ligne : " + CStr(myRS.Fields("id")),<br />
vbInformation<br />
If i = 2 Then<br />
myRS.Update "City", "Toronto"<br />
myRS.UpdateBatch<br />
End If<br />
myRS.MoveNext<br />
Next i<br />
' myRS.MovePrevious<br />
myRS.Close<br />
End If<br />
myConn.CommitTrans<br />
myConn.Close<br />
End Sub<br />
Si vous appliquez le paramètre adLockBatchOptimistic au jeu<br />
d'enregistrements, la métho<strong>de</strong> myRS.Update n'apporte aucune modification<br />
à la base <strong>de</strong> données elle-même : elle met à jour une copie locale <strong>de</strong> l'objet<br />
Recordset.<br />
La métho<strong>de</strong> myRS.UpdateBatch effectue la mise à jour du serveur <strong>de</strong> base<br />
<strong>de</strong> données, mais ne la vali<strong>de</strong> pas, car elle est interne à la transaction. Si une<br />
métho<strong>de</strong> UpdateBatch a été appelée à l'extérieur d'une transaction, la<br />
modification est validée.<br />
La métho<strong>de</strong> myConn.CommitTrans vali<strong>de</strong> les modifications. En effet,<br />
comme l'objet Recordset est désormais fermé, le fait que la copie locale <strong>de</strong>s<br />
données soit modifiée ou non n'a plus d'importance.
Utilisation <strong>de</strong>s transactions<br />
Chapitre 9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et ADO<br />
Par défaut, toute modification apportée à la base <strong>de</strong> données à l'ai<strong>de</strong> d'ADO<br />
est validée dès son exécution, qu'il s'agisse <strong>de</strong> mises à jour explicites ou <strong>de</strong> la<br />
métho<strong>de</strong> UpdateBatch appliquée à un objet Recordset. Toutefois, vous avez<br />
vu à la section précé<strong>de</strong>nte comment appliquer les métho<strong>de</strong>s BeginTrans et<br />
RollbackTrans ou CommitTrans à l'objet Connection pour utiliser <strong>de</strong>s<br />
transactions.<br />
Le niveau d'isolement d'une transaction est défini comme une propriété <strong>de</strong><br />
l'objet Connection. La propriété IsolationLevel peut prendre l'une <strong>de</strong>s valeurs<br />
suivantes :<br />
Niveau d’isolement<br />
ADO<br />
Constante Niveau ASA<br />
Non spécifié adXactUnspecified Non applicable. Défini à 0<br />
Chaos adXactChaos Non supporté. Défini à 0<br />
Browse (survol) adXactBrowse 0<br />
Read uncommitted<br />
(lecture non validée)<br />
Cursor stability<br />
(stabilité du curseur)<br />
Read committed<br />
(lecture validée)<br />
Repeatable read (lecture<br />
répétable)<br />
adXactReadUncommitte<br />
d<br />
adXactCursorStability 1<br />
adXactReadCommitted 1<br />
adXactRepeatableRead 2<br />
Isolated (isolé) adXactIsolated 3<br />
Serializable<br />
(sérialisable)<br />
adXactSerializable 3<br />
$ Pour plus d'informations sur les niveaux d'isolement, reportez-vous à la<br />
section "Niveaux d'isolement et cohérence", page 98 du document ASA<br />
<strong>Gui<strong>de</strong></strong> <strong>de</strong> l’utilisateur SQL.<br />
0<br />
377
Interfaces OLE DB supportées<br />
Interfaces OLE DB supportées<br />
378<br />
L’API OLE DB est constituée d'un ensemble d'interfaces. Le tableau suivant<br />
décrit le support <strong>de</strong> chaque interface dans le gestionnaire OLE DB<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Interface Fonction Restrictions<br />
IAccessor Définit <strong>de</strong>s liaisons entre la<br />
mémoire cliente et les<br />
valeurs <strong>de</strong>s sources <strong>de</strong><br />
données.<br />
IAlterIn<strong>de</strong>x<br />
IAlterTable<br />
Modifie les tables, les in<strong>de</strong>x<br />
et les colonnes.<br />
IChapteredRowset Un jeu <strong>de</strong> lignes par chapitre<br />
permet d'accé<strong>de</strong>r par<br />
chapitres séparés à <strong>de</strong>s lignes<br />
d'un même ensemble.<br />
IColumnsInfo Obtient <strong>de</strong>s informations<br />
simples sur les colonnes d'un<br />
jeu <strong>de</strong> lignes.<br />
IColumnsRowset Obtient <strong>de</strong>s informations sur<br />
les colonnes <strong>de</strong> métadonnées<br />
optionnelles d'un jeu <strong>de</strong><br />
lignes et obtient un jeu <strong>de</strong><br />
lignes <strong>de</strong>s métadonnées<br />
d'une colonne.<br />
ICommand Exécute les comman<strong>de</strong>s<br />
SQL.<br />
ICommandPersist Prolonge l'état d'un objet <strong>de</strong><br />
comman<strong>de</strong> (mais aucun jeu<br />
<strong>de</strong> lignes actif). Ces objets <strong>de</strong><br />
comman<strong>de</strong> persistants<br />
peuvent ensuite être<br />
énumérés à l'ai<strong>de</strong> du jeu <strong>de</strong><br />
lignes PROCEDURES ou<br />
VIEWS.<br />
DBACCESSOR_PASS<br />
BYREF non supporté.<br />
DBACCESSOR_OPTI<br />
MIZED non supporté.<br />
Non supportée<br />
Non supportée.<br />
<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> ne supporte<br />
pas les jeux <strong>de</strong> lignes<br />
par chapitre .<br />
N'existe pas sous CE.<br />
N'existe pas sous CE.<br />
Appel non supporté.<br />
IcommandProperties :<br />
GetProperties avec<br />
DBPROPSET_PROPE<br />
RTIESINERROR pour<br />
trouver les propriétés<br />
qui n'ont pas pu être<br />
définies.<br />
N'existe pas sous CE.
Chapitre 9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et ADO<br />
Interface Fonction Restrictions<br />
ICommandPrepare Prépare les comman<strong>de</strong>s. N'existe pas sous CE.<br />
ICommandProperties Définit les propriétés Rowset<br />
pour les jeux <strong>de</strong> lignes créés<br />
par une comman<strong>de</strong>. Utilisée<br />
le plus souvent pour spécifier<br />
les interfaces que le jeu <strong>de</strong><br />
lignes doit supporter.<br />
ICommandText Définit le texte <strong>de</strong> la<br />
comman<strong>de</strong> SQL pour<br />
ICommand.<br />
IcommandWithParame<br />
ters<br />
Définit ou obtient <strong>de</strong>s<br />
informations <strong>de</strong> paramètre<br />
pour une comman<strong>de</strong>.<br />
Supportée<br />
Seul le dialecte<br />
DBGUID_DEFAULT<br />
SQL est supporté.<br />
Aucun support pour les<br />
paramètres enregistrés<br />
comme vecteurs <strong>de</strong><br />
valeurs scalaires.<br />
Aucun support pour les<br />
paramètres BLOB.<br />
N'existe pas sous CE.<br />
IConvertType Supportée.<br />
Limitée sous CE.<br />
IDBAsynchNotify Traitement asynchrone. Non supportée<br />
IDBAsyncStatus Prévient le client <strong>de</strong>s<br />
événements pendant le<br />
traitement asynchrone <strong>de</strong><br />
l'initialisation <strong>de</strong> la source <strong>de</strong><br />
données, du remplissage <strong>de</strong>s<br />
jeux <strong>de</strong> lignes, etc.<br />
IDBCreateCommand Crée <strong>de</strong>s comman<strong>de</strong>s à partir<br />
d'une session.<br />
IDBCreateSession Crée une session à partir d'un<br />
objet <strong>de</strong> source <strong>de</strong> données.<br />
IDBDataSourceAdmin Crée/détruit/modifie <strong>de</strong>s<br />
objets <strong>de</strong> source <strong>de</strong> données,<br />
qui sont <strong>de</strong>s objets COM<br />
utilisés par les clients. Cette<br />
interface n'est pas utilisée<br />
pour la gestion <strong>de</strong>s sources<br />
<strong>de</strong> données (bases <strong>de</strong><br />
données).<br />
Supportée<br />
Supportée<br />
Non supportée<br />
379
Interfaces OLE DB supportées<br />
380<br />
Interface Fonction Restrictions<br />
IDBInfo Localise <strong>de</strong>s informations<br />
sur <strong>de</strong>s mots-clés propres à<br />
ce fournisseur (trouve <strong>de</strong>s<br />
mots-clés SQL non<br />
standard).<br />
En outre, trouve <strong>de</strong>s<br />
informations sur <strong>de</strong>s<br />
littéraux, caractères spéciaux<br />
utilisés dans les requêtes <strong>de</strong><br />
correspondance <strong>de</strong> texte et<br />
autres informations littérales.<br />
IDBInitialize Initialise les objets <strong>de</strong> source<br />
<strong>de</strong> données et les<br />
énumérateurs.<br />
IDBProperties Gère les propriétés d'un objet<br />
<strong>de</strong> source <strong>de</strong> données ou d'un<br />
énumérateur.<br />
IDBSchemaRowset Obtient <strong>de</strong>s informations sur<br />
les tables système, dans un<br />
format standard (jeu <strong>de</strong><br />
lignes).<br />
IErrorInfo<br />
IErrorLookup<br />
IErrorRecords<br />
Supporte un objet erreur<br />
ActiveX.<br />
IGetDataSource Renvoie un pointeur<br />
d'interface sur l'objet <strong>de</strong><br />
source <strong>de</strong> données <strong>de</strong> la<br />
session.<br />
IIn<strong>de</strong>xDefinition Crée ou supprime <strong>de</strong>s in<strong>de</strong>x<br />
dans la source <strong>de</strong> données.<br />
IMultipleResults Récupère plusieurs résultats<br />
(jeux <strong>de</strong> lignes ou décomptes<br />
<strong>de</strong> lignes) à partir d'une<br />
comman<strong>de</strong>.<br />
IOpenRowset Procédé non SQL pour avoir<br />
accès à une table <strong>de</strong> base <strong>de</strong><br />
données par son nom.<br />
IParentRowset Accè<strong>de</strong> aux jeux <strong>de</strong> lignes<br />
par chapitre/hiérarchisés.<br />
N'existe pas sous CE.<br />
N'existe pas sous CE.<br />
N'existe pas sous CE.<br />
N'existe pas sous CE.<br />
N'existe pas sous CE.<br />
Supportée<br />
Non supportée<br />
Supportée<br />
Supportée.<br />
L'ouverture d'une table<br />
avec son nom est<br />
supportée, mais pas<br />
avec un GUID.<br />
Non supportée
Chapitre 9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et ADO<br />
Interface Fonction Restrictions<br />
IRowset Accè<strong>de</strong> aux jeux <strong>de</strong> lignes. Supportée<br />
IRowsetChange Permet la retransmission<br />
dans la source <strong>de</strong>s données<br />
<strong>de</strong>s modifications <strong>de</strong>s<br />
données <strong>de</strong> jeu <strong>de</strong> lignes.<br />
InsertRow/SetData pas<br />
encore mis en oeuvre pour<br />
les objets BLOB.<br />
IRowsetChapterMemb<br />
er<br />
Accè<strong>de</strong> aux jeux <strong>de</strong> lignes<br />
par chapitre/hiérarchisés.<br />
IRowsetCurrentIn<strong>de</strong>x Modifie <strong>de</strong> façon dynamique<br />
l'in<strong>de</strong>x d'un jeu <strong>de</strong> lignes.<br />
IRowsetFind Localise dans un jeu <strong>de</strong><br />
lignes une ligne qui<br />
correspond à une valeur<br />
spécifiée.<br />
IRowsetI<strong>de</strong>ntity Compare les routines <strong>de</strong><br />
gestion <strong>de</strong> ligne.<br />
IRowsetIn<strong>de</strong>x Accè<strong>de</strong> aux in<strong>de</strong>x <strong>de</strong> bases<br />
<strong>de</strong> données.<br />
IRowsetInfo Trouve les informations sur<br />
les propriétés d'un jeu <strong>de</strong><br />
lignes ou l'objet ayant créé le<br />
jeu <strong>de</strong> lignes.<br />
IRowsetLocate Se positionne sur <strong>de</strong>s lignes<br />
d'un jeu <strong>de</strong> lignes, à l'ai<strong>de</strong> <strong>de</strong><br />
signets.<br />
IRowsetNotify Fournit une interface<br />
callback COM pour les<br />
événements <strong>de</strong> jeu <strong>de</strong> lignes.<br />
IRowsetRefresh Obtient la <strong>de</strong>rnière valeur <strong>de</strong><br />
données visible pour une<br />
transaction.<br />
IRowsetResynch Ancienne interface<br />
OLEDB 1.x, remplacée par<br />
IRowsetRefresh.<br />
IRowsetScroll Fait défiler un jeu <strong>de</strong> lignes<br />
pour extraire les données <strong>de</strong><br />
ligne.<br />
N'existe pas sous CE.<br />
Non supportée<br />
Non supportée<br />
Non supportée<br />
Non supportée<br />
Non supportée<br />
N'existe pas sous CE.<br />
N'existe pas sous CE.<br />
Supportée<br />
Non supportée<br />
Non supportée<br />
Non supportée<br />
381
Interfaces OLE DB supportées<br />
382<br />
Interface Fonction Restrictions<br />
IRowsetUpdate Reporte les modifications <strong>de</strong><br />
données d'un jeu <strong>de</strong> lignes<br />
jusqu'à appel d'Update.<br />
IRowsetView Utilise les vues sur un jeu <strong>de</strong><br />
lignes existant.<br />
ISequentialStream Récupère une colonne<br />
d'objet BLOB.<br />
ISessionProperties Obtient <strong>de</strong>s informations sur<br />
la propriété <strong>de</strong> la session.<br />
ISourcesRowset Obtient un jeu <strong>de</strong> lignes<br />
d'objets <strong>de</strong> source <strong>de</strong><br />
données et d'énumérateurs.<br />
ISQLErrorInfo<br />
ISupportErrorInfo<br />
ITableDefinition<br />
ITableDefinitionWith<br />
Constraints<br />
Supporte un objet erreur<br />
ActiveX.<br />
Crée, supprime et modifie<br />
<strong>de</strong>s tables, avec <strong>de</strong>s<br />
contraintes.<br />
ITransaction Vali<strong>de</strong> ou abandonne <strong>de</strong>s<br />
transactions.<br />
ITransactionJoin Supporte les transactions<br />
distribuées.<br />
ITransactionLocal Gère les transactions pour<br />
une session.<br />
Les balises ne sont pas toutes<br />
supportées.<br />
Supportée.<br />
N'existe pas sous CE.<br />
Non supportée<br />
Supportée pour la<br />
lecture seulement.<br />
Aucun support pour<br />
SetData avec cette<br />
interface.<br />
N'existe pas sous CE.<br />
Supportée<br />
N'existe pas sous CE.<br />
En option sous CE<br />
N'existe pas sous CE.<br />
Les balises ne sont pas<br />
toutes supportées.<br />
N'existe pas sous CE.<br />
Les balises ne sont pas<br />
toutes supportées.<br />
N'existe pas sous CE.<br />
N'existe pas sous CE.
Chapitre 9 Les interfaces <strong>de</strong> <strong>programmation</strong> OLE DB et ADO<br />
Interface Fonction Restrictions<br />
ITransactionOptions Obtient ou définit les options<br />
d'une transaction.<br />
IViewChapter Travaille avec les vues sur<br />
un jeu <strong>de</strong> lignes existant,<br />
spécifiquement pour<br />
appliquer <strong>de</strong>s filtres/un tri<br />
post-traitement aux lignes.<br />
IViewFilter Limite le contenu d'un jeu <strong>de</strong><br />
lignes aux lignes<br />
correspondant à un ensemble<br />
<strong>de</strong> conditions.<br />
IViewRowset L'ouverture d'un jeu <strong>de</strong><br />
lignes limite le contenu du<br />
jeu <strong>de</strong> lignes aux lignes<br />
vérifiant un ensemble <strong>de</strong><br />
conditions.<br />
IViewSort Applique un ordre <strong>de</strong> tri à<br />
une vue.<br />
N'existe pas sous CE.<br />
Non supportée<br />
Non supportée<br />
Non supportée<br />
Non supportée<br />
383
Interfaces OLE DB supportées<br />
384
CHAPITRE 10<br />
Interface Open Client<br />
Présentation<br />
Sommaire<br />
Ce chapitre décrit l'interface <strong>de</strong> <strong>programmation</strong> Open Client d'<strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>.<br />
La documentation principale associée au développement d'applications<br />
Open Client est disponible auprès <strong>de</strong> <strong>Sybase</strong>. Ce chapitre décrit <strong>de</strong>s fonctions<br />
spécifiques d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, mais n'est en aucun cas un gui<strong>de</strong><br />
exhaustif <strong>de</strong> la <strong>programmation</strong> d'applications Open Client.<br />
Sujet Page<br />
Préalables à la création d'applications Open Client 386<br />
Correspondances entre les types <strong>de</strong> données 387<br />
SQL dans les applications Open Client 389<br />
Limites d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> avec Open Client 392<br />
385
Préalables à la création d'applications Open Client<br />
Préalables à la création d'applications<br />
Open Client<br />
386<br />
Pour exécuter les applications Open Client, vous <strong>de</strong>vez installer et configurer<br />
les composants Open Client sur la même machine que l'application utilisée.<br />
Vous pouvez disposer <strong>de</strong> ces composants par l'installation d'autres produits<br />
<strong>Sybase</strong> ou installer les bibliothèques avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, selon<br />
les clauses <strong>de</strong> votre contrat <strong>de</strong> licence.<br />
Pour utiliser les applications Open Client, il n'est pas nécessaire que les<br />
composants Open Client se trouvent sur la même machine que le serveur <strong>de</strong><br />
base <strong>de</strong> données.<br />
Pour créer <strong>de</strong>s applications Open Client, vous <strong>de</strong>vez vous procurer la version<br />
<strong>de</strong> développement d'Open Client, disponible auprès <strong>de</strong> <strong>Sybase</strong>.<br />
Par défaut, les bases <strong>de</strong> données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> sont créées sans<br />
prendre en compte la distinction majuscules/minuscules, contrairement aux<br />
bases <strong>Adaptive</strong> <strong>Server</strong> Enterprise.<br />
$ Pour plus d'informations sur l'exécution <strong>de</strong>s applications Open Client<br />
avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, reportez-vous au chapitre "<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> exploité comme un Open <strong>Server</strong>", page 111 du document ASA<br />
<strong>Gui<strong>de</strong></strong> d’administration.
Chapitre 10 Interface Open Client<br />
Correspondances entre les types <strong>de</strong> données<br />
Types <strong>de</strong> données<br />
<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> sans<br />
équivalent direct<br />
dans Open Client<br />
Open Client dispose <strong>de</strong> ses propres types <strong>de</strong> données internes, qui diffèrent<br />
légèrement <strong>de</strong> ceux d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. C'est pourquoi <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong> effectue une mise en correspondance interne <strong>de</strong> certains<br />
types <strong>de</strong> données utilisés par les applications Open Client.<br />
Pour créer <strong>de</strong>s applications Open Client, vous <strong>de</strong>vez vous procurer la version<br />
<strong>de</strong> développement d'Open Client. Pour utiliser une application Open Client,<br />
les versions d'exécution (runtime) d'Open Client doivent être installées et<br />
configurées sur le même ordinateur que l'application.<br />
Le serveur <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> n'a pas besoin d'exécutable <strong>de</strong><br />
communication externe pour supporter les applications Open Client.<br />
Chaque type <strong>de</strong> données Open Client est mis en correspondance avec un type<br />
équivalent <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Tous les types <strong>de</strong> données Open<br />
Client sont supportés.<br />
Le tableau ci-<strong>de</strong>ssous dresse la liste <strong>de</strong>s mises en correspondance <strong>de</strong>s types<br />
<strong>de</strong> données supportés dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, n'ayant aucun<br />
équivalent direct dans Open Client.<br />
Type <strong>de</strong> données ASA Type <strong>de</strong> données Open Client<br />
unsigned short int<br />
unsigned int bigint<br />
unsigned bigint bigint<br />
date smalldatetime<br />
time smalldatetime<br />
serialization longbinary<br />
java longbinary<br />
string varchar<br />
timestamp struct datetime<br />
Limitation d’intervalle dans la mise en correspondance <strong>de</strong>s types<br />
<strong>de</strong> données<br />
Certains types <strong>de</strong> données présentent <strong>de</strong>s intervalles différents dans <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong> et dans Open Client. Dans ce cas, <strong>de</strong>s erreurs d'overflow<br />
peuvent survenir lors <strong>de</strong> la récupération ou <strong>de</strong> l'insertion <strong>de</strong> données.<br />
387
Correspondances entre les types <strong>de</strong> données<br />
Exemple<br />
Estampilles<br />
388<br />
Le tableau suivant indique les types <strong>de</strong> données <strong>de</strong>s applications Open Client<br />
possédant un équivalent sous <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> mais dont les<br />
intervalles <strong>de</strong>s valeurs admises diffèrent.<br />
Dans la plupart <strong>de</strong>s cas, les données Open Client acceptent un intervalle <strong>de</strong><br />
valeurs plus restreint que les données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
correspondantes. Par conséquent, il n'est pas exclu qu'une valeur transmise à<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> soit reconnue et stockée dans une base <strong>de</strong><br />
données, mais qu'elle soit en <strong>de</strong>hors <strong>de</strong>s intervalles admis par l'application<br />
Open Client.<br />
Type <strong>de</strong> données Open Client -<br />
limite<br />
inférieure<br />
MONEY –922 377 203<br />
685 477.5808<br />
Open Client -<br />
limite<br />
supérieure<br />
922 377 203<br />
685 477.5807<br />
ASA - limite<br />
inférieure<br />
ASA - limite<br />
supérieure<br />
–1e15 + 0.0001 1e15 – 0.0001<br />
SMALLMONEY –214 748.3648 214 748.3647 –214 748.3648 214 748.3647<br />
DATETIME 1 janvier 1753 31 décembre<br />
9999<br />
1 janvier 0001 31 décembre<br />
9999<br />
SMALLDATETIME 1 janvier 1900 6 juin 2079 1 mars 1600 31 décembre<br />
7910<br />
Les données Open Client <strong>de</strong> type MONEY et SMALLMONEY ne possè<strong>de</strong>nt<br />
pas un intervalle <strong>de</strong> valeurs numériques aussi étendu que leurs équivalents<br />
dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Par conséquent, il se peut que les valeurs<br />
d'une colonne dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> correspondant au type <strong>de</strong><br />
données MONEY Open Client, dépassent les limites imposées par ce <strong>de</strong>rnier.<br />
Lorsque le client lit <strong>de</strong>s valeurs répondant à ce cas <strong>de</strong> figure via <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>, une erreur survient.<br />
La mise en oeuvre dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> <strong>de</strong>s données <strong>de</strong> type<br />
TIMESTAMP d'Open Client diffère <strong>de</strong> celle d'<strong>Adaptive</strong> <strong>Server</strong> Enterprise.<br />
Dans <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, la valeur est convertie en type <strong>de</strong> données<br />
DATETIME. La valeur par défaut est NULL dans<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, sans garantie d'unicité. En revanche,<br />
<strong>Adaptive</strong> <strong>Server</strong> Enterprise incrémente automatiquement sa valeur, ce qui la<br />
rend unique.<br />
Inversement, le type <strong>de</strong> données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> TIMESTAMP<br />
contient l'année, le mois, le jour, l'heure, les minutes, les secon<strong>de</strong>s et les<br />
fractions <strong>de</strong> secon<strong>de</strong>. De plus, le type DATETIME offre un plus grand<br />
intervalle <strong>de</strong> valeurs que les types <strong>de</strong> données Open Client mis en<br />
correspondance par <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.
SQL dans les applications Open Client<br />
Exécution d'instructions SQL<br />
Chapitre 10 Interface Open Client<br />
Cette section fournit un aperçu rapi<strong>de</strong> <strong>de</strong> l'utilisation <strong>de</strong> SQL dans les<br />
applications Open Client et examine plus particulièrement les questions<br />
spécifiques d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
$ Pour une présentation <strong>de</strong>s concepts, reportez-vous au chapitre<br />
"Utilisation <strong>de</strong> SQL dans les applications", page 9. Pour une <strong>de</strong>scription plus<br />
complète, reportez-vous à la documentation d'Open Client.<br />
Vous pouvez envoyer <strong>de</strong>s instructions SQL à une base <strong>de</strong> données en les<br />
incluant dans <strong>de</strong>s appels <strong>de</strong> fonction Client Library. Par exemple, les <strong>de</strong>ux<br />
appels suivants exécutent une instruction DELETE :<br />
ret = ct_command(cmd, CS_LANG_CMD,<br />
"DELETE FROM employee<br />
WHERE emp_id=105"<br />
CS_NULLTERM,<br />
CS_UNUSED);<br />
ret = ct_send(cmd);<br />
La fonction ct_command offre <strong>de</strong> nombreuses possibilités d'utilisation.<br />
Utilisation d'instructions préparées<br />
La fonction ct_dynamic permet <strong>de</strong> gérer les instructions préparées. Cette<br />
fonction accepte le paramètre type, qui décrit l'opération que vous effectuez.<br />
v Pour utiliser une instruction préparée dans Open Client :<br />
1 Préparez l'instruction via la fonction ct_dynamic, avec le paramètre<br />
type CS_PREPARE.<br />
2 Définissez les paramètres <strong>de</strong> l'instruction avec ct_param.<br />
3 Exécutez l'instruction via ct_dynamic avec le paramètre type<br />
CS_EXECUTE.<br />
4 Libérez les ressources associées à l'instruction via ct_dynamic avec<br />
le paramètre type CS_DEALLOC.<br />
$ Pour plus d'informations sur l'utilisation d'instructions préparées dans<br />
Open Client, consultez la documentation d'Open Client.<br />
389
SQL dans les applications Open Client<br />
Curseurs<br />
Types <strong>de</strong> curseurs<br />
supportés<br />
Etapes d'utilisation<br />
<strong>de</strong>s curseurs<br />
390<br />
La fonction ct_cursor permet <strong>de</strong> gérer les curseurs. Cette fonction<br />
accepte le paramètre type, qui décrit l'opération que vous effectuez.<br />
Certains types <strong>de</strong> curseurs supportés par <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> ne sont<br />
pas disponibles via l'interface Open Client. Il n'est pas possible d'utiliser <strong>de</strong>s<br />
curseurs <strong>de</strong> défilement, <strong>de</strong>s curseurs <strong>de</strong> défilement dynamiques, ou encore<br />
<strong>de</strong>s curseurs insensibles (insensitive) par l'intermédiaire d'Open Client.<br />
Les curseurs possè<strong>de</strong>nt entre autres propriétés la garantie d'unicité et la<br />
capacité <strong>de</strong> mise à jour. Les curseurs peuvent être uniques (chaque ligne<br />
comporte <strong>de</strong>s informations <strong>de</strong> clé primaire ou d'unicité, qu'elles soient<br />
utilisées ou non par l'application) ou ne pas l'être. Les curseurs peuvent être<br />
en lecture seule ou capables <strong>de</strong> mise à jour. Lorsqu'un curseur peut être mis à<br />
jour mais n'est pas unique, aucune prélecture <strong>de</strong> ligne n'est possible, quelle<br />
que soit la valeur du paramètre CS_CURSOR_ROWS, et cela risque <strong>de</strong><br />
diminuer les performances.<br />
Contrairement à d'autres interfaces, telles qu'Embed<strong>de</strong>d SQL, Open Client<br />
associe un curseur aux instructions SQL sous la forme d'une chaîne.<br />
Embed<strong>de</strong>d SQL prépare tout d'abord une instruction, puis Open Client<br />
déclare le curseur par l'intermédiaire du <strong>de</strong>scripteur d'instruction.<br />
v Pour utiliser <strong>de</strong>s curseurs dans Open Client :<br />
1 Pour déclarer un curseur dans Open Client, utilisez ct_cursor avec le<br />
paramètre type CS_CURSOR_DECLARE.<br />
2 Après avoir déclaré un curseur, vous pouvez déterminer le nombre <strong>de</strong><br />
lignes faisant l'objet d'une extraction préalable du côté client à chaque<br />
fois qu'une ligne est extraite du serveur par l'intermédiaire <strong>de</strong><br />
ct_cursor avec le paramètre type CS_CURSOR_ROWS.<br />
Le fait <strong>de</strong> stocker <strong>de</strong>s lignes préalablement extraites du côté client<br />
diminue le nombre d'appels effectués vers le serveur, améliorant ainsi le<br />
débit global et le délai d'exécution. Les lignes ayant fait l'objet d'une<br />
extraction préalable ne sont pas transmises immédiatement à<br />
l'application, mais stockées dans un buffer du côté client, prêtes à être<br />
utilisées.<br />
L'option <strong>de</strong> base <strong>de</strong> données PREFETCH contrôle l'extraction préalable<br />
<strong>de</strong>s lignes pour d'autres interfaces. En revanche, elle est ignorée par les<br />
connexions Open Client. Le paramètre CS_CURSOR_ROWS est ignoré<br />
pour les curseurs non uniques pouvant être mis à jour.<br />
3 Pour ouvrir un curseur dans Open Client, utilisez ct_cursor avec le<br />
paramètre type CS_CURSOR_OPEN.
Modification <strong>de</strong> lignes via un curseur<br />
Chapitre 10 Interface Open Client<br />
4 Pour extraire chaque ligne vers l’application, utilisez ct_fetch.<br />
5 Pour fermer un curseur, utilisez ct_cursor avec CS_CURSOR_CLOSE.<br />
6 Dans Open Client, vous <strong>de</strong>vez également libérer les ressources associées<br />
à un curseur. Pour ce faire, utilisez ct_cursor avec<br />
CS_CURSOR_DEALLOC. Vous pouvez aussi utiliser<br />
CS_CURSOR_CLOSE avec le paramètre complémentaire<br />
CS_DEALLOC pour effectuer ces opérations en une seule étape.<br />
Avec Open Client, vous pouvez supprimer ou mettre à jour les lignes d'un<br />
curseur tant que ce <strong>de</strong>rnier est créé sur une seule table. L'utilisateur doit avoir<br />
l'autorisation <strong>de</strong> mettre à jour la table et le curseur doit être créé en mo<strong>de</strong><br />
mise à jour.<br />
v Pour modifier <strong>de</strong>s lignes via un curseur :<br />
♦ Au lieu d'exécuter une extraction, vous pouvez supprimer ou mettre à<br />
jour la ligne active du curseur en utilisant respectivement ct_cursor avec<br />
CS_CURSOR_DELETE ou CS_CURSOR_UPDATE.<br />
Vous ne pouvez pas insérer <strong>de</strong> lignes par l'intermédiaire d'un curseur dans les<br />
applications Open Client.<br />
Description <strong>de</strong>s résultats <strong>de</strong> requêtes dans Open Client<br />
Open Client gère les jeux <strong>de</strong> résultats différemment d'autres interfaces<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Avec Embed<strong>de</strong>d SQL et ODBC, vous <strong>de</strong>vez décrire une requête ou une<br />
procédure stockée pour définir le nombre et les types <strong>de</strong> variables corrects<br />
attendus dans le résultat. La <strong>de</strong>scription est effectuée dans l'instruction ellemême.<br />
Dans Open Client, il est inutile <strong>de</strong> décrire les instructions. En effet, chaque<br />
ligne renvoyée par le serveur peut comporter une <strong>de</strong>scription <strong>de</strong> son contenu.<br />
Si vous utilisez ct_command et ct_send pour exécuter <strong>de</strong>s instructions,<br />
vous pouvez utiliser la fonction ct_results pour gérer tous les aspects<br />
<strong>de</strong>s lignes renvoyées par les requêtes.<br />
Si vous ne souhaitez pas utiliser cette métho<strong>de</strong> <strong>de</strong> gestion <strong>de</strong>s jeux <strong>de</strong><br />
résultats ligne par ligne, vous pouvez utiliser ct_dynamic pour préparer<br />
une instruction SQL et ct_<strong>de</strong>scribe pour décrire son jeu <strong>de</strong> résultats.<br />
Cela correspond <strong>de</strong> manière plus proche à la <strong>de</strong>scription <strong>de</strong>s instructions<br />
SQL dans d'autres interfaces.<br />
391
Limites d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> avec Open Client<br />
Limites d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> avec Open<br />
Client<br />
392<br />
L’interface Open Client vous permet en gran<strong>de</strong> partie d’utiliser une base <strong>de</strong><br />
données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> <strong>de</strong> la même manière qu'une base <strong>de</strong><br />
données <strong>Adaptive</strong> <strong>Server</strong> Enterprise. Il existe toutefois <strong>de</strong>s restrictions, qui<br />
sont résumées ci-après :<br />
♦ Service Commit <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> ne supporte pas le service<br />
Commit d'<strong>Adaptive</strong> <strong>Server</strong> Enterprise.<br />
♦ Fonctions Les fonctions associées aux connexions client/serveur<br />
déterminent les types <strong>de</strong> requête client et <strong>de</strong> réponse serveur autorisés<br />
pour chaque connexion. Les fonctions suivantes ne sont pas supportées :<br />
♦ CS_REG_NOTIF<br />
♦ CS_CSR_ABS<br />
♦ CS_CSR_FIRST<br />
♦ CS_CSR_LAST<br />
♦ CS_CSR_PREV<br />
♦ CS_CSR_REL<br />
♦ CS_DATA_BOUNDARY<br />
♦ CS_DATA_SENSITIVITY<br />
♦ CS_PROTO_DYNPROC<br />
♦ CS_REQ_BCP<br />
♦ Les options <strong>de</strong> sécurité, comme SSL et les mots <strong>de</strong> passe cryptés, ne<br />
sont pas supportées.<br />
♦ Les applications Open Client peuvent se connecter à<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> via TCP/IP, ou en utilisant le protocole<br />
NamedPipes <strong>de</strong> la machine locale, le cas échéant.<br />
$ Pour plus d'informations sur les fonctions, reportez-vous au<br />
document Open <strong>Server</strong> <strong>Server</strong>-Library C Reference Manual.
CHAPITRE 11<br />
Transactions distribuées et architecture à<br />
trois niveaux<br />
Présentation<br />
Sommaire<br />
Ce chapitre décrit l'utilisation d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> dans un<br />
environnement d'architecture à trois niveaux avec un serveur applicatif. Il<br />
explique notamment comment inscrire <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> dans <strong>de</strong>s<br />
transactions distribuées.<br />
Sujet Page<br />
Introduction 394<br />
Architecture informatique à trois niveaux 395<br />
Utilisation <strong>de</strong>s transactions distribuées 399<br />
Utilisation d'EA<strong>Server</strong> avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> 401<br />
393
Introduction<br />
Introduction<br />
394<br />
Vous pouvez utiliser <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> comme serveur <strong>de</strong> base <strong>de</strong><br />
données ou comme gestionnaire <strong>de</strong> ressources, intervenant dans <strong>de</strong>s<br />
transactions distribuées coordonnées par un serveur <strong>de</strong> transactions.<br />
L'architecture à trois niveaux, dans laquelle un serveur applicatif joue un rôle<br />
d'intermédiaire entre les applications clientes et un ensemble <strong>de</strong> gestionnaires<br />
<strong>de</strong> ressources, est un environnement <strong>de</strong> transactions distribuées courant.<br />
<strong>Sybase</strong> EA<strong>Server</strong> et certains autres serveurs d'applications sont également<br />
<strong>de</strong>s serveurs <strong>de</strong> transactions.<br />
<strong>Sybase</strong> EA<strong>Server</strong> et Microsoft Transaction <strong>Server</strong> utilisent le service DTC<br />
(Distributed Transaction Coordinator) <strong>de</strong> Microsoft pour coordonner les<br />
transactions. De son côté, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte les<br />
transactions distribuées contrôlées par le service DTC ; vous pouvez ainsi<br />
l'utiliser soit avec ces serveurs d'applications, soit avec tout autre produit<br />
basé sur le modèle DTC.<br />
Lors <strong>de</strong> l'intégration d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> dans un environnement à<br />
trois niveaux, l'essentiel du travail doit être accompli à partir du serveur<br />
applicatif. Ce chapitre fournit une présentation générale <strong>de</strong>s concepts et <strong>de</strong><br />
l'architecture informatique à trois niveaux ainsi que <strong>de</strong>s fonctionnalités<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> correspondantes. Il ne décrit pas comment<br />
configurer votre serveur applicatif pour qu'il fonctionne avec<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Pour plus d'informations, reportez-vous à la<br />
documentation <strong>de</strong> votre serveur applicatif.
Chapitre 11 Transactions distribuées et architecture à trois niveaux<br />
Architecture informatique à trois niveaux<br />
Dans l'informatique à trois niveaux, la logique <strong>de</strong> l'application est conservée<br />
sur un serveur applicatif, tel que <strong>Sybase</strong> EA<strong>Server</strong>, qui fait le lien entre le<br />
gestionnaire <strong>de</strong> ressources et les applications clientes. Bien souvent, un seul<br />
serveur applicatif peut accé<strong>de</strong>r à plusieurs gestionnaires <strong>de</strong> ressources. Avec<br />
Internet, les applications clientes sont basées sur un navigateur et le serveur<br />
applicatif est généralement une extension du serveur Web.<br />
Serveurs<br />
d’applications<br />
<strong>Sybase</strong> EA<strong>Server</strong> enregistre la logique <strong>de</strong> l'application sous forme <strong>de</strong><br />
composants, qu'elle met à la disposition <strong>de</strong>s applications clientes. Il peut<br />
s'agir <strong>de</strong> composants PowerBuil<strong>de</strong>r, JavaBeans ou COM.<br />
$ Pour plus d'informations, reportez-vous à la documentation<br />
<strong>Sybase</strong> EA<strong>Server</strong>.<br />
395
Architecture informatique à trois niveaux<br />
Transactions distribuées dans une architecture à trois niveaux<br />
<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> dans les<br />
transactions<br />
distribuées<br />
396<br />
Lorsque <strong>de</strong>s applications clientes ou <strong>de</strong>s serveurs applicatifs utilisent une<br />
seule base <strong>de</strong> données <strong>de</strong> traitement <strong>de</strong>s transactions, telle<br />
qu'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, aucune logique transactionnelle externe à la<br />
base n'est nécessaire ; mais s'ils utilisent plusieurs gestionnaires <strong>de</strong><br />
ressources, le contrôle <strong>de</strong>s transactions doit couvrir les ressources impliquées<br />
dans ces transactions. Les serveurs applicatifs peuvent eux aussi fournir la<br />
logique <strong>de</strong> transaction à leurs applications clientes, ce qui garantit que <strong>de</strong>s<br />
ensembles d'opérations sont exécutés <strong>de</strong> façon atomique sur plusieurs bases<br />
<strong>de</strong> données.<br />
De nombreux serveurs <strong>de</strong> transactions, notamment <strong>Sybase</strong> EA<strong>Server</strong>,<br />
utilisent DTC (Distributed Transaction Coordinator) <strong>de</strong> Microsoft pour<br />
fournir les services transactionnels à leurs applications clientes. DTC utilise<br />
<strong>de</strong>s transactions OLE, qui à leur tour font appel au protocole <strong>de</strong> commit à<br />
<strong>de</strong>ux phases pour coordonner les transactions mettant en oeuvre plusieurs<br />
gestionnaires <strong>de</strong> ressources. DTC doit être installé pour utiliser les<br />
fonctionnalités décrites dans ce chapitre.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> peut intervenir dans <strong>de</strong>s transactions<br />
coordonnées par DTC ; en d'autres termes, vous pouvez utiliser <strong>de</strong>s bases <strong>de</strong><br />
données <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> dans <strong>de</strong>s transactions distribuées en<br />
utilisant un serveur <strong>de</strong> transactions tel que <strong>Sybase</strong> EA<strong>Server</strong> ou<br />
Microsoft Transaction <strong>Server</strong>. Vous pouvez aussi utiliser DTC directement<br />
dans vos applications pour coordonner <strong>de</strong>s transactions entre plusieurs<br />
gestionnaires <strong>de</strong> ressources.<br />
Terminologie relative aux transactions distribuées<br />
Il est supposé dans ce chapitre que vous avez une certaine connaissance <strong>de</strong>s<br />
transactions distribuées. Pour plus d'informations, reportez-vous à la<br />
documentation <strong>de</strong> votre serveur <strong>de</strong> transactions. Cette section présente les<br />
termes et expressions fréquemment employés.<br />
♦ Les gestionnaires <strong>de</strong> ressources sont les services qui gèrent les données<br />
impliquées dans la transaction.<br />
Lorsque l'accès au serveur <strong>de</strong> base <strong>de</strong> données<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> s'effectue par le biais d'ODBC ou<br />
d'OLE DB, celui-ci peut jouer le rôle <strong>de</strong> gestionnaire <strong>de</strong> ressources dans<br />
une transaction distribuée. Le pilote ODBC et le fournisseur OLE DB se<br />
comportent comme <strong>de</strong>s proxies du gestionnaire <strong>de</strong> ressources sur la<br />
machine cliente.
Commit à <strong>de</strong>ux<br />
phases<br />
Chapitre 11 Transactions distribuées et architecture à trois niveaux<br />
♦ Au lieu <strong>de</strong> communiquer directement avec le gestionnaire <strong>de</strong> ressources,<br />
les composants applicatifs peuvent communiquer avec <strong>de</strong>s distributeurs<br />
<strong>de</strong> ressources, qui à leur tour gèrent les connexions ou les zones <strong>de</strong><br />
connexions aux gestionnaires <strong>de</strong> ressources.<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> supporte <strong>de</strong>ux distributeurs <strong>de</strong> ressources : le<br />
gestionnaire <strong>de</strong> pilotes ODBC et OLE DB.<br />
♦ Lorsqu'un composant transactionnel <strong>de</strong>man<strong>de</strong> une connexion à la base<br />
<strong>de</strong> données (via un gestionnaire <strong>de</strong> ressources), le serveur applicatif<br />
inscrit chaque connexion qui prend part à la transaction. DTC et le<br />
distributeur <strong>de</strong> ressources effectuent le processus d'inscription.<br />
Les transactions distribuées sont gérées par le biais d'un commit à <strong>de</strong>ux<br />
phases. Lorsqu'une transaction est terminée, le gestionnaire <strong>de</strong> transactions<br />
(DTC) <strong>de</strong>man<strong>de</strong> à tous les gestionnaires <strong>de</strong> ressources inscrits dans la<br />
transaction s'ils sont prêts à la vali<strong>de</strong>r. Cette phase correspond à la<br />
préparation du commit.<br />
Si tous les gestionnaires <strong>de</strong> ressources répon<strong>de</strong>nt qu'ils sont prêts, DTC<br />
envoie une <strong>de</strong>man<strong>de</strong> <strong>de</strong> validation à chacun et informe son client que la<br />
transaction est terminée. Si un ou plusieurs gestionnaires <strong>de</strong> ressources ne<br />
répon<strong>de</strong>nt pas ou ne sont pas prêts, tout le travail <strong>de</strong> la transaction est annulé<br />
au niveau <strong>de</strong> tous les gestionnaires <strong>de</strong> ressources.<br />
Utilisation <strong>de</strong> DTC par les serveurs d’applications<br />
<strong>Sybase</strong> EA<strong>Server</strong> et Microsoft Transaction <strong>Server</strong> sont tous <strong>de</strong>ux <strong>de</strong>s<br />
serveurs <strong>de</strong> composants. La logique applicative est enregistrée sous forme <strong>de</strong><br />
composants et mise à la disposition <strong>de</strong>s applications clientes.<br />
Chaque composant possè<strong>de</strong> un attribut <strong>de</strong> transaction qui indique la manière<br />
dont il prend part aux transactions. Le développeur d'applications qui crée le<br />
composant doit programmer dans ce <strong>de</strong>rnier les tâches qu'exécutera la<br />
transaction, à savoir les connexions au gestionnaire <strong>de</strong> ressources et les<br />
opérations sur les données dont le gestionnaire <strong>de</strong> ressources a la charge.<br />
Toutefois, il n'est pas nécessaire d'y ajouter la logique <strong>de</strong> gestion <strong>de</strong>s<br />
transactions. Une fois que l'attribut <strong>de</strong> transaction défini indique que le<br />
composant a besoin d'une gestion <strong>de</strong> transaction, EA<strong>Server</strong> utilise DTC pour<br />
inscrire la transaction et gérer le processus <strong>de</strong> commit à <strong>de</strong>ux phases.<br />
Architecture <strong>de</strong>s transactions distribuées<br />
Le schéma suivant illustre l'architecture <strong>de</strong> transactions distribuées. Dans ce<br />
cas, le proxy du gestionnaire <strong>de</strong> ressources est indifféremment ODBC ou<br />
OLE DB.<br />
397
Architecture informatique à trois niveaux<br />
398<br />
Système<br />
client<br />
Proxy du<br />
gestionnaire<br />
<strong>de</strong><br />
ressources<br />
DTC<br />
Serveur<br />
système 1<br />
Serveur<br />
d’applications<br />
DTC<br />
DTC<br />
Serveur<br />
système 2<br />
Proxy du<br />
gestionnaire<br />
<strong>de</strong><br />
ressources<br />
Dans cet exemple, un distributeur <strong>de</strong> ressources est utilisé. Le serveur<br />
applicatif <strong>de</strong>man<strong>de</strong> au service DTC <strong>de</strong> préparer une transaction. DTC et le<br />
distributeur inscrivent chaque connexion figurant dans la transaction. Chaque<br />
gestionnaire <strong>de</strong> ressources doit être en contact avec DTC et avec la base <strong>de</strong><br />
données afin d'exécuter le travail et, au moment requis, d'informer DTC du<br />
statut <strong>de</strong> la transaction.<br />
Pour permettre le traitement <strong>de</strong>s transactions distribuées, un service DTC<br />
doit être actif sur chaque machine. Vous contrôlez les services DTC <strong>de</strong>puis<br />
l'icône Services dans le panneau <strong>de</strong> configuration <strong>de</strong> Windows ; le service<br />
DTC s'appelle MSDTC.<br />
$ Pour plus d'informations, reportez-vous à la documentation <strong>de</strong> DTC ou<br />
d'EA<strong>Server</strong>.
Chapitre 11 Transactions distribuées et architecture à trois niveaux<br />
Utilisation <strong>de</strong>s transactions distribuées<br />
Niveaux d’isolement DTC<br />
Lorsque <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est inscrit dans une transaction<br />
distribuée, il transmet le contrôle <strong>de</strong> la transaction au serveur <strong>de</strong> transactions<br />
et s'assure qu'il n'effectue pas une gestion implicite <strong>de</strong> la transaction. Les<br />
conditions suivantes sont automatiquement imposées par<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> lorsqu'il intervient dans <strong>de</strong>s transactions<br />
distribuées :<br />
♦ L'autocommit est automatiquement désactivé.<br />
♦ Les instructions <strong>de</strong> définition <strong>de</strong> données (qui ont pour effet d'exécuter<br />
un commit) sont interdites pendant le déroulement <strong>de</strong>s transactions<br />
distribuées.<br />
♦ Une instruction explicite COMMIT ou ROLLBACK adressée par<br />
l'application à <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> directement, et non par le<br />
biais du coordinateur <strong>de</strong> transactions, génère une erreur. Toutefois, la<br />
transaction n'est pas abandonnée.<br />
♦ Une connexion ne peut participer qu'à une seule transaction distribuée à<br />
la fois.<br />
♦ Aucune opération non validée ne doit avoir lieu au moment où la<br />
connexion est inscrite dans une transaction distribuée.<br />
DTC possè<strong>de</strong> un ensemble <strong>de</strong> niveaux d'isolement, spécifiés par le serveur<br />
applicatif. Ces niveaux d'isolement sont mis en correspondance avec les<br />
niveaux d'isolement d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> comme suit :<br />
Niveau d’isolement DTC Niveau d’isolement<br />
<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong><br />
ISOLATIONLEVEL_UNSPECIFIED 0<br />
ISOLATIONLEVEL_CHAOS 0<br />
ISOLATIONLEVEL_READUNCOMMITTED 0<br />
ISOLATIONLEVEL_BROWSE 0<br />
399
Utilisation <strong>de</strong>s transactions distribuées<br />
400<br />
Niveau d’isolement DTC Niveau d’isolement<br />
<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong><br />
ISOLATIONLEVEL_CURSORSTABILITY 1<br />
ISOLATIONLEVEL_READCOMMITTED 1<br />
ISOLATIONLEVEL_REPEATABLEREAD 2<br />
ISOLATIONLEVEL_SERIALIZABLE 3<br />
ISOLATIONLEVEL_ISOLATED 3<br />
Reprise à partir <strong>de</strong> transactions distribuées<br />
Si le serveur <strong>de</strong> base <strong>de</strong> données tombe en panne tandis que <strong>de</strong>s opérations<br />
non validées sont en attente, il doit soit les annuler, soit les vali<strong>de</strong>r au<br />
moment du démarrage, afin <strong>de</strong> préserver la nature atomique <strong>de</strong> la transaction.<br />
Si <strong>de</strong>s opérations non validées issues d'une transaction distribuée sont<br />
détectées durant une reprise, le serveur <strong>de</strong> base <strong>de</strong> données tente <strong>de</strong> se<br />
connecter à DTC et <strong>de</strong>man<strong>de</strong> à être réinscrit dans les transactions en attente<br />
ou pour lesquelles un doute subsiste. Une fois la réinscription terminée, DTC<br />
ordonne au serveur <strong>de</strong> base <strong>de</strong> données d'annuler ou <strong>de</strong> vali<strong>de</strong>r les opérations<br />
restantes.<br />
Si la réinscription échoue, <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> n'a aucun moyen <strong>de</strong><br />
savoir si les opérations sujettes à caution doivent être validées ou annulées, et<br />
la reprise échoue. Toutefois, si vous tenez à effectuer une reprise <strong>de</strong> cette<br />
base, malgré l'état incertain <strong>de</strong> ses données, vous pouvez l'imposer en<br />
utilisant les options suivantes du serveur <strong>de</strong> base <strong>de</strong> données :<br />
♦ -tmf Si DTC est introuvable, les opérations restantes sont annulées et la<br />
reprise se poursuit.<br />
$ Pour plus d'informations, reportez-vous à la section "Option <strong>de</strong><br />
serveur -tmf", page 164 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
♦ -tmt Si la réinscription n'est pas terminée avant le moment spécifié, les<br />
opérations restantes sont annulées et la reprise se poursuit.<br />
$ Pour plus d'informations, reportez-vous à la section "Option <strong>de</strong><br />
serveur -tmt", page 163 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.
Chapitre 11 Transactions distribuées et architecture à trois niveaux<br />
Utilisation d’EA<strong>Server</strong> avec <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong><br />
Configuration d’EA<strong>Server</strong><br />
Cette section présente les opérations à effectuer dans EA<strong>Server</strong> version 3.0<br />
ou ultérieures pour qu'il fonctionne avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Pour<br />
plus d'informations, reportez-vous à la documentation d'EA<strong>Server</strong>.<br />
Tous les composants installés dans <strong>Sybase</strong> EA<strong>Server</strong> partagent le même<br />
coordinateur <strong>de</strong> transactions.<br />
EA<strong>Server</strong> 3.0 (et versions ultérieures) propose plusieurs coordinateurs <strong>de</strong><br />
transactions. Vous <strong>de</strong>vez utiliser DTC comme coordinateur si vous incluez<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> dans les transactions. Cette section explique<br />
comment configurer EA<strong>Server</strong> 3.0 pour utiliser DTC comme coordinateur <strong>de</strong><br />
transactions.<br />
Le serveur <strong>de</strong> composants dans EA<strong>Server</strong> s'appelle Jaguar.<br />
v Pour configurer un serveur EA<strong>Server</strong> en vue d'utiliser le modèle<br />
transactionnel DTC <strong>de</strong> Microsoft :<br />
1 Vérifiez que le serveur Jaguar est actif.<br />
Sous Windows, le serveur Jaguar est généralement utilisé en tant que<br />
service. Pour démarrer manuellement le serveur Jaguar installé, fourni<br />
avec EA<strong>Server</strong> 3.0, sélectionnez<br />
Démarrer➤Programmes➤<strong>Sybase</strong>➤EA<strong>Server</strong>➤EA<strong>Server</strong>.<br />
2 Démarrez Jaguar Manager.<br />
A partir du bureau Windows, sélectionnez<br />
Démarrer➤Programmes➤<strong>Sybase</strong>➤EA<strong>Server</strong>➤Jaguar Manager.<br />
3 Connectez-vous au serveur Jaguar à partir <strong>de</strong> Jaguar Manager.<br />
Dans le menu <strong>Sybase</strong> Central, choisissez Outils➤Connexion➤Jaguar<br />
Manager. Dans la boîte <strong>de</strong> dialogue <strong>de</strong> connexion, entrez jagadmin<br />
comme nom d'utilisateur, laissez le champ Mot <strong>de</strong> passe vi<strong>de</strong> et indiquez<br />
localhost comme nom d'hôte. Cliquez sur OK pour vous connecter.<br />
4 Définissez le modèle transactionnel pour le serveur Jaguar.<br />
401
Utilisation d’EA<strong>Server</strong> avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
402<br />
Dans le volet gauche, ouvrez le dossier Serveurs. Dans le volet droit,<br />
cliquez avec le bouton droit sur le serveur que vous voulez configurer,<br />
puis sélectionnez Propriétés serveur dans le menu contextuel. Cliquez<br />
sur l'onglet Transactions et choisissez Microsoft DTC comme modèle.<br />
Cliquez sur OK pour terminer.<br />
Définition <strong>de</strong> l'attribut <strong>de</strong> transaction du composant<br />
Dans EA<strong>Server</strong>, vous pouvez mettre en oeuvre un composant qui exécute <strong>de</strong>s<br />
opérations sur plusieurs bases <strong>de</strong> données. Vous affectez à ce composant un<br />
attribut <strong>de</strong> transaction qui définit son mo<strong>de</strong> <strong>de</strong> participation dans les<br />
transactions. L'attribut <strong>de</strong> transaction peut prendre les valeurs suivantes :<br />
♦ Not Supported Les métho<strong>de</strong>s du composant ne s'exécutent jamais en<br />
tant qu'élément d'une transaction. Si le composant est activé par un autre<br />
composant qui s'exécute dans une transaction, les tâches <strong>de</strong> la nouvelle<br />
instance sont effectuées hors <strong>de</strong> la transaction existante. Il s'agit <strong>de</strong> la<br />
valeur par défaut.<br />
♦ Supports Transaction Le composant peut s'exécuter dans le contexte<br />
d'une transaction mais aucune connexion n'est requise pour l'exécution<br />
<strong>de</strong> ses métho<strong>de</strong>s. Si le composant est instancié directement par un client<br />
<strong>de</strong> base, EA<strong>Server</strong> ne démarre pas <strong>de</strong> transaction. Ainsi, si le composant<br />
A est instancié par le composant B et si B s'exécute dans une transaction,<br />
A s'exécute dans la même transaction.<br />
♦ Requires Transaction Le composant s'exécute toujours dans une<br />
transaction. Lorsqu'il est instancié directement par un client <strong>de</strong> base, une<br />
nouvelle transaction commence. Ainsi, si le composant A est activé par<br />
le composant B et si B s'exécute dans une transaction, A s'exécutera<br />
dans la même transaction ; si B ne s'exécute pas dans une transaction, A<br />
s'exécutera dans une nouvelle transaction.<br />
♦ Requires New Transaction Chaque fois que le composant est instancié,<br />
une nouvelle transaction commence. Si le composant A est activé par le<br />
composant B et si B s'exécute dans une transaction, A commence une<br />
nouvelle transaction qui n'est pas touchée par les résultats <strong>de</strong> la<br />
transaction <strong>de</strong> B ; si B ne s'exécute pas dans une transaction, A s'exécute<br />
dans une nouvelle transaction.<br />
Ainsi, dans l'exemple d'application Virtual University <strong>de</strong> <strong>Sybase</strong>, fourni avec<br />
EA<strong>Server</strong> sous le nom <strong>de</strong> package SVU, la métho<strong>de</strong> enroll() du composant<br />
SVUEnrollment exécute <strong>de</strong>ux opérations distinctes (réservation d'une place<br />
à une conférence, facturation <strong>de</strong> la conférence à l'étudiant). Ces <strong>de</strong>ux<br />
opérations doivent être traitées comme une transaction unique.
Chapitre 11 Transactions distribuées et architecture à trois niveaux<br />
Microsoft Transaction <strong>Server</strong> propose le même ensemble <strong>de</strong> valeurs<br />
d'attribut.<br />
v Pour définir l'attribut <strong>de</strong> transaction d'un composant :<br />
1 Dans Jaguar Manager, localisez le composant.<br />
Pour localiser le composant SVUEnrollment dans l’exemple<br />
d’application Jaguar, connectez-vous au serveur Jaguar, ouvrez le dossier<br />
Packages, puis le package SVU. La liste <strong>de</strong>s composants du package<br />
s’affiche dans le volet droit.<br />
2 Définissez l'attribut <strong>de</strong> transaction pour le composant choisi.<br />
Cliquez sur le composant avec le bouton droit <strong>de</strong> la souris, puis<br />
sélectionnez Component Properties dans le menu contextuel. Cliquez sur<br />
l'onglet Transaction et choisissez dans la liste la valeur <strong>de</strong> l'attribut <strong>de</strong><br />
transaction. Cliquez sur OK pour terminer.<br />
Le composant SVUEnrollment possè<strong>de</strong> déjà l'attribut Requires<br />
Transaction.<br />
Une fois l'attribut <strong>de</strong> transaction du composant défini, vous pouvez effectuer<br />
<strong>de</strong>s opérations <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> à partir <strong>de</strong> ce composant, en étant<br />
assuré que le traitement <strong>de</strong> la transaction se déroule au niveau spécifié.<br />
403
Utilisation d’EA<strong>Server</strong> avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
404
CHAPITRE 12<br />
Déploiement <strong>de</strong> bases <strong>de</strong> données et<br />
d'applications<br />
Présentation<br />
Sommaire<br />
Ce chapitre explique comment déployer les composants d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>. Il i<strong>de</strong>ntifie les fichiers requis pour le déploiement et traite <strong>de</strong>s<br />
procédures connexes, telles que le paramétrage <strong>de</strong>s connexions.<br />
Vérifiez votre contrat <strong>de</strong> licence<br />
La redistribution <strong>de</strong>s fichiers est soumise à votre contrat <strong>de</strong> licence.<br />
Aucune instruction <strong>de</strong> ce document ne prime sur une clause quelconque<br />
<strong>de</strong> votre contrat <strong>de</strong> licence. Veuillez consulter votre contrat <strong>de</strong> licence<br />
avant d'envisager le déploiement d'applications.<br />
Sujet Page<br />
Présentation du déploiement 406<br />
Répertoires d'installation et noms <strong>de</strong> fichiers 409<br />
Utilisation <strong>de</strong>s objets et modèles InstallShield pour le déploiement 414<br />
Déploiement avec une installation silencieuse 416<br />
Déploiement <strong>de</strong>s applications clientes 420<br />
Déploiement <strong>de</strong>s outils d'administration 431<br />
Déploiement <strong>de</strong>s serveurs <strong>de</strong> base <strong>de</strong> données 432<br />
Déploiement d'applications <strong>de</strong> base <strong>de</strong> données embarquées 435<br />
405
Présentation du déploiement<br />
Présentation du déploiement<br />
Modèles <strong>de</strong> déploiement<br />
406<br />
Lorsque vous avez terminé une application <strong>de</strong> base <strong>de</strong> données, vous <strong>de</strong>vez<br />
la déployer afin qu'elle soit accessible aux utilisateurs. Selon la manière dont<br />
votre application utilise <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> (comme base <strong>de</strong> données<br />
embarquée, en mo<strong>de</strong> client/serveur, etc.), vous <strong>de</strong>vrez peut-être déployer en<br />
même temps certains composants du logiciel <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Il<br />
peut être également nécessaire <strong>de</strong> déployer <strong>de</strong>s informations <strong>de</strong><br />
configuration, par exemple les noms <strong>de</strong>s sources <strong>de</strong> données, qui permettront<br />
à l'application <strong>de</strong> communiquer avec <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Vérifiez votre contrat <strong>de</strong> licence<br />
La redistribution <strong>de</strong> fichiers est soumise à votre contrat <strong>de</strong> licence avec<br />
<strong>Sybase</strong>. Aucune instruction <strong>de</strong> ce document ne prime sur une clause<br />
quelconque <strong>de</strong> votre contrat <strong>de</strong> licence. Veuillez consulter votre contrat <strong>de</strong><br />
licence avant d'envisager le déploiement d'applications.<br />
Voici les étapes <strong>de</strong> déploiement traitées dans ce chapitre :<br />
♦ Détermination <strong>de</strong>s fichiers requis en fonction du choix <strong>de</strong> la plate-forme<br />
et <strong>de</strong> l'architecture <strong>de</strong>s applications.<br />
♦ Configuration <strong>de</strong>s applications clientes.<br />
Ce chapitre traite essentiellement <strong>de</strong>s fichiers individuels et <strong>de</strong> leur<br />
emplacement. Toutefois, le mo<strong>de</strong> conseillé pour déployer les composants<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est l'utilisation <strong>de</strong>s objets InstallShield ou<br />
l'installation silencieuse. Pour plus d'informations, reportez-vous aux<br />
sections "Utilisation <strong>de</strong>s objets et modèles InstallShield pour le<br />
déploiement", page 414 et "Déploiement avec une installation silencieuse",<br />
page 416.<br />
Les fichiers qu'il convient <strong>de</strong> déployer dépen<strong>de</strong>nt du modèle <strong>de</strong> déploiement<br />
choisi. Voici quelques modèles possibles :<br />
♦ Déploiement client Vous pouvez ne déployer que la partie cliente<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> vers les utilisateurs finals, <strong>de</strong> sorte qu'ils<br />
puissent se connecter à un serveur <strong>de</strong> base <strong>de</strong> données sur un réseau<br />
central.<br />
♦ Déploiement serveur <strong>de</strong> réseau Vous pouvez déployer les serveurs <strong>de</strong><br />
réseau vers <strong>de</strong>s bureaux, puis déployer les clients vers chaque utilisateur<br />
<strong>de</strong> ces bureaux.
Mo<strong>de</strong>s <strong>de</strong> distribution <strong>de</strong>s fichiers<br />
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
♦ Déploiement <strong>de</strong> base <strong>de</strong> données embarquée Vous pouvez déployer<br />
une application exécutée via un serveur <strong>de</strong> base <strong>de</strong> données personnel.<br />
Dans ce cas, les serveurs client et personnel doivent tous <strong>de</strong>ux être<br />
installés sur la machine <strong>de</strong> l'utilisateur final.<br />
♦ Déploiement SQL Remote Déployer une application SQL Remote est<br />
une extension du modèle <strong>de</strong> déploiement <strong>de</strong> base <strong>de</strong> données embarquée.<br />
♦ Déploiement d'outils <strong>de</strong> base <strong>de</strong> données Vous pouvez déployer<br />
Interactive SQL, <strong>Sybase</strong> Central et d'autres outils <strong>de</strong> gestion.<br />
Pour déployer <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, vous avez le choix entre :<br />
♦ Utiliser l’installation d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> Vous pouvez<br />
mettre le programme <strong>de</strong> configuration à disposition <strong>de</strong>s utilisateurs<br />
finals. En sélectionnant ensuite l'option appropriée, chaque utilisateur<br />
final est assuré <strong>de</strong> recevoir les fichiers dont il a besoin.<br />
Cette solution est souvent la plus simple. Si vous l'adoptez, vous <strong>de</strong>vez<br />
néanmoins fournir aux utilisateurs finals une métho<strong>de</strong> <strong>de</strong> connexion au<br />
serveur <strong>de</strong> base <strong>de</strong> données (source <strong>de</strong> données ODBC, par exemple).<br />
$ Pour plus d'informations, reportez-vous à la section "Déploiement<br />
avec une installation silencieuse", page 416.<br />
♦ Développer votre propre installation Vous pouvez, pour diverses<br />
raisons, souhaiter développer votre propre programme d'installation qui<br />
intègre les fichiers d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. C'est cette solution,<br />
nettement plus complexe, qui fait l'objet essentiel <strong>de</strong> ce chapitre.<br />
Si <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est déjà installé pour le type <strong>de</strong> serveur et<br />
le système d'exploitation requis par l'architecture <strong>de</strong> l'application cliente,<br />
les fichiers requis se trouvent dans le sous-répertoire approprié du<br />
répertoire d'installation d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Par exemple, si vous avez choisi le répertoire d'installation par défaut, le<br />
sous-répertoire win32 <strong>de</strong> ce répertoire contient les fichiers requis pour<br />
exécuter le serveur sur les systèmes d'exploitaiton Windows.<br />
Par ailleurs, les utilisateurs d'InstallShield Professional 5.5 et versions<br />
supérieures peuvent utiliser SQL <strong>Anywhere</strong> Studio InstallShield<br />
Template Projects pour déployer leur propre application. Grâce à cette<br />
fonctionnalité, vous avez la possibilité <strong>de</strong> créer rapi<strong>de</strong>ment l'installation<br />
<strong>de</strong> votre application en utilisant le projet <strong>de</strong> modèles complet ou<br />
uniquement les éléments applicables à votre programme d'installation.<br />
407
Présentation du déploiement<br />
408<br />
Quelle que soit l'option choisie, veillez à ne pas violer les termes <strong>de</strong> votre<br />
contrat <strong>de</strong> licence.
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Répertoires d'installation et noms <strong>de</strong> fichiers<br />
Pour qu'une application déployée fonctionne correctement, le serveur <strong>de</strong> base<br />
<strong>de</strong> données et les bibliothèques clientes doivent pouvoir localiser les fichiers<br />
dont ils ont besoin. Les fichiers déployés doivent se trouver en relation les<br />
uns avec les autres, <strong>de</strong> la même manière que dans votre installation <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>.<br />
Dans la pratique, cela signifie que, sur un PC, la plupart <strong>de</strong>s fichiers se<br />
trouvent dans un seul répertoire. Par exemple, sous Windows, les fichiers<br />
nécessaires pour le client et le serveur <strong>de</strong> base <strong>de</strong> données sont installés dans<br />
un seul répertoire, qui est le sous-répertoire win32 du répertoire d'installation<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
$ Pour plus <strong>de</strong> précisions sur les emplacements où le logiciel recherche<br />
les fichiers, reportez-vous à la section "Recherche <strong>de</strong> fichiers dans <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>", page 222 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Remarques sur le déploiement UNIX<br />
Les déploiements sous UNIX diffèrent quelque peu <strong>de</strong>s déploiements sur<br />
PC :<br />
♦ Structure <strong>de</strong> répertoires Pour les installations UNIX, la structure <strong>de</strong><br />
répertoires est la suivante :<br />
Directory Sommaire<br />
/opt/sybase/SYBSsa8/bin Fichiers exécutables<br />
/opt/sybase/SYBSsa8/lib Objets et bibliothèques partagés<br />
/opt/sybase/SYBSsa8/res Fichiers chaîne<br />
Sous AIX, le répertoire racine par défaut est /usr/lpp/sybase/SYBSsa8 et<br />
non /opt/sybase/SYBSsa8.<br />
♦ Extensions <strong>de</strong> fichiers Dans les tableaux <strong>de</strong> ce chapitre, les objets<br />
partagés sont répertoriés avec l'extension .so. Pour HP-UX, l'extension<br />
est .sl.<br />
Sous le système d'exploitation AIX, les objets partagés auxquels les<br />
applications doivent être liées sont dotés <strong>de</strong> l'extension .a.<br />
♦ Liens symboliques Chaque objet partagé est installé comme lien<br />
symbolique à un fichier portant le même nom avec l'extension<br />
complémentaire .1 (un). Par exemple, libdblib8.so est un lien symbolique<br />
au fichier libdblib8.so.1 dans le même répertoire.<br />
409
Répertoires d'installation et noms <strong>de</strong> fichiers<br />
410<br />
Si l’installation d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> requiert <strong>de</strong>s patchs, ceux-ci<br />
sont fournis avec l’extension .2, et le lien symbolique doit être acheminé<br />
à nouveau.<br />
♦ Applications utilisant ou non les threads natifs La plupart <strong>de</strong>s objets<br />
partagés sont fournis sous <strong>de</strong>ux formes, l'une ayant les caractères _r<br />
précédant l'extension <strong>de</strong> fichier. Par exemple, outre libdblib8.so, il existe<br />
un fichier appelé libdblib8_r.so. Dans ce cas, les applications utilisant les<br />
threads natifs doivent être liées à l'objet partagé dont le nom<br />
comporte _r, tandis que les applications ne les utilisant pas doivent être<br />
liées à l'objet partagé dont le nom ne comporte pas _r.<br />
♦ Conversion <strong>de</strong>s jeux <strong>de</strong> caractère Vous <strong>de</strong>vez intégrer les fichiers<br />
suivants si vous souhaitez utiliser la conversion <strong>de</strong>s jeux <strong>de</strong> caractère <strong>de</strong><br />
serveur <strong>de</strong> base <strong>de</strong> données (l'option <strong>de</strong> serveur -ct):<br />
♦ libunic.so<br />
♦ charsets/ sous-arborescence du répertoire<br />
♦ asa.cvf<br />
$ Pour plus <strong>de</strong> précisions sur les emplacements où le logiciel recherche<br />
les fichiers, reportez-vous à la section "Recherche <strong>de</strong> fichiers dans <strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong>", page 222 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Conventions <strong>de</strong> dénomination <strong>de</strong>s fichiers<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> adopte un système <strong>de</strong> dénomination cohérent <strong>de</strong><br />
façon à faciliter l'i<strong>de</strong>ntification et le regroupement <strong>de</strong>s composants du<br />
système.<br />
Ces conventions sont les suivantes :<br />
♦ Numéro <strong>de</strong> version Le numéro <strong>de</strong> version d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
est indiqué dans le nom <strong>de</strong> fichier <strong>de</strong>s composants du serveur principal<br />
(fichiers .exe et .dll).<br />
Par exemple, le fichier dbeng8.exe est un fichier exécutable <strong>de</strong> la<br />
version 8.<br />
♦ Langue La langue utilisée dans une bibliothèque <strong>de</strong> ressources <strong>de</strong><br />
langue est indiquée par un co<strong>de</strong> <strong>de</strong> <strong>de</strong>ux lettres dans son nom <strong>de</strong> fichier.<br />
La langue <strong>de</strong> cette bibliothèque est indiquée par les <strong>de</strong>ux caractères<br />
précédant le numéro <strong>de</strong> version. Par exemple, dblgen8.dll est la<br />
bibliothèque <strong>de</strong> ressources <strong>de</strong> langue pour l'anglais. Ces co<strong>de</strong>s sont<br />
spécifiés par la norme ISO 639.
I<strong>de</strong>ntification<br />
d’autres types <strong>de</strong><br />
fichiers<br />
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
$ Pour plus d'informations sur les libellés <strong>de</strong> langue, reportez-vous à<br />
la section "La langue <strong>de</strong> localisation", page 280 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
Vous pouvez transférer gratuitement <strong>de</strong>puis le site Web <strong>de</strong> <strong>Sybase</strong> un kit<br />
international <strong>de</strong> déploiement <strong>de</strong> ressources contenant <strong>de</strong>s DLL <strong>de</strong><br />
déploiement <strong>de</strong> ressources <strong>de</strong> langue.<br />
v Pour transférer le kit international <strong>de</strong> déploiement <strong>de</strong> ressources<br />
<strong>de</strong>puis le site Web <strong>de</strong> <strong>Sybase</strong> :<br />
1 Connectez-vous à l'URL suivante à partir <strong>de</strong> votre navigateur :<br />
http://www.sybase.com/products/anywhere/<br />
2 Cliquez sur Downloads, situé sous l'en-tête SQL <strong>Anywhere</strong> Studio sur la<br />
gauche <strong>de</strong> la page.<br />
3 Cliquez sur An assortment of Emergency Bug Fixes and Updates for<br />
SQL <strong>Anywhere</strong> Studio, sous l'en-tête Emergency Bug Fix/Updates.<br />
4 Connectez-vous à votre compte Web <strong>Sybase</strong>.<br />
Si vous ne disposez pas encore d'un compte Web <strong>Sybase</strong>, cliquez sur<br />
Create a New Account pour en créer un.<br />
5 Dans la liste <strong>de</strong>s éléments disponibles, sélectionnez le kit international<br />
<strong>de</strong> déploiement <strong>de</strong> ressources (International Resources Deployment Kit)<br />
correspondant à la plate-forme et à la version d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> que vous utilisez.<br />
$ Pour obtenir la liste <strong>de</strong>s langues disponibles dans <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>, reportez-vous à la section "Classements fournis", page 286 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
Le tableau suivant indique la plate-forme et la fonction <strong>de</strong>s fichiers<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> selon leur extension <strong>de</strong> fichier. <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> respecte, chaque fois que possible, les conventions d'extension <strong>de</strong><br />
fichier standard.<br />
411
Répertoires d'installation et noms <strong>de</strong> fichiers<br />
Nom <strong>de</strong>s fichiers<br />
<strong>de</strong> base <strong>de</strong><br />
données<br />
412<br />
Extension <strong>de</strong><br />
fichier<br />
Plate-forme Type <strong>de</strong> fichier<br />
.nlm Novell NetWare Module chargeable<br />
NetWare<br />
.cnt, .ftg, .fts,<br />
.gid, .hlp, .chm,<br />
.chw<br />
Windows Fichier d'ai<strong>de</strong> système<br />
.lib Dépend <strong>de</strong> l'outil <strong>de</strong><br />
développement<br />
.cfg, .cpr, .dat,<br />
.loc, .spr, .srt,<br />
.xlt<br />
Bibliothèques d'exécution<br />
statiques pour la création<br />
d'exécutables<br />
Embed<strong>de</strong>d SQL<br />
Windows Composants <strong>de</strong> <strong>Sybase</strong><br />
<strong>Adaptive</strong> <strong>Server</strong> Enterprise<br />
.cmd .bat Windows Fichiers <strong>de</strong> comman<strong>de</strong>s<br />
.res NetWare, UNIX Fichier <strong>de</strong> ressources <strong>de</strong><br />
langue pour les<br />
environnements non-<br />
Windows<br />
.dll Windows Bibliothèque DLL<br />
(Dynamic Link Library)<br />
.so .sl .a UNIX Fichier d'objet partagé (Sun<br />
Solaris et IBM AIX) ou <strong>de</strong><br />
bibliothèque partagée (HP-<br />
UX). Equivalent d'un DLL<br />
sur les plates-formes PC.<br />
Les bases <strong>de</strong> données d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> sont constituées <strong>de</strong> <strong>de</strong>ux<br />
éléments :<br />
♦ Fichier <strong>de</strong> base <strong>de</strong> données Ce fichier contient les informations dans<br />
un format structuré. Il est doté d'une extension .db.<br />
♦ Fichier du journal <strong>de</strong> transactions Ce fichier enregistre toutes les<br />
modifications <strong>de</strong>s données contenues dans le fichier <strong>de</strong> base <strong>de</strong> données.<br />
Il est doté <strong>de</strong> l'extension .log et généré par <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> si<br />
un tel fichier n'existe pas et qu'un fichier journal doit être utilisé. Un<br />
journal <strong>de</strong> transactions en miroir est suivi <strong>de</strong> l'extension par défaut .mlg.<br />
♦ Fichier d'écriture Si votre application en utilise un, il est généralement<br />
doté <strong>de</strong> l'extension .wrt.<br />
♦ Fichier <strong>de</strong> base <strong>de</strong> données compacté Si vous fournissez un fichier <strong>de</strong><br />
base <strong>de</strong> données compacté, il porte généralement l'extension .cdb.
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Ces fichiers sont mis à jour, maintenus et gérés par le système <strong>de</strong> gestion <strong>de</strong><br />
bases <strong>de</strong> données relationnel (SGBDR) <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
413
Utilisation <strong>de</strong>s objets et modèles InstallShield pour le déploiement<br />
Utilisation <strong>de</strong>s objets et modèles InstallShield<br />
pour le déploiement<br />
414<br />
Si vous utilisez InstallShield 6 ou une version supérieure, vous pouvez<br />
inclure <strong>de</strong>s objets InstallShield <strong>de</strong> SQL <strong>Anywhere</strong> Studio dans votre<br />
programme d'installation. Les objets permettant <strong>de</strong> déployer <strong>de</strong>s clients, <strong>de</strong>s<br />
serveurs <strong>de</strong> base <strong>de</strong> données personnels, <strong>de</strong>s serveurs <strong>de</strong> réseau et <strong>de</strong>s outils<br />
d'administration se trouvent dans le sous-répertoire <strong>de</strong>ployment\Object du<br />
répertoire SQL <strong>Anywhere</strong>.<br />
Les utilisateurs d'InstallShield Professional version 5.5 et ultérieures peuvent<br />
utiliser les projets modèles InstallShield <strong>de</strong> SQL <strong>Anywhere</strong> Studio pour<br />
faciliter le déploiement. Vous trouverez <strong>de</strong>s modèles pour le déploiement<br />
d'un serveur réseau, d'un serveur personnel, d'interfaces clientes et d'outils<br />
d'administration dans le sous-répertoire SQL <strong>Anywhere</strong><br />
8\<strong>de</strong>ployment\Templates.<br />
Si vous disposez <strong>de</strong> la version 6 ou d'une version ultérieure d'InstallShield, il<br />
est conseillé d'en utiliser les objets plutôt que les modèles, car ils s'intègrent<br />
plus facilement aux autres composants d'une installation.<br />
v Pour ajouter un projet <strong>de</strong> modèle dans votre InstallShield IDE :<br />
1 Démarrez InstallShield IDE.<br />
2 Choisissez Fichier➤Ouvrir.<br />
3 Accé<strong>de</strong>z à votre installation SQL <strong>Anywhere</strong> 8 et au dossier <strong>de</strong><br />
déploiement.<br />
Par exemple :<br />
C:\Program Files\<strong>Sybase</strong>\SQL <strong>Anywhere</strong> 8\<strong>de</strong>ployment<br />
4 Ouvrez le dossier <strong>de</strong> modèles correspondant au type d'objet à déployer.<br />
Vous avez le choix entre Network<strong>Server</strong>, Personal<strong>Server</strong>, Client et<br />
JavaTools.<br />
5 Sélectionnez le fichier ayant l'extension .ipr.<br />
Le projet s'ouvre dans InstallShield IDE. Le volet Projects affiche une<br />
icône pour le modèle.<br />
Les modèles seront modifiés au moment <strong>de</strong> l'installation <strong>de</strong> sorte que les<br />
chemins d'accès aux différents fichiers répertoriés dans les fichiers .fgl<br />
pointent sur le programme d'installation courant d'ASA. Il suffit <strong>de</strong><br />
charger le modèle dans InstallShield IDE, <strong>de</strong> créer le support et le<br />
modèle s'exécute immédiatement.
Remarques :<br />
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Lors <strong>de</strong> la création du support, <strong>de</strong>s avertissements sur <strong>de</strong>s groupes <strong>de</strong><br />
fichiers vi<strong>de</strong>s s'affichent. Ces groupes ont été ajoutés dans les modèles<br />
comme marques <strong>de</strong> réservation pour les fichiers <strong>de</strong> votre application.<br />
Pour supprimer ces avertissements, ajoutez les fichiers <strong>de</strong> votre<br />
application dans les groupes <strong>de</strong> fichiers, ou bien supprimez ou<br />
renommez ces groupes.<br />
415
Déploiement avec une installation silencieuse<br />
Déploiement avec une installation silencieuse<br />
416<br />
Les installations silencieuses ne nécessitent aucun intervention <strong>de</strong> l'utilisateur<br />
et pendant qu'elles se déroulent, aucune indication n'est fournie à l'utilisateur.<br />
Sous les systèmes d'exploitation Windows, vous pouvez appeler le<br />
programme InstallShield d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> à partir <strong>de</strong> votre<br />
programme Setup afin que l'installation d'<strong>Anywhere</strong> se déroule en mo<strong>de</strong><br />
silencieux. Ce type d'installation est également possible avec SMS (Systems<br />
Management <strong>Server</strong>) <strong>de</strong> Microsoft (voir "Installation SMS", page 418).<br />
Vous pouvez utiliser le mo<strong>de</strong> d'installation silencieuse pour tous les modèles<br />
<strong>de</strong> déploiement décrits dans la section "Modèles <strong>de</strong> déploiement", page 406.<br />
Vous pouvez également vous en servir pour déployer <strong>de</strong>s serveurs <strong>de</strong><br />
synchronisation MobiLink.<br />
Création d'un programme d'installation silencieuse<br />
Les options d'installation utilisées en mo<strong>de</strong> silencieux sont fournies par un<br />
fichier <strong>de</strong> réponse. Ce fichier est créé lors <strong>de</strong> l'exécution du programme<br />
setup d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> avec l'option <strong>de</strong> comman<strong>de</strong> –r. Vous<br />
effectuez un programme d'installation silencieuse en exécutant setup avec<br />
l'option <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> –s.<br />
N’utilisez pas le bouton Parcourir<br />
Lors <strong>de</strong> la création d'un programme d'installation silencieuse, n'utilisez<br />
pas le bouton Parcourir. En effet, l'enregistrement <strong>de</strong> ce bouton n'est pas<br />
fiable.<br />
v Pour créer un programme d'installation silencieuse :<br />
1 Supprimez les installations existantes d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong><br />
(facultatif).<br />
2 Ouvrez une fenêtre <strong>de</strong> comman<strong>de</strong>s système et accé<strong>de</strong>z au répertoire<br />
contenant l'image d'installation (comprenant setup.exe, setup.ins, etc.).<br />
3 Installez le logiciel en mo<strong>de</strong> Record.<br />
Entrez la comman<strong>de</strong> suivante :<br />
setup –s
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Cette comman<strong>de</strong> exécute le programme d'installation d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> et crée le fichier <strong>de</strong> réponses à partir <strong>de</strong>s sélections<br />
effectuées. Le fichier <strong>de</strong> réponses s'appelle setup.iss et il se trouve dans<br />
votre répertoire Windows. Ce fichier contient les réponses que vous avez<br />
fournies dans les boîtes <strong>de</strong> dialogue lors <strong>de</strong> l'installation.<br />
En mo<strong>de</strong> Enregistrement (record), le programme d'installation ne vous<br />
invite pas à redémarrer le système, même si l'opération est nécessaire.<br />
4 Installez <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> avec les options et les paramètres à<br />
utiliser pour le déploiement d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> sur la machine<br />
<strong>de</strong> l'utilisateur final, qui exécutera votre application. Vous pouvez<br />
modifier les chemins durant l'installation silencieuse.<br />
Exécution d'une installation silencieuse<br />
Votre programme d’installation doit appeler celui d’installation silencieuse<br />
d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> au moyen <strong>de</strong> l’option <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> –<br />
s. Cette section décrit comment utiliser un programme d'installation<br />
silencieuse.<br />
v Pour utiliser un programme d’installation silencieuse :<br />
1 Ajoutez la comman<strong>de</strong> <strong>de</strong>stinée à appeler le programme d'installation<br />
silencieuse d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> pour votre procédure.<br />
Si le fichier <strong>de</strong> réponses se trouve dans le répertoire image du<br />
programme d'installation, vous pouvez exécuter celui-ci en tapant la<br />
comman<strong>de</strong> ci-après dans le répertoire où se trouve l'image :<br />
setup –s<br />
Si le fichier <strong>de</strong> réponses se trouve ailleurs, spécifiez l'emplacement<br />
adéquat avec l'option –f1. L’option f1 et les guillemets ne doivent être<br />
séparés par aucun espace sur la ligne <strong>de</strong> comman<strong>de</strong>.<br />
setup –s –f1"c:\winnt\setup.iss"<br />
Pour appeler le programme d'installation à partir d'un autre script<br />
InstallShield, vous pouvez aussi entrer la comman<strong>de</strong> ci-après :<br />
DoInstall( "chemin_image_install_ASA\SETUP.INS",<br />
"-s", WAIT );<br />
Des options <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong> permettent <strong>de</strong> remplacer les chemins<br />
tant pour le répertoire d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> que pour le<br />
répertoire partagé.<br />
setup TARGET_DIR=dirname SHARED_DIR=shared_dir –s<br />
417
Déploiement avec une installation silencieuse<br />
Installation SMS<br />
418<br />
Les arguments TARGET_DIR et SHARED_DIR doivent précé<strong>de</strong>r les<br />
autres options.<br />
2 Vérifiez si l'ordinateur <strong>de</strong>stinataire doit être redémarré ou non.<br />
Le programme d'installation crée un fichier nommé silent.log dans le<br />
répertoire cible. Il contient une section appelée ResponseResult, qui<br />
inclut la ligne suivante :<br />
Reboot=valeur<br />
Cette ligne indique si l'ordinateur <strong>de</strong>stinataire doit être redémarré pour<br />
que l'installation soit terminée ; elle prend la valeur 0 ou 1, selon le cas.<br />
♦ Reboot=0 Redémarrage inutile<br />
♦ Reboot=1 L'indicateur BATCH_INSTALL a été défini durant<br />
l'installation et l'ordinateur <strong>de</strong>stinataire doit être redémarré. La<br />
procédure qui a appelé le programme d'installation silencieux doit<br />
vérifier l'entrée Reboot et redémarrer, si nécessaire, l'ordinateur<br />
<strong>de</strong>stinataire.<br />
3 Vérifiez que l'exécution du programme Setup s'est correctement<br />
déroulée.<br />
Setup crée un fichier nommé setup.log dans le répertoire contenant le<br />
fichier <strong>de</strong> réponses. Le journal <strong>de</strong> transactions inclut un rapport sur le<br />
programme d'installation silencieuse. La <strong>de</strong>rnière section <strong>de</strong> ce fichier,<br />
intitulée ResponseResult, comporte la ligne suivante :<br />
ResultCo<strong>de</strong>=valeur<br />
Cette ligne indique si l'installation s'est correctement terminée. Si la<br />
valeur <strong>de</strong> ResultCo<strong>de</strong> est différente <strong>de</strong> zéro, cela signifie qu'une erreur<br />
s'est produite. Pour obtenir une <strong>de</strong>scription <strong>de</strong>s co<strong>de</strong>s d'erreur, reportezvous<br />
à la documentation <strong>de</strong> votre InstallShield.<br />
SMS (System Management <strong>Server</strong>) <strong>de</strong> Microsoft utilise un programme<br />
d'installation silencieuse qui ne redémarre pas l'ordinateur cible. Celui<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> ne redémarre pas l'ordinateur.<br />
Votre package SMS doit contenir le fichier <strong>de</strong> réponses, l'image du<br />
programme d'installation et le fichier <strong>de</strong> définition du package asa8.pdf (qui<br />
se trouve sur le CD-ROM d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, dans le répertoire<br />
\extras). La comman<strong>de</strong> du Setup dans le fichier PDF contient les options<br />
suivantes :
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
♦ Option –s pour une installation silencieuse<br />
♦ Option –SMS pour indiquer l’utilisation <strong>de</strong> SMS<br />
♦ Option –m pour générer un fichier MIF. Le fichier MIF est utilisé par<br />
SMS pour déterminer si l'installation a réussi.<br />
419
Déploiement <strong>de</strong>s applications clientes<br />
Déploiement <strong>de</strong>s applications clientes<br />
420<br />
Pour déployer une application cliente exécutée sur un serveur <strong>de</strong> base <strong>de</strong><br />
données réseau, vous <strong>de</strong>vez fournir à chaque utilisateur final :<br />
♦ Application cliente Le logiciel <strong>de</strong> l'application est indépendant du<br />
logiciel <strong>de</strong> base <strong>de</strong> données, aussi nous ne le décrirons pas.<br />
♦ Fichiers <strong>de</strong> l'interface <strong>de</strong> base <strong>de</strong> données L’application cliente doit<br />
disposer <strong>de</strong>s fichiers requis par l'interface <strong>de</strong> base <strong>de</strong> données qu'elle<br />
utilise (ODBC, JDBC, Embed<strong>de</strong>d SQL ou Open Client).<br />
♦ Informations <strong>de</strong> connexion Chaque application cliente doit disposer<br />
<strong>de</strong>s informations <strong>de</strong> connexion à la base <strong>de</strong> données.<br />
Les fichiers d'interface et les informations <strong>de</strong> connexion requis dépen<strong>de</strong>nt <strong>de</strong><br />
l'interface utilisée par l'application. Les sections qui suivent traitent <strong>de</strong>s<br />
différentes interfaces.<br />
Le moyen le plus simple pour déployer <strong>de</strong>s applications clientes consiste à<br />
utiliser les objets InstallShield fournis. Pour plus d'informations, reportezvous<br />
à la section "Utilisation <strong>de</strong>s objets et modèles InstallShield pour le<br />
déploiement", page 414.<br />
Déploiement <strong>de</strong> clients OLE DB et ADO<br />
Le moyen le plus simple pour déployer <strong>de</strong>s bibliothèques clientes OLE DB<br />
consiste à utiliser les objets ou modèles InstallShield. Pour plus<br />
d'informations, reportez-vous à la section "Utilisation <strong>de</strong>s objets et modèles<br />
InstallShield pour le déploiement", page 414. Si vous voulez créer votre<br />
propre installation, cette section décrit les fichiers à déployer pour les<br />
utilisateurs finaux.<br />
Chaque machine cliente OLE DB doit disposer <strong>de</strong>s éléments suivants :<br />
♦ Une installation OLE DB en état <strong>de</strong> marche Les fichiers et instructions<br />
OLE DB sont disponibles pour redistribution, auprès <strong>de</strong> Microsoft<br />
Corporation. Ils ne sont pas décrits en détail ici.<br />
♦ Le fournisseur OLE DB d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> Le tableau<br />
suivant répertorie les fichiers nécessaires au fonctionnement d'un<br />
fournisseur OLE DB pour <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>. Ces fichiers<br />
doivent être placés dans un seul répertoire. L'installation d'<strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong> les place tous dans le sous-répertoire du système<br />
d'exploitation du répertoire d'installation SQL <strong>Anywhere</strong> ; par exemple :<br />
win32.
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Description Windows Windows CE<br />
Pilote OLE DB dboledb8.dll dboledb8.dll<br />
Pilote OLE DB dboledba8.dll dboledba8.dll<br />
Bibliothèque <strong>de</strong> ressources dblgen8.dll dblgen8.dll<br />
<strong>de</strong> langue<br />
Boîte <strong>de</strong> dialogue<br />
Connexion<br />
Déploiement <strong>de</strong> clients ODBC<br />
dbcon8.dll sans objet<br />
Les fournisseurs OLE DB nécessitent <strong>de</strong> nombreuses entrées dans le<br />
registre. Vous pouvez créer ces entrées en auto-enregistrant les DLL au<br />
moyen soit <strong>de</strong> l'utilitaire regsvr32 sous Windows, soit <strong>de</strong> l'utilitaire<br />
regsvrce sous Windows CE.<br />
$ Pour plus d'informations, reportez-vous aux sections "Création <strong>de</strong><br />
bases <strong>de</strong> données pour Windows CE", page 291 du document ASA<br />
<strong>Gui<strong>de</strong></strong> d’administration et "Liaison d'applications ODBC sous<br />
Windows CE", page 279.<br />
Le moyen le plus simple pour déployer <strong>de</strong>s clients ODBC consiste à utiliser<br />
les objets ou modèles InstallShield. Pour plus d'informations, reportez-vous à<br />
la section "Utilisation <strong>de</strong>s objets et modèles InstallShield pour le<br />
déploiement", page 414.<br />
Chaque machine cliente ODBC doit disposer <strong>de</strong> :<br />
♦ Une installation ODBC en état <strong>de</strong> marche Les fichiers et instructions<br />
ODBC sont disponibles pour redistribution auprès <strong>de</strong> Microsoft<br />
Corporation. Ils ne sont pas décrits en détail ici.<br />
Microsoft fournit le gestionnaire <strong>de</strong> pilote ODBC pour les systèmes<br />
d'exploitation Windows. SQL <strong>Anywhere</strong> Studio comprend un<br />
gestionnaire <strong>de</strong> pilote ODBC pour UNIX. Il n'existe aucun gestionnaire<br />
<strong>de</strong> pilote ODBC pour Windows CE.<br />
Les applications ODBC peuvent s'exécuter sans gestionnaire <strong>de</strong> pilote.<br />
Sur les plates-formes pour lesquelles il existe un gestionnaire <strong>de</strong> pilote<br />
ODBC, l'utilisation <strong>de</strong> ce <strong>de</strong>rnier est déconseillée.<br />
421
Déploiement <strong>de</strong>s applications clientes<br />
Fichiers requis par le pilote ODBC<br />
Remarques<br />
422<br />
Si nécessaire, mettez ODBC à jour<br />
Le programme Setup <strong>de</strong> SQL <strong>Anywhere</strong> met à jour les anciennes<br />
installations <strong>de</strong>s composants d'accès aux données Microsoft<br />
(MDAC), notamment ODBC. Si vous déployez votre propre<br />
application, vous <strong>de</strong>vez vous assurer que l'installation ODBC est<br />
suffisante.<br />
♦ Le pilote ODBC d’<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> Il s'agit du fichier<br />
dbodbc8.dll associé à quelques autres fichiers.<br />
$ Pour plus d'informations, reportez-vous à la section "Fichiers<br />
requis par le pilote ODBC", page 422.<br />
♦ Les informations <strong>de</strong> connexion Les informations <strong>de</strong> connexion.<br />
L'application cliente doit avoir accès aux informations requises pour se<br />
connecter au serveur. Ces informations se trouvent généralement dans<br />
une source <strong>de</strong> données ODBC.<br />
Le tableau suivant indique les fichiers requis par un pilote ODBC d'<strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong> en cours d'exploitation. Ces fichiers doivent être placés<br />
dans un seul répertoire. L'installation d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> les place<br />
tous dans le sous-répertoire du système d'exploitation du répertoire<br />
d'installation SQL <strong>Anywhere</strong> ; par exemple : win32.<br />
Description Windows Windows CE UNIX<br />
Pilote ODBC dbodbc8.dll dbodbc8.dll libdbodbc8.so<br />
libdbtasks8.so<br />
Bibliothèque <strong>de</strong><br />
ressources <strong>de</strong> langue<br />
dblgen8.dll dblgen8.dll dblgen8.res<br />
Boîte <strong>de</strong> dialogue<br />
Connexion<br />
dbcon8.dll sans objet sans objet<br />
♦ L'utilisateur final doit disposer d'une installation ODBC en état <strong>de</strong><br />
marche, avec un gestionnaire <strong>de</strong> pilote. Les instructions <strong>de</strong> déploiement<br />
d'ODBC se trouvent dans Microsoft ODBC SDK.<br />
♦ La boîte <strong>de</strong> dialogue Connexion est requise si les utilisateurs finaux<br />
prévoient <strong>de</strong> créer leurs propres sources <strong>de</strong> données, s'ils doivent entrer<br />
<strong>de</strong>s ID utilisateur et <strong>de</strong>s mots <strong>de</strong> passe au moment <strong>de</strong> la connexion à la<br />
base <strong>de</strong> données ou s'ils souhaitent afficher la boîte <strong>de</strong> dialogue<br />
Connexion pour toute autre raison.
Configuration du pilote ODBC<br />
Windows<br />
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
♦ Le traducteur ODBC n’est requis que si votre application repose sur la<br />
conversion <strong>de</strong> jeu <strong>de</strong> caractères OEM vers ANSI.<br />
$ Pour plus d'informations, reportez-vous aux sections "Création <strong>de</strong><br />
bases <strong>de</strong> données pour Windows CE", page 291 du document ASA<br />
<strong>Gui<strong>de</strong></strong> d’administration et "Liaison d'applications ODBC sous<br />
Windows CE", page 279.<br />
♦ Pour les applications multithread sous UNIX, utilisez libdbodbc8_r.so et<br />
libdbtasks8_r.so.<br />
Le programme <strong>de</strong> configuration doit, outre copier les fichiers du pilote<br />
ODBC sur le disque, créer un jeu d'entrées <strong>de</strong> registre pour installer<br />
correctement le pilote ODBC.<br />
Le programme Setup d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> modifie la base <strong>de</strong><br />
registre pour i<strong>de</strong>ntifier et configurer le pilote ODBC. Si vous élaborez un<br />
programme <strong>de</strong> configuration pour les utilisateurs finals, veillez à effectuer les<br />
mêmes paramétrages.<br />
Vous disposez <strong>de</strong> l'utilitaire regedit pour examiner les entrées <strong>de</strong> registre.<br />
Le pilote ODBC d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> est i<strong>de</strong>ntifié par le système au<br />
moyen d'un ensemble <strong>de</strong> valeurs <strong>de</strong> registre dans la clé <strong>de</strong> registre suivante :<br />
HKEY_LOCAL_MACHINE\<br />
SOFTWARE\<br />
ODBC\<br />
ODBCINST.INI\<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> 8.0<br />
Les valeurs sont les suivantes :<br />
Nom <strong>de</strong> la valeur Type <strong>de</strong> valeur Données <strong>de</strong> la<br />
valeur<br />
Driver Chaîne chemin\dbodbc8.dll<br />
Setup Chaîne chemin\dbodbc8.dll<br />
Il existe également une valeur <strong>de</strong> registre dans la clé :<br />
HKEY_LOCAL_MACHINE\<br />
SOFTWARE\<br />
ODBC\<br />
ODBCINST.INI\<br />
ODBC Drivers<br />
La valeur se présente comme suit :<br />
423
Déploiement <strong>de</strong>s applications clientes<br />
Pilotes ODBC <strong>de</strong><br />
fournisseurs tiers<br />
424<br />
Nom <strong>de</strong> la valeur Type <strong>de</strong> valeur Données <strong>de</strong> la<br />
valeur<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> 8.0 Chaîne Installed<br />
Si vous utilisez un pilote ODBC d'un fournisseur tiers sur un système<br />
d'exploitation autre que Windows, consultez la documentation <strong>de</strong> ce pilote<br />
pour le configurer.<br />
Déploiement <strong>de</strong>s informations <strong>de</strong> connexion<br />
Types <strong>de</strong> source<br />
<strong>de</strong> données<br />
Les informations <strong>de</strong> connexion client ODBC sont généralement déployées<br />
comme une source <strong>de</strong> données ODBC. Pour déployer une source <strong>de</strong> données<br />
ODBC, vous avez le choix :<br />
♦ Par programme Ajoutez une <strong>de</strong>scription <strong>de</strong> source données dans les<br />
fichiers <strong>de</strong> registre ou d'initialisation ODBC pour l'utilisateur final.<br />
♦ Manuellement Fournissez <strong>de</strong>s instructions aux utilisateurs finals, <strong>de</strong><br />
sorte qu'ils puissent créer une source <strong>de</strong> données adéquate sur leur<br />
machine propre.<br />
Pour créer manuellement une source <strong>de</strong> données, faites appel à<br />
l'Administrateur <strong>de</strong> source <strong>de</strong> données ODBC, à partir <strong>de</strong> l'onglet DSN<br />
utilisateur ou <strong>de</strong> l'onglet DSN système. Le pilote ODBC d'<strong>Adaptive</strong><br />
<strong>Server</strong> <strong>Anywhere</strong> affiche la boîte <strong>de</strong> dialogue <strong>de</strong> configuration pour<br />
définir les paramètres. Les paramètres <strong>de</strong> la source <strong>de</strong> données<br />
comprennent l'emplacement du fichier <strong>de</strong> base <strong>de</strong> données, le nom du<br />
serveur <strong>de</strong> base <strong>de</strong> données, ainsi que les éventuels paramètres <strong>de</strong><br />
démarrage et d'autres options.<br />
Cette section vous donne les informations nécessaires pour l'une et l'autre<br />
métho<strong>de</strong>.<br />
Il existe trois types <strong>de</strong> sources <strong>de</strong> données : sources <strong>de</strong> données utilisateur,<br />
sources <strong>de</strong> données système et source <strong>de</strong> données fichier.<br />
Les définitions <strong>de</strong>s sources <strong>de</strong> données utilisateur sont enregistrées dans la<br />
partie du registre contenant les paramètres spécifiques <strong>de</strong> l'utilisateur<br />
actuellement connecté au système. Les sources <strong>de</strong> données système,<br />
toutefois, sont accessibles à tous les utilisateurs et aux services Windows, qui<br />
sont exécutés qu'un utilisateur soit ou non connecté au système. Soit, par<br />
exemple, une source <strong>de</strong> données système correctement configurée, appelée<br />
MonApp : tout utilisateur peut utiliser cette connexion ODBC, s'il indique<br />
DSN=MonApp dans la chaîne <strong>de</strong> connexion ODBC.
Entrées <strong>de</strong> registre<br />
<strong>de</strong> source <strong>de</strong><br />
données<br />
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Les sources <strong>de</strong> données fichier ne se trouvent pas dans le registre, mais dans<br />
un répertoire particulier. Une chaîne <strong>de</strong> connexion doit fournir un paramètre<br />
<strong>de</strong> connexion FileDSN pour utiliser une source <strong>de</strong> données fichier.<br />
Le système i<strong>de</strong>ntifie chaque source <strong>de</strong> données utilisateur par <strong>de</strong>s entrées <strong>de</strong><br />
registre.<br />
Vous <strong>de</strong>vez créer un ensemble <strong>de</strong> valeurs <strong>de</strong> registre dans une clé <strong>de</strong> registre<br />
particulière. Pour les sources <strong>de</strong> données utilisateur, la clé est la suivante :<br />
HKEY_CURRENT_USER\<br />
SOFTWARE\<br />
ODBC\<br />
ODBC.INI\<br />
nom_source_données_utilisateur<br />
Pour les sources <strong>de</strong> données système, la clé est la suivante :<br />
HKEY_LOCAL_MACHINE\<br />
SOFTWARE\<br />
ODBC\<br />
ODBC.INI\<br />
nom_source_données_système<br />
La clé contient un ensemble <strong>de</strong> valeurs <strong>de</strong> registre, chacune correspondant à<br />
un paramètre <strong>de</strong> connexion. Par exemple, la clé ASA 8.0 Sample<br />
correspondant à la source <strong>de</strong> données ASA 8.0 Sample contient les<br />
paramètres :<br />
Nom <strong>de</strong> la<br />
valeur<br />
Type <strong>de</strong><br />
valeur<br />
Autostop Chaîne Yes<br />
Données <strong>de</strong> la valeur<br />
DatabaseFile Chaîne Chemin\asa<strong>de</strong>mo.db<br />
Description Chaîne Exemple <strong>de</strong> base <strong>de</strong> données <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong><br />
Driver Chaîne Chemin\win32\dbodbc8.dll<br />
PWD Chaîne sql<br />
Start Chaîne Chemin\win32\dbeng8.exe -c 8m<br />
UID Chaîne dba<br />
Dans ces entrées, chemin est le répertoire d'installation d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>.<br />
Vous <strong>de</strong>vez en outre ajouter la source <strong>de</strong> données à la liste <strong>de</strong>s sources <strong>de</strong><br />
données dans le registre. Pour les sources <strong>de</strong> données utilisateur, utilisez la<br />
clé :<br />
HKEY_CURRENT_USER\<br />
425
Déploiement <strong>de</strong>s applications clientes<br />
Paramètres <strong>de</strong><br />
connexion<br />
obligatoires et<br />
facultatifs<br />
426<br />
SOFTWARE\<br />
ODBC\<br />
ODBC.INI\<br />
ODBC Data Sources<br />
Pour les sources <strong>de</strong> données système, utilisez la clé :<br />
HKEY_LOCAL_MACHINE\<br />
SOFTWARE\<br />
ODBC\<br />
ODBC.INI\<br />
ODBC Data Sources.<br />
La valeur associe chaque source <strong>de</strong> données à un pilote ODBC. Le nom <strong>de</strong> la<br />
valeur est celui <strong>de</strong> la source <strong>de</strong> données et les données <strong>de</strong> la valeur sont le<br />
nom du pilote ODBC. Par exemple, la source <strong>de</strong> données utilisateur installée<br />
par <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> s'appelle ASA 8.0 Sample et a la valeur<br />
suivante :<br />
Nom <strong>de</strong> la valeur Type <strong>de</strong><br />
valeur<br />
Données <strong>de</strong> la valeur<br />
ASA 8.0 Sample Chaîne <strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> 8.0<br />
Avertissement : Les paramètres ODBC sont facilement visibles<br />
Les configurations <strong>de</strong> source <strong>de</strong> données utilisateur peuvent contenir <strong>de</strong>s<br />
paramètres <strong>de</strong> base <strong>de</strong> données sensibles, tels qu'ID utilisateur et mot <strong>de</strong><br />
passe. Ces paramètres sont enregistrés en clair dans le registre et peuvent<br />
être affichés par le biais <strong>de</strong>s éditeurs <strong>de</strong> registre Windows regedit.exe ou<br />
regedt32.exe, fournis par Microsoft avec le système d'exploitation. Vous<br />
pouvez déci<strong>de</strong>r <strong>de</strong> chiffrer les mots <strong>de</strong> passe, ou d'obliger les utilisateurs à<br />
les fournir lorsqu'ils se connectent.<br />
Vous pouvez i<strong>de</strong>ntifier le nom <strong>de</strong> la source <strong>de</strong> données dans une chaîne <strong>de</strong><br />
configuration ODBC :<br />
DSN=nom_source_données_utilisateur<br />
Lorsqu'un paramètre DSN est fourni dans la chaîne <strong>de</strong> connexion, les<br />
définitions <strong>de</strong> la source <strong>de</strong>s données utilisateur courante sont recherchées<br />
dans le registre ; la source <strong>de</strong>s données système est ensuite recherchée. Les<br />
sources <strong>de</strong>s données fichier ne sont recherchées que lorsque FileDSN est<br />
fourni dans la chaîne <strong>de</strong> connexion ODBC.<br />
Le tableau suivant illustre les conséquences, pour l'utilisateur et le<br />
développeur, <strong>de</strong> l'existence d'une source <strong>de</strong> données et <strong>de</strong> son insertion dans<br />
la chaîne <strong>de</strong> connexion <strong>de</strong> l'application en tant que paramètre DSN ou<br />
FileDSN.
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Lorsque la source <strong>de</strong><br />
données...<br />
Contient le nom et<br />
l’emplacement du pilote<br />
ODBC, le nom du<br />
fichier/serveur <strong>de</strong> la base<br />
<strong>de</strong> données, les<br />
paramètres <strong>de</strong> démarrage,<br />
l'ID utilisateur et le mot<br />
<strong>de</strong> passe.<br />
Contient uniquement le<br />
nom et l'emplacement du<br />
pilote ODBC.<br />
La chaîne <strong>de</strong><br />
connexion doit<br />
i<strong>de</strong>ntifier...<br />
Aucune information<br />
complémentaire<br />
Le nom du fichier/serveur<br />
<strong>de</strong> la base <strong>de</strong> données et,<br />
éventuellement, l'ID<br />
utilisateur et le mot <strong>de</strong><br />
passe.<br />
N'existe pas. Le nom du pilote ODBC à<br />
utiliser, selon la syntaxe :<br />
Driver={nom_pilote<br />
_ODBC}<br />
Egalement, le nom <strong>de</strong> la<br />
base <strong>de</strong> données, du<br />
fichier <strong>de</strong> base <strong>de</strong> données<br />
ou du serveur et,<br />
éventuellement, d'autres<br />
paramètres <strong>de</strong> connexion<br />
tels que l'ID utilisateur ou<br />
le mot <strong>de</strong> passe.<br />
L'utilisateur doit<br />
fournir...<br />
Aucune information<br />
complémentaire<br />
L'ID utilisateur et le<br />
mot <strong>de</strong> passe, s'ils ne<br />
sont pas fournis dans le<br />
DSN ou la chaîne <strong>de</strong><br />
connexion ODBC.<br />
L'ID utilisateur et le<br />
mot <strong>de</strong> passe, s'ils ne<br />
sont pas fournis dans la<br />
chaîne <strong>de</strong> connexion<br />
ODBC.<br />
$ Pour plus d’informations sur les connexions et les configurations<br />
ODBC, reportez-vous aux sujets suivants :<br />
♦ "Connexion à une base <strong>de</strong> données", page 39 du document ASA <strong>Gui<strong>de</strong></strong><br />
d’administration.<br />
♦ Open Database Connectivity (ODBC) SDK, disponible auprès <strong>de</strong><br />
Microsoft.<br />
Déploiement <strong>de</strong> clients Embed<strong>de</strong>d SQL<br />
Le moyen le plus simple pour déployer <strong>de</strong>s clients Embed<strong>de</strong>d SQL consiste à<br />
utiliser les objets ou modèles InstallShield. Pour plus d'informations,<br />
reportez-vous à la section "Utilisation <strong>de</strong>s objets et modèles InstallShield<br />
pour le déploiement", page 414.<br />
427
Déploiement <strong>de</strong>s applications clientes<br />
428<br />
Pour déployer <strong>de</strong>s clients Embed<strong>de</strong>d SQL, vous <strong>de</strong>vez disposer <strong>de</strong>s éléments<br />
suivants :<br />
♦ Fichiers installés Chaque machine cliente doit disposer <strong>de</strong>s fichiers<br />
requis pour une application cliente Embed<strong>de</strong>d SQL d’<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>.<br />
♦ Les informations <strong>de</strong> connexion Les informations <strong>de</strong> connexion.<br />
L'application cliente doit avoir accès aux informations requises pour se<br />
connecter au serveur. Ces informations peuvent se trouver dans une<br />
source <strong>de</strong> données ODBC.<br />
Installation <strong>de</strong>s fichiers pour les clients Embed<strong>de</strong>d SQL<br />
Remarques<br />
Le tableau suivant indique les fichiers requis pour les clients<br />
Embed<strong>de</strong>d SQL.<br />
Description Windows UNIX<br />
Bibliothèque d'interface dblib8.dll libdblib8.so,<br />
libdbtasks8.so<br />
Bibliothèque <strong>de</strong> ressources dblgen8.dll dblgen8.res<br />
<strong>de</strong> langue<br />
Communications réseau<br />
IPX<br />
Boîte <strong>de</strong> dialogue<br />
Connexion<br />
dbipx8.dll sans objet<br />
dbcon8.dll sans objet<br />
♦ Le DLL <strong>de</strong>s ports réseau n'est pas requis si le client ne travaille qu'avec<br />
le serveur <strong>de</strong> base <strong>de</strong> données personnel.<br />
♦ Si l'application cliente utilise une source <strong>de</strong> données ODBC pour<br />
conserver les paramètres <strong>de</strong> connexion, l'utilisateur final doit disposer<br />
d'une installation ODBC active. Les instructions <strong>de</strong> déploiement<br />
d'ODBC se trouvent dans Microsoft ODBC SDK.<br />
$ Pour plus d'informations sur le déploiement ODBC, reportez-vous<br />
à la section "Déploiement <strong>de</strong> clients ODBC", page 421.<br />
♦ La boîte <strong>de</strong> dialogue Connexion est requise si les utilisateurs finaux<br />
prévoient <strong>de</strong> créer leur propres sources <strong>de</strong> données, s'ils doivent entrer<br />
<strong>de</strong>s ID utilisateur et <strong>de</strong>s mots <strong>de</strong> passe au moment <strong>de</strong> la connexion à la<br />
base <strong>de</strong> données ou s'ils souhaitent afficher la boîte <strong>de</strong> dialogue<br />
Connexion pour toute autre raison.<br />
♦ Pour les applications multithread sous UNIX, utilisez libdblib8_r.so et<br />
libdbtasks8_r.so.
Informations <strong>de</strong> connexion<br />
Déploiement <strong>de</strong> clients JDBC<br />
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Pour déployer les informations <strong>de</strong> connexion Embed<strong>de</strong>d SQL, vous avez le<br />
choix :<br />
♦ Manuelle Fournissez aux utilisateurs finals les instructions requises pour<br />
créer une source <strong>de</strong> données adéquate sur leur machine.<br />
♦ Fichier Distribuez un fichier contenant les informations <strong>de</strong> connexion<br />
dans un format lisible par votre application.<br />
♦ Source <strong>de</strong> données ODBC Vous pouvez placer les informations <strong>de</strong><br />
connexion dans une source <strong>de</strong> données ODBC. Pour ce faire, vous avez<br />
besoin d'un sous-ensemble <strong>de</strong>s fichiers ODBC redistribuables,<br />
disponible auprès <strong>de</strong> Microsoft. Pour plus d'informations, reportez-vous<br />
à la section "Déploiement <strong>de</strong> clients ODBC", page 421.<br />
♦ Codé matériellement Vous pouvez co<strong>de</strong>r matériellement les<br />
informations <strong>de</strong> connexion dans votre application. Il s'agit d'une<br />
métho<strong>de</strong> rigi<strong>de</strong>, risquant d'être restrictive lors, par exemple, <strong>de</strong>s mises à<br />
niveau <strong>de</strong> bases <strong>de</strong> données.<br />
Chaque client JDBC requiert, outre un environnement Java Runtime, le<br />
pilote JDBC jConnect <strong>de</strong> <strong>Sybase</strong> ou la passerelle JDBC-ODBC.<br />
$ Pour plus d'informations sur le déploiement <strong>de</strong> jConnect, reportez-vous<br />
à la page http://manuals.sybase.com/onlinebooks/group-jc sur le site Web <strong>de</strong><br />
<strong>Sybase</strong>.<br />
Pour déployer la passerelle JDBC-ODBC, vous <strong>de</strong>vez déployer les fichiers<br />
suivants:<br />
♦ jodbc.jar Ce fichier doit se trouver dans le répertoire <strong>de</strong>s classes <strong>de</strong><br />
l'application.<br />
♦ dbjodbc8.dll Ce fichier doit se trouver dans le répertoire système. Sous<br />
environnements UNIX et Linux, il s'agit d'un fichier <strong>de</strong> bibliothèque<br />
partagée (dbjodbc8.so).<br />
♦ Les fichiers pilote ODBC. Pour <strong>de</strong> plus amples informations, reportezvous<br />
à la rubrique "Fichiers requis par le pilote ODBC", page 422.<br />
Votre application Java doit être dotée d'une URL pour se connecter à la base<br />
<strong>de</strong> données. Cette URL spécifie le pilote, la machine à utiliser et le port<br />
écouté par le serveur <strong>de</strong> base <strong>de</strong> données.<br />
$ Pour plus d'informations, reportez-vous à la section "Fourniture d'une<br />
URL au serveur", page 149.<br />
429
Déploiement <strong>de</strong>s applications clientes<br />
Déploiement d'une application Open Client<br />
430<br />
Pour déployer <strong>de</strong>s applications Open Client, chaque machine cliente doit<br />
disposer du produit Open Client <strong>de</strong> <strong>Sybase</strong>. Vous <strong>de</strong>vez acquérir le logiciel<br />
Open Client distinctement <strong>de</strong> <strong>Sybase</strong>. Il contient ses propres instructions<br />
d'installation.<br />
$ Les informations <strong>de</strong> connexion pour les clients Open Client se trouvent<br />
dans le fichier d'interface. Pour <strong>de</strong>s informations sur le fichier d'interface,<br />
reportez-vous à la documentation Open Client et à la section "Configuration<br />
d'Open <strong>Server</strong>", page 116 du document ASA <strong>Gui<strong>de</strong></strong> d’administration.
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Déploiement <strong>de</strong>s outils d'administration<br />
Déploiement<br />
Interactive SQL<br />
Selon votre contrat <strong>de</strong> licence, vous pouvez déployer un ensemble d'outils<br />
d'administration comprenant Interactive SQL, <strong>Sybase</strong> Central et l'utilitaire <strong>de</strong><br />
contrôle dbconsole.<br />
Le moyen le plus simple pour déployer ces outils d'administration consiste à<br />
utiliser les objets InstallShield fournis. Pour plus d'informations, reportezvous<br />
à la section "Utilisation <strong>de</strong>s objets et modèles InstallShield pour le<br />
déploiement", page 414.<br />
Si l'application cliente fonctionne sur <strong>de</strong>s machines aux ressources limitées,<br />
il peut être intéressant <strong>de</strong> déployer la version C d'Interactive SQL<br />
(dbisqlc.exe) au lieu <strong>de</strong> la version standard (dbisql.exe et les classes Java<br />
associées).<br />
L'exécutable dbisqlc nécessite les bibliothèques clientes Embed<strong>de</strong>d SQL<br />
standard.<br />
$ Pour plus d'informations sur les conditions système requises pour les<br />
outils d'administration, reportez-vous à la section "Conditions système pour<br />
les outils d'administration", page 147 du document Présentation <strong>de</strong> SQL<br />
<strong>Anywhere</strong> Studio.<br />
431
Déploiement <strong>de</strong>s serveurs <strong>de</strong> base <strong>de</strong> données<br />
Déploiement <strong>de</strong>s serveurs <strong>de</strong> base <strong>de</strong> données<br />
432<br />
Vous pouvez déployer un serveur <strong>de</strong> base <strong>de</strong> données en mettant le<br />
programme <strong>de</strong> configuration <strong>de</strong> SQL <strong>Anywhere</strong> Studio à disposition <strong>de</strong>s<br />
utilisateurs finals. En sélectionnant ensuite l'option appropriée, chaque<br />
utilisateur final est assuré <strong>de</strong> recevoir les fichiers dont il a besoin.<br />
Le moyen le plus simple pour déployer un serveur <strong>de</strong> base <strong>de</strong> données<br />
personnel ou <strong>de</strong> réseau consiste à utiliser les objets InstallShield fournis.<br />
Pour plus d'informations, reportez-vous à la section "Utilisation <strong>de</strong>s objets et<br />
modèles InstallShield pour le déploiement", page 414.<br />
Pour exécuter un serveur <strong>de</strong> base <strong>de</strong> données, vous <strong>de</strong>vez installer un<br />
ensemble <strong>de</strong> fichiers. Les fichiers sont répertoriés dans le tableau suivant.<br />
Toute redistribution <strong>de</strong> ces fichiers est soumise aux termes <strong>de</strong> votre contrat<br />
<strong>de</strong> licence. Vous <strong>de</strong>vez confirmer que vous détenez l'autorisation <strong>de</strong><br />
redistribuer les fichiers du serveur <strong>de</strong> base <strong>de</strong> données avant <strong>de</strong> procé<strong>de</strong>r à la<br />
redistribution.<br />
Windows UNIX NetWare<br />
dbeng8.exe dbeng8 sans objet<br />
dbsrv8.exe dbsrv8 dbsrv8.nlm<br />
dbserv8.dll libdbserv8.so,<br />
libdbtasks8_r.so<br />
sans objet<br />
dblgen8.dll dblgen8.res dblgen8.res<br />
dbjava8.dll (1)<br />
libdbjava8.so (1)<br />
dbjava8.nlm (1)<br />
dbctrs8.dll sans objet sans objet<br />
dbextf.dll (2)<br />
asajdbc.zip (1,3)<br />
asajrt12.zip (1,3)<br />
classes.zip (1,3)<br />
dbmem.vxd (4)<br />
libdbextf.so (2)<br />
asajdbc.zip (1,3)<br />
asajrt12.zip (1,3)<br />
classes.zip (1,3)<br />
N/A N/A<br />
libunic.dll libunic.so N/A<br />
dbextf.nlm (2)<br />
asajdbc.zip (1,3)<br />
asajrt12.zip (1,3)<br />
classes.zip (1,3)<br />
asa.cvf asa.cvf asa.cvf<br />
charsets\ directory charsets/ directory N/A<br />
1. Requis uniquement si Java est utilisé dans la base <strong>de</strong> données. Pour les bases <strong>de</strong> données<br />
initialisées avec JDK 1.1, distribuez asajdbc.zip. Pour celles initialisées avec JDK 1.2 ou<br />
JDK 1.3, distribuez asajrt13.zip.<br />
2. Requis uniquement si vous utilisez les procédures stockées et les fonctions (xp_) à l'échelle du<br />
système.
Remarques<br />
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
3. Installez <strong>de</strong> sorte que la variable d’environnement CLASSPATH puisse localiser les classes<br />
dans ce fichier.<br />
4. Requis sous Windows 95/98/Me si vous utilisez l'allocation <strong>de</strong> mémoire cache dynamique.<br />
♦ Selon votre situation, choisissez <strong>de</strong> déployer le serveur <strong>de</strong> base <strong>de</strong><br />
données personnel (dbeng8) ou le serveur <strong>de</strong> base <strong>de</strong> données <strong>de</strong> réseau<br />
(dbsrv8).<br />
♦ La DLL Java (dbjava8.dll) n'est requise que si le serveur <strong>de</strong> base <strong>de</strong><br />
données doit utiliser la fonctionnalité Java dans la base <strong>de</strong> données.<br />
♦ Le tableau ne mentionne pas les fichiers requis pour exécuter <strong>de</strong>s<br />
utilitaires tels que dbbackup.<br />
$ Pour <strong>de</strong>s informations sur le déploiement <strong>de</strong>s utilitaires, reportezvous<br />
à la section "Déploiement <strong>de</strong>s outils d'administration", page 431.<br />
♦ Les fichiers zip ne sont requis que pour les applications utilisant Java<br />
dans la base <strong>de</strong> données, et doivent être installés à un emplacement<br />
référencé par la variable d'environnement CLASSPATH <strong>de</strong> l'utilisateur.<br />
Déploiement <strong>de</strong> bases <strong>de</strong> données<br />
Pour déployer un fichier <strong>de</strong> base <strong>de</strong> données, installez-le sur le disque <strong>de</strong><br />
l'utilisateur final.<br />
Tant que le serveur <strong>de</strong> base <strong>de</strong> données se ferme correctement, il est inutile<br />
<strong>de</strong> déployer un journal <strong>de</strong> transactions avec le fichier <strong>de</strong> base <strong>de</strong> données.<br />
Lorsque l'utilisateur final lance la base <strong>de</strong> données, un nouveau journal <strong>de</strong><br />
transactions est créé.<br />
Pour les applications SQL Remote, la base <strong>de</strong> données doit être créée dans<br />
un état correctement synchronisé, auquel cas un journal <strong>de</strong> transactions est<br />
inutile. Vous pouvez utiliser l'utilitaire Extraction à cet effet.<br />
Déploiement <strong>de</strong> bases <strong>de</strong> données sur un support en lecture seule<br />
Vous pouvez distribuer <strong>de</strong>s bases <strong>de</strong> données sur un support en lecture seule,<br />
tel qu'un CD-ROM, dès lors que vous l'exécutez en mo<strong>de</strong> lecture seule ou<br />
que vous utilisez un fichier d'écriture.<br />
$ Pour plus d'information sur l'exécution <strong>de</strong>s bases <strong>de</strong> données en lecture<br />
seule, reportez-vous à la section "Option <strong>de</strong> serveur -r", page 160 du<br />
document ASA <strong>Gui<strong>de</strong></strong> d’administration.<br />
433
Déploiement <strong>de</strong>s serveurs <strong>de</strong> base <strong>de</strong> données<br />
434<br />
Pour que les modifications soient répercutées dans les bases <strong>de</strong> données<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> distribuées sur un support en lecture seule, tel<br />
qu'un CD-ROM, vous pouvez utiliser un fichier d'écriture. Le fichier<br />
d'écriture enregistre les modifications apportées à un fichier <strong>de</strong> base <strong>de</strong><br />
données en lecture seule ; il se trouve sur un support <strong>de</strong> stockage <strong>de</strong> type<br />
lecture/écriture, par exemple un disque dur.<br />
Dans ce cas, le fichier <strong>de</strong> base <strong>de</strong> données est placé sur le CD-ROM et le<br />
fichier d'écriture sur le disque. La connexion est établie avec le fichier<br />
d'écriture, lequel maintient un fichier journal <strong>de</strong> transactions sur le disque.<br />
$ Pour plus d'informations sur les fichiers d'écriture, reportez-vous à la<br />
section "Utilisation <strong>de</strong>s fichiers d'écriture", page 239 du document ASA<br />
<strong>Gui<strong>de</strong></strong> d’administration.
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Déploiement d'applications <strong>de</strong> base <strong>de</strong> données<br />
embarquées<br />
Cette section traite du déploiement d'applications <strong>de</strong> bases <strong>de</strong> données<br />
embarquées, où l'application et la base <strong>de</strong> données rési<strong>de</strong>nt toutes <strong>de</strong>ux sur la<br />
même machine.<br />
Une application <strong>de</strong> base <strong>de</strong> données embarquée contient :<br />
♦ Application cliente Cela inclut les conditions du client <strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong>.<br />
$ Pour <strong>de</strong>s informations sur le déploiement <strong>de</strong>s applications clientes,<br />
reportez-vous à la section "Déploiement <strong>de</strong>s applications clientes",<br />
page 420.<br />
♦ Serveur <strong>de</strong> base <strong>de</strong> données Serveur <strong>de</strong> base <strong>de</strong> données personnel<br />
d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
$ Pour <strong>de</strong>s informations sur le déploiement <strong>de</strong>s serveurs <strong>de</strong> base <strong>de</strong><br />
données, reportez-vous à la section "Déploiement <strong>de</strong>s serveurs <strong>de</strong> base<br />
<strong>de</strong> données", page 432.<br />
♦ SQL Remote Si votre application exploite la réplication SQL Remote,<br />
vous <strong>de</strong>vez déployer l'agent <strong>de</strong> message SQL Remote.<br />
♦ La base <strong>de</strong> données Vous <strong>de</strong>vez déployer un fichier <strong>de</strong> base <strong>de</strong><br />
données contenant les données utilisées par l'application.<br />
Déploiement <strong>de</strong> serveurs personnels<br />
Lorsque vous déployez une application qui utilise le serveur personnel, vous<br />
<strong>de</strong>vez déployer à la fois les composants <strong>de</strong> l'application cliente et ceux du<br />
serveur <strong>de</strong> base <strong>de</strong> données.<br />
La bibliothèque <strong>de</strong> ressources <strong>de</strong> langue (dblgen8.dll) est partagée par le<br />
client et le serveur. Vous n'avez besoin que d'une copie <strong>de</strong> ce fichier.<br />
Il est conseillé <strong>de</strong> suivre le comportement <strong>de</strong> l'installation d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> et d'installer les fichiers clients et serveur dans le même<br />
répertoire.<br />
N'oubliez pas <strong>de</strong> fournir les fichiers zip Java et le DLL Java si votre<br />
application fait appel à Java dans la base <strong>de</strong> données.<br />
435
Déploiement d'applications <strong>de</strong> base <strong>de</strong> données embarquées<br />
Déploiement d'utilitaires <strong>de</strong> base <strong>de</strong> données<br />
Remarques<br />
436<br />
Si vous <strong>de</strong>vez déployer <strong>de</strong>s utilitaires <strong>de</strong> base <strong>de</strong> données (tels que<br />
dbbackup.exe) avec votre application, vous <strong>de</strong>vez disposer <strong>de</strong> l'exécutable <strong>de</strong><br />
l'utilitaire et <strong>de</strong>s fichiers complémentaires suivants :<br />
Description Windows UNIX<br />
Bibliothèque d'outils <strong>de</strong> base <strong>de</strong><br />
données<br />
dbtool8.dll libdbtools8.so,<br />
libdbtasks8.so<br />
Bibliothèque complémentaire dbwtsp8.dll libdbwtsp8.so<br />
Bibliothèque <strong>de</strong> ressources <strong>de</strong><br />
langue<br />
Boîte <strong>de</strong> dialogue Connexion<br />
(dbisqlc uniquement)<br />
Déploiement <strong>de</strong> SQL Remote<br />
dblgen8.dll dblgen8.res<br />
dbcon8.dll<br />
♦ Les outils <strong>de</strong> base <strong>de</strong> données sont <strong>de</strong>s applications Embed<strong>de</strong>d SQL et<br />
vous <strong>de</strong>vez donc fournir les fichiers requis par ces applications,<br />
répertoriés à la section "Déploiement <strong>de</strong> clients Embed<strong>de</strong>d SQL",<br />
page 427.<br />
♦ Pour les applications multithread sous UNIX, utilisez libdbtools8_r.so et<br />
libdbtasks8_r.so.<br />
Si vous déployez l'agent <strong>de</strong> message SQL Remote, vous <strong>de</strong>vez intégrer les<br />
fichiers suivants :<br />
Description Windows UNIX<br />
agent <strong>de</strong> message dbremote.exe dbremote<br />
Bibliothèque d'outils <strong>de</strong> base <strong>de</strong><br />
données<br />
dbtool8.dll libdbtools8.so,<br />
libdbtasks8.so<br />
Bibliothèque complémentaire dbwtsp8.dll libdbwtsp8.so<br />
Bibliothèque <strong>de</strong> ressources <strong>de</strong><br />
langue<br />
Bibliothèque <strong>de</strong> liaison <strong>de</strong><br />
message VIM 1<br />
dblgen8.dll dblgen8.res<br />
dbvim8.dll
Chapitre 12 Déploiement <strong>de</strong> bases <strong>de</strong> données et d'applications<br />
Description Windows UNIX<br />
Bibliothèque <strong>de</strong> liaison <strong>de</strong><br />
message SMTP 1<br />
Bibliothèque <strong>de</strong> liaison <strong>de</strong><br />
message FILE 1<br />
Bibliothèque <strong>de</strong> liaison <strong>de</strong><br />
message FILE 1<br />
Bibliothèque <strong>de</strong> liaison <strong>de</strong><br />
message MAPI 1<br />
dbsmtp8.dll<br />
dbfile8.dll libdbfile8.so<br />
dbftp8.dll<br />
dbmapi8.dll<br />
Bibliothèque d'interface dblib8.dll<br />
1 Déploie uniquement la bibliothèque pour la liaison <strong>de</strong> messagerie que vous utilisez.<br />
Il est conseillé <strong>de</strong> suivre le comportement <strong>de</strong> l'installation d'<strong>Adaptive</strong> <strong>Server</strong><br />
<strong>Anywhere</strong> et d'installer les fichiers SQL Remote dans le même répertoire que<br />
les fichiers d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>.<br />
Pour les applications multithread sous UNIX, utilisez libdbtools8_r.so et<br />
libdbtasks8_r.so.<br />
437
Déploiement d'applications <strong>de</strong> base <strong>de</strong> données embarquées<br />
438
CHAPITRE 13<br />
Messages d'erreur du préprocesseur SQL<br />
Présentation<br />
Sommaire<br />
Ce chapitre présente une liste <strong>de</strong> tous les messages d'erreur et d'avertissement<br />
du préprocesseur SQL.<br />
Sujet Page<br />
Messages d'erreur du préprocesseur SQL in<strong>de</strong>xés par valeur <strong>de</strong><br />
message d'erreur 440<br />
Erreurs SQLPP 444<br />
439
Messages d'erreur du préprocesseur SQL in<strong>de</strong>xés par valeur <strong>de</strong> message d'erreur<br />
Messages d'erreur du préprocesseur SQL<br />
in<strong>de</strong>xés par valeur <strong>de</strong> message d'erreur<br />
440<br />
Valeur <strong>de</strong> message Message<br />
2601 "Valeur <strong>de</strong> souscription '%1' trop élevée", page 458<br />
2602 "Association <strong>de</strong> pointeurs et <strong>de</strong> tables non gérée<br />
pour ces types d'hôtes", page 449<br />
2603 "Seuls les tableaux à une seule colonne sont gérés<br />
pour le type char", page 457<br />
2604 "Le type VARCHAR doit contenir une longueur",<br />
page 448<br />
2605 "Tables <strong>de</strong> VARCHAR non gérées", page 448<br />
2606 "Les variables du système hôte VARCHAR ne<br />
peuvent pas être <strong>de</strong>s pointeurs", page 448<br />
2607 "Le système d'initialisation ne peut être utilisé sur<br />
les variables du système hôte VARCHAR",<br />
page 453<br />
2608 "Le type FIXCHAR doit contenir une longueur",<br />
page 445<br />
2609 "Tableaux <strong>de</strong> FIXCHAR non gérés", page 448<br />
2610 "Tables <strong>de</strong> ce type non gérées", page 449<br />
2611 "Spécifiez la précision pour le type décimal",<br />
page 457<br />
2612 "Tableau <strong>de</strong> DECIMAL non autorisé", page 449<br />
2613 "Type <strong>de</strong> variable du système hôte inconnu",<br />
page 447<br />
2614 "Entier incorrect", page 454<br />
2615 "La variable du système hôte '%1' doit être un type<br />
<strong>de</strong> chaîne en C", page 444<br />
2617 "Symbole '%1' déjà défini", page 444<br />
2618 "Type incorrect attribué à l'instruction SQL",<br />
page 455<br />
2619 "Le fichier à inclure, '%1', est introuvable",<br />
page 445<br />
2620 "Variable du système hôte '%1' inconnue",<br />
page 451
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Valeur <strong>de</strong> message Message<br />
2621 "Variable d’indicateur ’%1’ inconnue", page 453<br />
2622 "Type incorrect pour la variable d’indicateur ’%1’",<br />
page 455<br />
2623 "Type <strong>de</strong> variable du système hôte incorrect sur<br />
'%1'", page 454<br />
2625 "La variable '%1' possè<strong>de</strong> <strong>de</strong>ux définitions<br />
différentes", page 451<br />
2626 "L'instruction '%1' n'a pas été préparée", page 457<br />
2627 "Le curseur '%1' n'a pas été déclaré", page 450<br />
2628 "Instruction '%1' inconnue", page 459<br />
2629 "Variables du système hôte non autorisées pour ce<br />
curseur", page 452<br />
2630 "Variables du système hôte spécifiées <strong>de</strong>ux fois -<br />
avec <strong>de</strong>clare et open", page 452<br />
2631 "Vous <strong>de</strong>vez spécifier une liste <strong>de</strong> variables du<br />
système hôte dans une clause USING <strong>de</strong> %1",<br />
page 456<br />
2633 "Clause INTO non autorisée dans une instruction<br />
SELECT", page 456<br />
2634 "Syntaxe <strong>de</strong> langage SQL incorrecte - ceci est une<br />
extension '%1'", page 453<br />
2635 "Syntaxe Embed<strong>de</strong>d SQL incorrecte - ceci est une<br />
extension '%1'", page 452<br />
2636 "Syntaxe Embed<strong>de</strong>d SQL incorrecte", page 452<br />
2637 "Guillemet <strong>de</strong> fin <strong>de</strong> chaîne manquant", page 455<br />
2639 "Jeton trop grand", page 458<br />
2640 "La variable du système hôte '%1' doit être <strong>de</strong> type<br />
integer", page 444<br />
2641 "Spécifiez une structure SQLDA avec<br />
DESCRIBE", page 456<br />
2642 "Deux structures SQLDA du même type spécifiées<br />
(INTO ou USING)", page 447<br />
2646 "Impossible <strong>de</strong> décrire <strong>de</strong>s curseurs statiques",<br />
page 449<br />
2647 "Impossible <strong>de</strong> redéfinir les macros", page 447<br />
2648 "Taille <strong>de</strong> tableau incorrecte", page 447<br />
441
Messages d'erreur du préprocesseur SQL in<strong>de</strong>xés par valeur <strong>de</strong> message d'erreur<br />
442<br />
Valeur <strong>de</strong> message Message<br />
2649 "L’in<strong>de</strong>x <strong>de</strong> <strong>de</strong>scripteur est incorrect", page 454<br />
2650 "Champ incorrect pour SET DESCRIPTOR",<br />
page 454<br />
2651 "Champ utilisé plusieurs fois dans l'instruction SET<br />
DESCRIPTOR", page 450<br />
2652 "La valeur <strong>de</strong>s données doit être une variable du<br />
système hôte", page 450<br />
2660 "Clause INTO sur curseur DECLARE non<br />
autorisée - ignorée", page 446<br />
2661 "Syntaxe SQL inconnue", page 459<br />
2662 "Fonction SQL inconnue '%1'", page 459<br />
2663 "Nombre <strong>de</strong> paramètres erroné pour la fonction<br />
SQL '%1'", page 460<br />
2664 "Les noms <strong>de</strong> déclarations statiques ne fonctionnent<br />
pas correctement lorsqu'ils sont utilisés par <strong>de</strong>ux<br />
threads", page 458<br />
2665 "La variable du système hôte '%1' a été redéfinie",<br />
page 451<br />
2666 "Extension propriétaire", page 460<br />
2667 "Fonction SQL intermédiaire", page 453<br />
2668 "Fonction SQL complète", page 451<br />
2669 "Extension Transact-SQL", page 458<br />
2680 "Pas <strong>de</strong> section <strong>de</strong> déclaration ni d'instruction<br />
INCLUDE SQLCA", page 457<br />
2681 "Impossible d'ouvrir le fichier temporaire",<br />
page 459<br />
2682 "Erreur <strong>de</strong> lecture du fichier temporaire", page 450<br />
2683 "Erreur d'écriture du fichier <strong>de</strong> résultats", page 450<br />
2690 "Nombre incorrect <strong>de</strong> variables du système hôte<br />
pour ce curseur", page 446<br />
2691 "Types <strong>de</strong> variables du système hôte incorrects<br />
pour ce curseur", page 446<br />
2692 "Variables d'indicateur incorrectes pour ce<br />
curseur", page 446
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Valeur <strong>de</strong> message Message<br />
2693 "Fonctionnalité non disponible avec UltraLite",<br />
page 445<br />
2694 "Aucune instruction OPEN pour le curseur '%1'",<br />
page 456<br />
2695 "Aucune instruction FETCH ou PUT pour le<br />
curseur '%1'", page 456<br />
2696 "La variable hôte '%1' est utilisée plusieurs fois<br />
avec <strong>de</strong>s indicateurs différents", page 445<br />
2697 "La taille <strong>de</strong>s données long binary/long varchar est<br />
limitée à 65 535 octets pour UltraLite", page 455<br />
443
Erreurs SQLPP<br />
Erreurs SQLPP<br />
444<br />
Cette section répertorie les messages générés par le préprocesseur SQL. Il<br />
peut s'agir <strong>de</strong> messages d'erreur et/ou d'avertissement selon les options <strong>de</strong><br />
ligne <strong>de</strong> comman<strong>de</strong> activées.<br />
$ Pour plus d'informations sur le préprocesseur SQL et ses options <strong>de</strong><br />
ligne <strong>de</strong> comman<strong>de</strong>, reportez-vous à la section "Préprocesseur SQL",<br />
page 247.<br />
La variable du système hôte '%1' doit être un type <strong>de</strong> chaîne en C<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2615 Erreur<br />
Une chaîne en C était requise dans une instruction Embed<strong>de</strong>d SQL (pour un<br />
nom <strong>de</strong> curseur, un nom d'option, etc.) et la valeur fournie n'était pas une<br />
chaîne <strong>de</strong> ce type.<br />
La variable du système hôte '%1' doit être <strong>de</strong> type integer<br />
Description<br />
Symbole '%1' déjà défini<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2640 Erreur<br />
Vous avez utilisé une variable hôte qui n'est pas <strong>de</strong> type entier dans une<br />
instruction où seule une variable hôte <strong>de</strong> type entier est autorisée.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2617 Erreur<br />
Vous avez défini <strong>de</strong>ux fois une variable hôte.
Le fichier à inclure, '%1', est introuvable<br />
Description<br />
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2619 Erreur<br />
Impossible <strong>de</strong> trouver le fichier à inclure spécifié. Le préprocesseur utilisera<br />
la variable d'environnement INCLUDE pour rechercher les fichiers à inclure.<br />
Le type FIXCHAR doit contenir une longueur<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2608 Erreur<br />
Vous avez utilisé la macro DECL_FIXCHAR pour déclarer une variable<br />
hôte <strong>de</strong> type FIXCHAR mais vous avez omis <strong>de</strong> spécifier une longueur.<br />
Fonctionnalité non disponible avec UltraLite<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2693 Drapeau (avertissement ou erreur)<br />
Vous avez utilisé une fonctionnalité non supportée par UltraLite.<br />
La variable hôte '%1' est utilisée plusieurs fois avec <strong>de</strong>s indicateurs<br />
différents<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2696 Erreur<br />
Vous avez utilisé la même variable hôte plusieurs fois avec différentes<br />
variables d'indicateurs dans la même instruction. Cette fonctionnalité n'est<br />
pas supportée.<br />
445
Erreurs SQLPP<br />
Types <strong>de</strong> variables du système hôte incorrects pour ce curseur<br />
Description<br />
446<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2691 Erreur<br />
Vous avez utilisé une variable hôte avec une longueur ou un type différent <strong>de</strong><br />
la longueur ou du type utilisé précé<strong>de</strong>mment avec le curseur. Les types <strong>de</strong>s<br />
variable hôte doivent être corrects pour le curseur.<br />
Variables d’indicateur incorrectes pour ce curseur<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2692 Erreur<br />
Vous avez utilisé une variable d'indicateur avec le curseur, alors qu'aucune<br />
variable <strong>de</strong> ce type n'avait été utilisée précé<strong>de</strong>mment, ou inversement.<br />
L'utilisation <strong>de</strong>s variables d'indicateur doit être correcte pour le curseur.<br />
Nombre incorrect <strong>de</strong> variables du système hôte pour ce curseur<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2690 Erreur<br />
Vous avez utilisé un nombre <strong>de</strong> variables hôte différent <strong>de</strong> celui utilisé<br />
précé<strong>de</strong>mment avec le curseur. Le nombre <strong>de</strong> variables hôte doit être correct<br />
pour le curseur.<br />
Clause INTO sur curseur DECLARE non autorisée - ignorée<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2660 Avertissement<br />
Vous avez utilisé une clause INTO dans une instruction DECLARE<br />
CURSOR. La clause INTO sera ignorée.
Taille <strong>de</strong> tableau incorrecte<br />
Description<br />
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2648 Erreur<br />
La taille <strong>de</strong> tableau <strong>de</strong> la variable est négative.<br />
Impossible <strong>de</strong> redéfinir les macros<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2647 Erreur<br />
Une macro du préprocesseur a été définie <strong>de</strong>ux fois, peut-être dans un fichier<br />
d'en-tête.<br />
Deux structures SQLDA du même type spécifiées (INTO ou USING)<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2642 Erreur<br />
Vous avez spécifié <strong>de</strong>ux clauses INTO DESCRIPTOR ou USING<br />
DESCRIPTOR pour cette instruction.<br />
Type <strong>de</strong> variable du système hôte inconnu<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2613 Erreur<br />
Vous avez déclaré une variable hôte d'un type non compris par le<br />
préprocesseur SQL.<br />
447
Erreurs SQLPP<br />
Les variables du système hôte VARCHAR ne peuvent pas être <strong>de</strong>s<br />
pointeurs<br />
Description<br />
448<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2606 Erreur<br />
Vous avez tenté <strong>de</strong> déclarer une variable hôte comme un pointeur vers une<br />
variable VARCHAR ou BINARY. Il ne s'agit pas d'un type <strong>de</strong> variable hôte<br />
autorisé.<br />
Le type VARCHAR doit contenir une longueur<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2604 Erreur<br />
Tableaux <strong>de</strong> FIXCHAR non gérés<br />
Description<br />
Tables <strong>de</strong> VARCHAR non gérées<br />
Description<br />
Vous avez tenté <strong>de</strong> déclarer une variable hôte VARCHAR ou BINARY à<br />
l'ai<strong>de</strong> <strong>de</strong> la macro DECL_VARCHAR ou DECL_BINARY mais vous avez<br />
omis d'indiquer une taille pour la table.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2609 Erreur<br />
Vous avez tenté <strong>de</strong> déclarer une variable hôte comme un tableau <strong>de</strong><br />
FIXCHAR. Il ne s'agit pas d'un type <strong>de</strong> variable hôte autorisé.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2605 Erreur<br />
Vous avez tenté <strong>de</strong> déclarer une variable hôte comme une table <strong>de</strong><br />
VARCHAR ou BINARY. Il ne s'agit pas d'un type <strong>de</strong> variable hôte autorisé.
Tableau <strong>de</strong> DECIMAL non autorisé<br />
Description<br />
Tables <strong>de</strong> ce type non gérées<br />
Description<br />
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2612 Erreur<br />
Vous avez tenté <strong>de</strong> déclarer une variable hôte comme un tableau <strong>de</strong><br />
DECIMAL. Il ne s'agit pas d'un type <strong>de</strong> variable hôte autorisé.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2610 Erreur<br />
Vous avez tenté <strong>de</strong> déclarer une table <strong>de</strong> variable hôte qui a un type non<br />
supporté.<br />
Impossible <strong>de</strong> décrire <strong>de</strong>s curseurs statiques<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2646 Erreur<br />
Vous avez décrit un curseur statique. Lors <strong>de</strong> la <strong>de</strong>scription d'un curseur, son<br />
nom doit être spécifié dans une variable hôte.<br />
Association <strong>de</strong> pointeurs et <strong>de</strong> tables non gérée pour ces types<br />
d'hôtes<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2602 Erreur<br />
Vous avez utilisé une table <strong>de</strong> pointeurs comme variable hôte. Cette<br />
opération n'est pas autorisée.<br />
449
Erreurs SQLPP<br />
Le curseur '%1' n'a pas été déclaré<br />
Description<br />
450<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2627 Erreur<br />
Un nom <strong>de</strong> curseur Embed<strong>de</strong>d SQL a été utilisé (dans une instruction<br />
FETCH, OPEN, CLOSE etc.) sans avoir été déclaré (DECLARE).<br />
La valeur <strong>de</strong>s données doit être une variable du système hôte<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2652 Erreur<br />
La variable utilisée dans l'instruction SET DESCRIPTOR n'a pas été<br />
déclarée comme une variable hôte.<br />
Erreur <strong>de</strong> lecture du fichier temporaire<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2682 Erreur<br />
Une erreur s'est produite lors <strong>de</strong> la lecture à partir d'un fichier temporaire.<br />
Erreur d'écriture du fichier <strong>de</strong> résultats<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2683 Erreur<br />
Une erreur s'est produite lors <strong>de</strong> l'écriture dans le fichier <strong>de</strong> résultats.<br />
Champ utilisé plusieurs fois dans l'instruction SET DESCRIPTOR<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2651 Erreur
Description<br />
Fonction SQL complète<br />
Description<br />
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Le même mot-clé a été spécifié plusieurs fois dans une même instruction<br />
SET DESCRIPTOR.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2668 Drapeau (avertissement ou erreur)<br />
Vous avez utilisé une fonctionnalité SQL/92 complète et prétraité avec<br />
l'option <strong>de</strong> balisage -ee, -ei, -we ou -wi.<br />
La variable du système hôte '%1' a été redéfinie<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2665 Avertissement<br />
Vous avez redéfini la même variable hôte avec un type d'hôte différent. En<br />
ce qui concerne le préprocesseur, les variables hôte sont globales ; il n'est pas<br />
possible que <strong>de</strong>ux variables hôte du même nom aient <strong>de</strong>s types différents.<br />
La variable '%1' possè<strong>de</strong> <strong>de</strong>ux définitions différentes<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2625 Erreur<br />
Le même nom <strong>de</strong> variable hôte a été défini avec <strong>de</strong>ux types différents au sein<br />
d'un même module. Notez que les noms <strong>de</strong> variable hôte sont globaux pour<br />
chaque module C.<br />
Variable du système hôte '%1' inconnue<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2620 Erreur<br />
451
Erreurs SQLPP<br />
Description<br />
452<br />
Vous avez utilisé une variable hôte dans une instruction, qui n'a pas été<br />
déclarée dans une section <strong>de</strong> déclaration.<br />
Variables du système hôte non autorisées pour ce curseur<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2629 Erreur<br />
Les variables hôte ne sont pas autorisées dans l'instruction <strong>de</strong> déclaration<br />
pour le curseur spécifié. Si le nom <strong>de</strong> curseur est fourni par le biais d'une<br />
variable hôte, vous <strong>de</strong>vez utiliser SQL dynamique et préparer l'instruction.<br />
Une instruction préparée peut comporter <strong>de</strong>s variables hôte.<br />
Variables du système hôte spécifiées <strong>de</strong>ux fois - avec <strong>de</strong>clare et<br />
open<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2630 Erreur<br />
Vous avez spécifié <strong>de</strong>s variables hôte pour un curseur à la fois dans <strong>de</strong>s<br />
instructions <strong>de</strong>clare et open. Dans le cas statique, vous <strong>de</strong>vez spécifier les<br />
variables hôte dans l'instruction <strong>de</strong>clare. Dans le cas dynamique, indiquez-les<br />
dans l'instruction open.<br />
Syntaxe Embed<strong>de</strong>d SQL incorrecte - ceci est une extension ’%1’<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2635 Erreur<br />
Syntaxe Embed<strong>de</strong>d SQL incorrecte<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2636 Erreur
Description<br />
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Une instruction Embed<strong>de</strong>d SQL spécifique (OPEN, DECLARE, FETCH,<br />
etc.) comporte une erreur <strong>de</strong> syntaxe.<br />
Syntaxe <strong>de</strong> langage SQL incorrecte - ceci est une extension ’%1’<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2634 Erreur<br />
Variable d’indicateur ’%1’ inconnue<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2621 Erreur<br />
Vous avez utilisé une variable d'indicateur dans une instruction, qui n'a pas<br />
été déclarée dans une section <strong>de</strong> déclaration.<br />
Le système d'initialisation ne peut être utilisé sur les variables du<br />
système hôte VARCHAR<br />
Description<br />
Fonction SQL intermédiaire<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2607 Erreur<br />
Vous ne pouvez pas spécifier un initialiseur <strong>de</strong> variable en C pour une<br />
variable <strong>de</strong> système hôte <strong>de</strong> type VARCHAR ou BINARY. Vous <strong>de</strong>vez<br />
initialiser cette variable à l'ai<strong>de</strong> d'un co<strong>de</strong> C exécutable standard.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2667 Drapeau (avertissement ou erreur)<br />
Vous avez utilisé une fonctionnalité SQL/92 intermédiaire et prétraité avec<br />
l'option <strong>de</strong> balisage -ee ou -we.<br />
453
Erreurs SQLPP<br />
L’in<strong>de</strong>x <strong>de</strong> <strong>de</strong>scripteur est incorrect<br />
Description<br />
454<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2649 Erreur<br />
Vous n'avez alloué aucune variable avec l'instruction ALLOCATE<br />
DESCRIPTOR.<br />
Champ incorrect pour SET DESCRIPTOR<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2650 Erreur<br />
Un mot-clé incorrect ou inconnu est présent dans une instruction SET<br />
DESCRIPTOR. Seuls les mots-clés TYPE, PRECISION, SCALE,<br />
LENGTH, INDICATOR, ou DATA sont acceptés.<br />
Type <strong>de</strong> variable du système hôte incorrect sur '%1'<br />
Description<br />
Entier incorrect<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2623 Erreur<br />
Vous avez utilisé une variable hôte qui n'est pas du type chaîne à un<br />
emplacement où le préprocesseur attendait une variable <strong>de</strong> ce type.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2614 Erreur<br />
Un entier était requis dans une instruction Embed<strong>de</strong>d SQL (pour un résultat<br />
d'extraction, un in<strong>de</strong>x <strong>de</strong> table <strong>de</strong> variables hôte, etc.) et le préprocesseur n'a<br />
pas pu convertir les données fournies par l'entier.
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Type incorrect pour la variable d’indicateur ’%1’<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2622 Erreur<br />
Les variables d'indicateur doivent être <strong>de</strong> type entier court. Vous avez utilisé<br />
une variable d'un autre type comme variable d'indicateur.<br />
Type incorrect attribué à l'instruction SQL<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2618 Erreur<br />
Une variable hôte utilisée dans un i<strong>de</strong>ntificateur d'instruction doit être du<br />
type a_sql_statement_number. Vous avez tenté d'utiliser une variable hôte<br />
d'un autre type comme i<strong>de</strong>ntificateur d'instruction.<br />
La taille <strong>de</strong>s données long binary/long varchar est limitée à 65 535<br />
octets pour UltraLite<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2697 Erreur<br />
Lorsque vous utilisez DECL_LONGBINARY ou DECL_LONGVARCHAR<br />
avec UltraLite, la taille maximale <strong>de</strong> la table est <strong>de</strong> 64 ko.<br />
Guillemet <strong>de</strong> fin <strong>de</strong> chaîne manquant<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2637 Erreur<br />
Vous avez spécifié une constante <strong>de</strong> chaîne dans une instruction Embed<strong>de</strong>d<br />
SQL, mais avez omis le guillemet <strong>de</strong> fin avant la fin <strong>de</strong> la ligne ou du fichier.<br />
455
Erreurs SQLPP<br />
Vous <strong>de</strong>vez spécifier une liste <strong>de</strong> variables du système hôte dans<br />
une clause USING <strong>de</strong> %1<br />
Description<br />
456<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2631 Erreur<br />
L'instruction spécifiée requiert <strong>de</strong>s variables hôte <strong>de</strong>vant être indiquées dans<br />
une liste <strong>de</strong> variables hôte ou à partir d'une SQLDA.<br />
Spécifiez une structure SQLDA avec DESCRIBE<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2641 Erreur<br />
Aucune instruction FETCH ou PUT pour le curseur '%1'<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2695 Erreur<br />
Un curseur est déclaré et ouvert, mais n'est jamais utilisé.<br />
Clause INTO non autorisée dans une instruction SELECT<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2633 Erreur<br />
Vous avez spécifié une instruction Embed<strong>de</strong>d SELECT statique mais vous<br />
avez omis d'indiquer une clause INTO pour les résultats.<br />
Aucune instruction OPEN pour le curseur ’%1’<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2694 Erreur
Description<br />
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Un curseur est déclaré, et éventuellement utilisé, mais jamais ouvert.<br />
Pas <strong>de</strong> section <strong>de</strong> déclaration ni d'instruction INCLUDE SQLCA<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2680 Erreur<br />
L’instruction EXEC SQL INCLUDE SQLCA est absente du fichier source.<br />
Seuls les tableaux à une seule colonne sont gérés pour le type<br />
char<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2603 Erreur<br />
Vous avez tenté <strong>de</strong> déclarer une variable hôte comme une table <strong>de</strong> tables <strong>de</strong><br />
caractères. Il ne s'agit pas d'un type <strong>de</strong> variable hôte autorisé.<br />
Spécifiez la précision pour le type décimal<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2611 Erreur<br />
Vous <strong>de</strong>vez indiquer la précision lorsque vous déclarez, à l'ai<strong>de</strong> <strong>de</strong> la macro<br />
DECL_DECIMAL, une variable hôte en décimal con<strong>de</strong>nsé. L'échelle est<br />
facultative.<br />
L'instruction '%1' n'a pas été préparée<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2626 Erreur<br />
Un nom d'instruction Embed<strong>de</strong>d SQL a été utilisé (EXECUTE) sans avoir<br />
été préparé (PREPARE).<br />
457
Erreurs SQLPP<br />
Les noms <strong>de</strong> déclarations statiques ne fonctionnent pas<br />
correctement lorsqu'ils sont utilisés par <strong>de</strong>ux threads<br />
Description<br />
458<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2664 Avertissement<br />
Vous avez utilisé un nom d'instruction statique et prétraité avec l'option -r.<br />
Les noms d'instruction statique entraînent la définition par la base <strong>de</strong><br />
données <strong>de</strong>s variables statiques générées. Si <strong>de</strong>ux threads utilisent la même<br />
instruction, un conflit se produit sur cette variable. Utilisez une variable hôte<br />
locale comme i<strong>de</strong>ntificateur d'instruction à la place du nom statique.<br />
Valeur <strong>de</strong> souscription '%1' trop élevée<br />
Description<br />
Jeton trop grand<br />
Description<br />
Extension Transact-SQL<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2601 Erreur<br />
Vous avez tenté d'in<strong>de</strong>xer une variable hôte qui est une table possédant une<br />
valeur trop élevée.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2639 Erreur<br />
Le préprocesseur SQL a une longueur <strong>de</strong> jeton maximale <strong>de</strong> 2 ko. Tout jeton<br />
supérieur à 2 ko provoque cette erreur. Pour les chaînes constantes dans les<br />
comman<strong>de</strong>s Embed<strong>de</strong>d SQL (où cette erreur se produit le plus<br />
fréquemment), utilisez la concaténation pour obtenir une chaîne plus longue.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2669 Drapeau (avertissement ou erreur)
Description<br />
Chapitre 13 Messages d'erreur du préprocesseur SQL<br />
Vous avez utilisé une fonctionnalité Transact-SQL <strong>Sybase</strong> qui n'est pas<br />
définie par SQL/92 et prétraité avec l'option <strong>de</strong> balisage -ee, -ei, -ef, -we, -wi<br />
ou -wf .<br />
Impossible d’ouvrir le fichier temporaire<br />
Description<br />
Fonction SQL inconnue ’%1’<br />
Description<br />
Instruction ’%1’ inconnue<br />
Description<br />
Syntaxe SQL inconnue<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2681 Erreur<br />
Une erreur s'est produite lors <strong>de</strong> la tentative d'ouverture d'un fichier<br />
temporaire.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2662 Avertissement<br />
Vous avez utilisé une fonction SQL inconnue du préprocesseur et susceptible<br />
<strong>de</strong> provoquer une erreur lors <strong>de</strong> l'envoi <strong>de</strong> l'instruction au moteur <strong>de</strong> la base<br />
<strong>de</strong> données.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2628 Erreur<br />
Vous avez tenté <strong>de</strong> supprimer une instruction Embed<strong>de</strong>d SQL qui n'existe<br />
pas.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2661 Avertissement<br />
459
Erreurs SQLPP<br />
Description<br />
Extension propriétaire<br />
Description<br />
460<br />
Vous avez utilisé une instruction SQL susceptible <strong>de</strong> provoquer une erreur <strong>de</strong><br />
syntaxe lors <strong>de</strong> l'envoi <strong>de</strong> l'instruction au moteur <strong>de</strong> base <strong>de</strong> données.<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2666 Drapeau (avertissement ou erreur)<br />
Vous avez utilisé une fonctionnalité d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong> qui n'est<br />
pas définie par SQL/92 et prétraité avec l'option <strong>de</strong> balisage -ee, -ei, -ef, -we,<br />
-wi ou -wf .<br />
Nombre <strong>de</strong> paramètres erroné pour la fonction SQL '%1'<br />
Description<br />
Valeur <strong>de</strong> message Type <strong>de</strong> message<br />
2663 Avertissement<br />
Vous avez utilisé une fonction SQL avec un nombre erroné <strong>de</strong> paramètres.<br />
Cette opération est susceptible <strong>de</strong> provoquer une erreur lors <strong>de</strong> l'envoi <strong>de</strong><br />
l'instruction au moteur <strong>de</strong> la base <strong>de</strong> données.
In<strong>de</strong>x<br />
><br />
>><br />
métho<strong>de</strong> Java dans la base <strong>de</strong> données, 75<br />
A<br />
a_backup_db, structure, 332<br />
a_change_log, structure, 334<br />
a_compress_db, structure, 336<br />
a_compress_stats, structure, 337<br />
a_create_db, structure, 338<br />
a_crypt_db, structure, 340<br />
a_db_collation, structure, 341<br />
a_db_info, structure, 343<br />
a_dblic_info, structure, 346<br />
a_dbtools_info, structure, 347<br />
a_name, structure, 349<br />
a_stats_line, structure, 349<br />
a_sync_db, structure, 350<br />
a_syncpub, structure, 352<br />
a_sysinfo, structure, 352<br />
a_table_info, structure, 353<br />
a_translate_log, structure, 354<br />
a_truncate_log, structure, 356<br />
a_validate_db, structure, 360<br />
a_validate_type, énumération, 366<br />
a_writefile, structure, 361<br />
accès Java<br />
privé, 69<br />
protégé, 69<br />
public, 69<br />
ActiveX Data Objects<br />
généralités, 370<br />
ADO<br />
comman<strong>de</strong>, 372<br />
connexion, 370<br />
curseur, 26, 375<br />
généralités, 370<br />
introduction à la <strong>programmation</strong>, 3<br />
mise à jour, 375<br />
objet Command, 372<br />
objet Connection, 370<br />
objet Recordset, 373, 375<br />
requête, 373, 375<br />
type <strong>de</strong> curseur, 25<br />
utilisation d'instructions SQL dans les<br />
applications, 10<br />
adresse <strong>de</strong> serveur<br />
fonction Embed<strong>de</strong>d SQL, 256<br />
agencement<br />
Java dans la base <strong>de</strong> données, 116<br />
ajout<br />
classe Java dans la base <strong>de</strong> données, 102<br />
fichier JAR, 103<br />
alloc_sqlda, fonction<br />
généralités, 251<br />
alloc_sqlda_noind, fonction<br />
généralités, 251<br />
461
B–B<br />
ALTER DATABASE, instruction<br />
Java dans la base <strong>de</strong> données, 97, 99<br />
an_erase_db, structure, 347<br />
an_expand_db, structure, 348<br />
an_unload_db, structure, 357<br />
an_upgra<strong>de</strong>_db, structure, 359<br />
annulation <strong>de</strong> requêtes<br />
Embed<strong>de</strong>d SQL, 245<br />
appartenance<br />
jeu <strong>de</strong> résultats, 29<br />
application<br />
déploiement, 405, 420<br />
déploiement Embed<strong>de</strong>d SQL, 427<br />
SQL, 10<br />
application distribuée<br />
conditions requises, 171<br />
exemple, 173<br />
généralités, 171<br />
application multithread<br />
ODBC, 276, 291<br />
UNIX, 280<br />
application utilisant les threads natifs<br />
UNIX, 410<br />
applications multi-thread<br />
Embed<strong>de</strong>d SQL, 208<br />
architecture à trois niveaux<br />
Distributed Transaction Coordinator, 397<br />
distributeur <strong>de</strong> ressources, 396<br />
EA<strong>Server</strong>, 397<br />
généralités, 393<br />
gestionnaire <strong>de</strong> ressources, 396<br />
Microsoft Transaction <strong>Server</strong>, 397<br />
transaction distribuée, 396<br />
architecture informatique<br />
trois niveaux, 395<br />
architecture multithread<br />
Java dans la base <strong>de</strong> données, 121<br />
ARRAY, clause<br />
instruction FETCH, 215<br />
asa<strong>de</strong>mo.db, fichier<br />
généralités, xiv<br />
462<br />
asajdbc.zip<br />
classe d'exécution, 95<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
ASAJDBCDRV<br />
fichier JAR, 96<br />
ASAJRT<br />
fichier JAR, 96<br />
asajrt12.zip<br />
classe d'exécution, 95<br />
ASAProv<br />
fournisseur OLE DB, 368<br />
ASASystem<br />
fichier JAR, 96<br />
assistant<br />
création <strong>de</strong> classe Java, 83, 102, 159<br />
création <strong>de</strong> fichiers JAR et ZIP, 103<br />
mise à jour <strong>de</strong> base <strong>de</strong> données, 99<br />
attribut<br />
Java dans la base <strong>de</strong> données, 130<br />
attribut <strong>de</strong> transaction<br />
composant, 402<br />
autocommit<br />
contrôle, 47<br />
mise en oeuvre, 48<br />
ODBC, 160<br />
transaction, 47<br />
autocommit côté client<br />
généralités, 48<br />
autocommit côté serveur<br />
généralités, 48<br />
autorisation<br />
JDBC, 170<br />
B<br />
base <strong>de</strong> données<br />
configuration pour Java, 95, 97, 99<br />
déploiement, 433<br />
Java dans la base <strong>de</strong> données, 130<br />
URL, 150<br />
base <strong>de</strong> données embarquée<br />
déploiement, 435
ase <strong>de</strong> données exemple<br />
généralités, xiv<br />
Java dans la base <strong>de</strong> données, 92<br />
bibliothèque<br />
Embed<strong>de</strong>d SQL, 181<br />
bibliothèque d'importation<br />
alternatives, 183<br />
DBTools, 311<br />
Embed<strong>de</strong>d SQL, 181<br />
NetWare, 185<br />
ODBC, 278<br />
présentation, 179<br />
Windows CE ODBC, 280<br />
bibliothèque d'interface<br />
chargement dynamique, 183<br />
généralités, 178<br />
nom <strong>de</strong> fichier, 178<br />
BINARY, type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL, 197<br />
BLOB<br />
Embed<strong>de</strong>d SQL, 235<br />
envoi dans Embed<strong>de</strong>d SQL, 238<br />
récupération dans Embed<strong>de</strong>d SQL, 236<br />
bloc catch<br />
Java, 71<br />
bloc finally<br />
Java, 71<br />
bloc try<br />
Java, 71<br />
Borland C++<br />
support, 180<br />
C<br />
cache<br />
Java dans la base <strong>de</strong> données, 137<br />
CALL, instruction<br />
Embed<strong>de</strong>d SQL, 241<br />
callback<br />
DB_CALLBACK_DEBUG_MESSAGE, 260<br />
DB_CALLBACK_FINISH, 260<br />
DB_CALLBACK_MESSAGE, 261<br />
DB_CALLBACK_START, 260<br />
DB_CALLBACK_WAIT, 260<br />
callback, fonction<br />
enregistrement, 259<br />
caractère d'échappement<br />
Java dans la base <strong>de</strong> données, 78<br />
SQL, 78<br />
CD-ROM<br />
déploiement <strong>de</strong> bases <strong>de</strong> données sur, 433<br />
chaîne<br />
Java dans la base <strong>de</strong> données, 76<br />
remplissage <strong>de</strong> blancs <strong>de</strong> DT_STRING, 192<br />
type <strong>de</strong> données, 268<br />
chaîne <strong>de</strong> caractères, 249<br />
chaîne terminée par une valeur NULL<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
CHAINED, option<br />
JDBC, 160<br />
champ<br />
classe, 65<br />
instance, 65<br />
Java dans la base <strong>de</strong> données, 64<br />
privé, 69<br />
protégé, 69<br />
public, 69, 81<br />
SQLDA, 227<br />
champ <strong>de</strong> bits<br />
utilisation, 316<br />
champ public<br />
question, 81<br />
Class.forName, métho<strong>de</strong><br />
chargement <strong>de</strong> jConnect, 149<br />
classe<br />
constructeur, 64<br />
création, 101<br />
exécution, 73<br />
exemple, 108<br />
généralités, 62<br />
importation, 173<br />
installation, 101<br />
instance, 68<br />
Java, 68<br />
mise à jour, 104<br />
C–C<br />
463
C–C<br />
type <strong>de</strong> données, 106<br />
version, 104<br />
classe <strong>de</strong> compilation, 62<br />
classe définie par l'utilisateur<br />
Java dans la base <strong>de</strong> données, 74<br />
classe d'exécution<br />
contenu, 95<br />
installation, 95<br />
classe d'exécution Java dans la base <strong>de</strong> données, 73<br />
classe d'exécution Java <strong>de</strong> <strong>Sybase</strong><br />
présentation, 95<br />
classe Java<br />
ajout, 102<br />
installation, 102<br />
classe Java déconseillée<br />
généralités, 73<br />
classe supportée, 59<br />
classe, champ<br />
généralités, 65<br />
classes.zip<br />
classe d'exécution, 95<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
CLASSPATH, variable d'environnement<br />
généralités, 80<br />
Java dans la base <strong>de</strong> données, 80<br />
jConnect, 147<br />
paramètre, 157<br />
clause<br />
WITH HOLD, 21<br />
clé primaire<br />
Java dans la base <strong>de</strong> données, 117<br />
CLOSE, instruction<br />
généralités, 212<br />
co<strong>de</strong> <strong>de</strong> retour, 313<br />
ODBC, 304<br />
co<strong>de</strong> octet<br />
classe Java, 56<br />
colonne<br />
mise à jour, 111<br />
type <strong>de</strong> données Java dans la base <strong>de</strong> données,<br />
106<br />
464<br />
colonne calculée<br />
création, 134<br />
instruction INSERT, 135<br />
instruction UPDATE, 135<br />
Java dans la base <strong>de</strong> données, 134<br />
recalcul, 136<br />
restriction, 136<br />
trigger, 135<br />
colonne clé primaire<br />
Java dans la base <strong>de</strong> données, 117<br />
colonne unique<br />
Java dans la base <strong>de</strong> données, 117<br />
com.sybase, package<br />
classe d'exécution, 95<br />
Command, objet<br />
ADO, 372<br />
comman<strong>de</strong><br />
objet Command d'ADO, 372<br />
commit<br />
transaction ODBC, 287<br />
commit à <strong>de</strong>ux phases<br />
architecture à trois niveaux, 396, 397<br />
Open Client, 392<br />
commit automatique<br />
ODBC, 287<br />
COMMIT, instruction<br />
curseur, 49<br />
JDBC, 160<br />
mo<strong>de</strong> autocommit, 47<br />
compareTo, métho<strong>de</strong><br />
comparaison d'objets, 117<br />
compilateur<br />
supporté, 180<br />
compilateur GNU<br />
support, 180<br />
composant<br />
attribut <strong>de</strong> transaction, 402<br />
COMPUTE, clause<br />
CREATE TABLE, 134<br />
conception d'une base <strong>de</strong> données<br />
Java dans la base <strong>de</strong> données, 130
con<strong>de</strong>nsation <strong>de</strong> structure<br />
fichier d'en-tête, 181<br />
configuration requise<br />
application Open Client, 386<br />
Connection, objet<br />
ADO, 370<br />
connexion<br />
application JDBC cliente, 154<br />
attribut ODBC, 290<br />
exemple JDBC, 154, 158<br />
fonction, 265<br />
fonction ODBC, 288<br />
jConnect, 150<br />
JDBC, 145, 154, 158, 160<br />
objet Connection d'ADO, 370<br />
<strong>programmation</strong> ODBC, 289<br />
temps d'activité, 260<br />
URL jConnect, 149<br />
constructeur<br />
généralités, 64<br />
insertion <strong>de</strong> données, 110<br />
Java, 69<br />
conventions<br />
documentation, xi<br />
conventions <strong>de</strong> dénomination<br />
fichier, 410<br />
conversion<br />
type <strong>de</strong> données, 203<br />
conversion du jeu <strong>de</strong> caractères<br />
passerelle JDBC-ODBC, 153<br />
coordinateur <strong>de</strong> transactions<br />
EA<strong>Server</strong>, 401<br />
CREATE DATABASE, instruction<br />
Java dans la base <strong>de</strong> données, 97, 98<br />
CREATE PROCEDURE, instruction<br />
Embed<strong>de</strong>d SQL, 241<br />
création <strong>de</strong> classe Java, assistant<br />
utilisation, 83, 102, 159<br />
création <strong>de</strong> fichiers JAR et ZIP, assistant<br />
utilisation, 103<br />
cryptage<br />
interface DBTools, 323<br />
CS_CSR_ABS, 392<br />
CS_CSR_FIRST, 392<br />
CS_CSR_LAST, 392<br />
CS_CSR_PREV, 392<br />
CS_CSR_REL, 392<br />
CS_DATA_BOUNDARY, 392<br />
CS_DATA_SENSITIVITY, 392<br />
CS_PROTO_DYNPROC, 392<br />
CS_REG_NOTIF, 392<br />
CS_REQ_BCP, 392<br />
ct_command, fonction<br />
Open Client, 389, 391<br />
ct_cursor, fonction<br />
Open Client, 390<br />
ct_dynamic, fonction<br />
Open Client, 389<br />
ct_results, fonction<br />
Open Client, 391<br />
ct_send, fonction<br />
Open Client, 391<br />
C–C<br />
curseur, 28<br />
ADO, 26<br />
annulation, 24, 255<br />
appartenance, 29<br />
choix <strong>de</strong>s caractéristiques d'un curseur ODBC,<br />
297<br />
co<strong>de</strong> exemple en C, 186<br />
défilement, 23, 25, 39<br />
défilement dynamique, 25, 38<br />
<strong>de</strong>man<strong>de</strong>, 26<br />
<strong>de</strong>scription, 45<br />
disponibilité, 25<br />
DYNAMIC SCROLL, 21<br />
dynamique, 36<br />
Embed<strong>de</strong>d SQL, 27, 212<br />
exemple <strong>de</strong> sensibilité, 31, 33<br />
extraction <strong>de</strong> lignes, 20, 21<br />
extraction multiligne, 22<br />
étape d'utilisation, 17<br />
fat, 22<br />
généralités, 15<br />
insensible, 25, 35<br />
465
D–D<br />
instruction préparée, 19<br />
interne, 29<br />
jeu <strong>de</strong> résultats, 15<br />
jeu <strong>de</strong> résultats ODBC, 298<br />
keyset, 39<br />
lecture seule, 25<br />
mise à jour, 375, 391<br />
mise à jour et suppression, 23<br />
mise à jour ODBC, 300<br />
modification visible, 30<br />
niveau d'isolement, 21<br />
ODBC, 26, 297<br />
OLE DB, 26<br />
Open Client, 390<br />
ordre, 29<br />
performances, 42, 43<br />
plate-forme, 25<br />
point <strong>de</strong> sauvegar<strong>de</strong>, 50<br />
positionnement, 20<br />
présentation, 15<br />
procédure stockée, 242<br />
sans défilement, 25, 35<br />
sensibilité, 29, 30<br />
sensibilité indéfinie, 38<br />
sensibilité non spécifiée, 38<br />
sensible, 36<br />
signet ODBC, 300<br />
statique, 35<br />
suppression, 391<br />
suppression ODBC, 300<br />
table <strong>de</strong> travail, 42<br />
tenant compte <strong>de</strong>s valeurs, 39<br />
transaction, 49<br />
unique, 25<br />
utilisation, 15, 20<br />
valeur, 29<br />
curseur à sensibilité indéfinie<br />
exemple <strong>de</strong> mise à jour, 33<br />
exemple <strong>de</strong> suppression, 31<br />
généralités, 38<br />
présentation, 30<br />
curseur avec défilement, 23<br />
généralités, 25, 39<br />
curseur avec défilement dynamique<br />
généralités, 25, 38<br />
curseur bloc, 22<br />
ODBC, 28<br />
466<br />
curseur dynamique<br />
exemple, 189<br />
généralités, 36<br />
ODBC, 26<br />
curseur en lecture seule<br />
généralités, 25<br />
curseur insensible<br />
exemple <strong>de</strong> mise à jour, 33<br />
exemple <strong>de</strong> suppression, 31<br />
généralités, 25, 35<br />
présentation, 30<br />
curseur keyset<br />
généralités, 39<br />
ODBC, 26<br />
curseur mixte<br />
ODBC, 26<br />
curseur sans défilement<br />
généralités, 25, 35<br />
curseur sensible<br />
exemple <strong>de</strong> mise à jour, 33<br />
exemple <strong>de</strong> suppression, 31<br />
généralités, 36<br />
présentation, 30<br />
curseur statique<br />
généralités, 35<br />
ODBC, 26<br />
curseur tenant compte <strong>de</strong>s valeurs<br />
exemple <strong>de</strong> mise à jour, 33<br />
exemple <strong>de</strong> suppression, 31<br />
généralités, 39<br />
présentation, 30<br />
curseur unique<br />
généralités, 25<br />
curseurs avec défilement<br />
support JDBC, 141<br />
D<br />
db_backup, fonction<br />
généralités, 245, 252<br />
DB_BACKUP_CLOSE_FILE, paramètre, 252<br />
DB_BACKUP_END, paramètre, 252
DB_BACKUP_OPEN_FILE, paramètre, 252<br />
DB_BACKUP_READ_PAGE, paramètre, 252<br />
DB_BACKUP_READ_RENAME_LOG, paramètre,<br />
252<br />
DB_BACKUP_START, paramètre, 252<br />
DB_CALLBACK_CONN_DROPPED, paramètre<br />
callback, 260<br />
DB_CALLBACK_DEBUG_MESSAGE, paramètre<br />
callback, 260<br />
DB_CALLBACK_FINISH, paramètre callback, 260<br />
DB_CALLBACK_MESSAGE, paramètre callback,<br />
261<br />
DB_CALLBACK_START, paramètre callback, 260<br />
DB_CALLBACK_WAIT, paramètre callback, 260<br />
db_cancel_request, fonction<br />
généralités, 255<br />
gestion <strong>de</strong>s requêtes, 245<br />
db_<strong>de</strong>lete_file, fonction<br />
généralités, 255<br />
db_find_engine, fonction<br />
généralités, 256<br />
db_fini, fonction<br />
généralités, 256<br />
db_fini_dll<br />
appel, 184<br />
db_get_property, fonction<br />
généralités, 256<br />
db_init, fonction<br />
généralités, 257<br />
db_init_dll<br />
appel, 184<br />
db_is_working, fonction<br />
généralités, 258<br />
gestion <strong>de</strong>s requêtes, 245<br />
db_locate_servers, fonction<br />
généralités, 258<br />
db_register_a_callback, fonction<br />
généralités, 259<br />
gestion <strong>de</strong>s requêtes, 245<br />
D–D<br />
db_start_database, fonction<br />
généralités, 261<br />
db_start_engine, fonction<br />
généralités, 262<br />
db_stop_database, fonction<br />
généralités, 263<br />
db_stop_engine, fonction<br />
généralités, 264<br />
db_string_connect, fonction<br />
généralités, 265<br />
db_string_disconnect, fonction<br />
généralités, 265<br />
db_string_ping_server, fonction<br />
généralités, 266<br />
DBBackup, fonction, 320<br />
DBChangeLogName, fonction, 320<br />
DBChangeWriteFile, fonction, 321<br />
DBCollate, fonction, 321<br />
DBCompress, fonction, 322<br />
dbcon8.dll<br />
déploiement <strong>de</strong> clients Embed<strong>de</strong>d SQL, 428<br />
déploiement <strong>de</strong> clients ODBC, 422<br />
déploiement <strong>de</strong> clients OLE DB, 420<br />
déploiement d'utilitaires <strong>de</strong> base <strong>de</strong> données, 436<br />
dbconsole, utilitaire<br />
déploiement, 431<br />
DBCreate, fonction, 322<br />
DBCreateWriteFile, fonction, 323<br />
DBCrypt, fonction, 323<br />
dbctrs8.dll<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
dbeng8<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
DBErase, fonction, 323<br />
DBExpand, fonction, 324<br />
dbextf.dll<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
467
D–D<br />
dbfile.dll<br />
déploiement <strong>de</strong> SQL Remote, 436<br />
DBInfo, fonction, 324<br />
DBInfoDump, fonction, 325<br />
DBInfoFree, fonction, 325<br />
dbinit, utilitaire<br />
Java dans la base <strong>de</strong> données, 97, 98<br />
dbipx8.dll<br />
déploiement <strong>de</strong> clients Embed<strong>de</strong>d SQL, 428<br />
déploiement <strong>de</strong> clients ODBC, 422<br />
dbjava8.dll<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
dblgen8.dll<br />
déploiement <strong>de</strong> clients Embed<strong>de</strong>d SQL, 428<br />
déploiement <strong>de</strong> clients ODBC, 422<br />
déploiement <strong>de</strong> clients OLE DB, 420<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
déploiement <strong>de</strong> SQL Remote, 436<br />
déploiement d'utilitaires <strong>de</strong> base <strong>de</strong> données, 436<br />
dblib8.dll<br />
bibliothèque d'interface, 178<br />
déploiement <strong>de</strong> clients Embed<strong>de</strong>d SQL, 428<br />
DBLicense, fonction, 326<br />
dbmapi.dll<br />
déploiement <strong>de</strong> SQL Remote, 436<br />
dbmlsync, utilitaire<br />
API C, 350<br />
création personnelle, 350<br />
dbodbc8.dll<br />
déploiement <strong>de</strong> clients ODBC, 422<br />
dbodbc8.lib<br />
bibliothèque d'importation ODBC Windows CE,<br />
280<br />
dbodbc8.so<br />
pilote ODBC UNIX, 281<br />
dboledb8.dll<br />
déploiement <strong>de</strong> clients OLE DB, 420<br />
dboledba8.dll<br />
déploiement <strong>de</strong> clients OLE DB, 420<br />
dbremote<br />
déploiement <strong>de</strong> SQL Remote, 436<br />
468<br />
dbserv8.dll<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
dbsmtp.dll<br />
déploiement <strong>de</strong> SQL Remote, 436<br />
dbsrv8<br />
déploiement <strong>de</strong> serveurs <strong>de</strong> base <strong>de</strong> données, 432<br />
DBStatusWriteFile, fonction, 326<br />
DBSynchronizeLog, fonction, 327<br />
dbtool8.dll<br />
déploiement <strong>de</strong> SQL Remote, 436<br />
déploiement d'utilitaires <strong>de</strong> base <strong>de</strong> données, 436<br />
Windows CE, 310<br />
DBTools, interface<br />
appel <strong>de</strong>s fonctions DBTools, 312<br />
arrêt, 311<br />
démarrage, 311<br />
énumération, 364<br />
fonction, 320<br />
généralités, 309<br />
introduction, 310<br />
programme exemple, 316<br />
utilisation, 311<br />
DBToolsFini, fonction, 327<br />
DBToolsInit, fonction, 328<br />
DBToolsVersion, fonction, 328<br />
dbtran_userlist_type, énumération, 365<br />
DBTranslateLog, fonction, 329<br />
DBTruncateLog, fonction, 329<br />
DBUnload, fonction, 330<br />
dbunload, utilitaire<br />
création personnelle, 357<br />
fichier d'en-tête, 357<br />
dbunload_type, énumération, 365<br />
dbupgrad, utilitaire<br />
Java dans la base <strong>de</strong> données, 97, 99<br />
DBUpgra<strong>de</strong>, fonction, 330<br />
DBValidate, fonction, 331<br />
dbvim.dll<br />
déploiement <strong>de</strong> SQL Remote, 436
dbwtsp8.dll<br />
déploiement <strong>de</strong> SQL Remote, 436<br />
déploiement d'utilitaires <strong>de</strong> base <strong>de</strong> données, 436<br />
dbxtract, utilitaire<br />
création personnelle, 357<br />
fichier d'en-tête, 357<br />
dbxtract, utilitaire <strong>de</strong> ligne <strong>de</strong> comman<strong>de</strong><br />
interface d'outils <strong>de</strong> base <strong>de</strong> données, 330<br />
DECIMAL, type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL, 197<br />
DECL_BINARY<br />
macro, 197<br />
DECL_DECIMAL<br />
macro, 197<br />
DECL_FIXCHAR<br />
macro, 197<br />
DECL_LONGBINARY<br />
macro, 197<br />
DECL_LONGVARCHAR<br />
macro, 197<br />
DECL_VARCHAR<br />
macro, 197<br />
déclaration<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
variable hôte, 196<br />
DECLARE, instruction<br />
généralités, 212<br />
définition<br />
valeurs au moyen <strong>de</strong> la zone SQLDA, 231<br />
DELETE, instruction<br />
Java dans la base <strong>de</strong> données, 112<br />
positionnée, 23<br />
dénomination <strong>de</strong>s fichiers<br />
conventions, 410<br />
déploiement<br />
application, 420<br />
base <strong>de</strong> données, 433<br />
base <strong>de</strong> données embarquée, 435<br />
base <strong>de</strong> données en lecture seule, 433<br />
base <strong>de</strong> données et application, 405<br />
base <strong>de</strong> données sur CD-ROM, 433<br />
client JDBC, 429<br />
Embed<strong>de</strong>d SQL, 427<br />
emplacement <strong>de</strong>s fichiers, 409<br />
fichier d'écriture, 412<br />
fournisseur OLE DB, 420<br />
généralités, 405<br />
installation silencieuse, 416<br />
InstallShield, 414<br />
Interactive SQL, 431<br />
Java dans la base <strong>de</strong> données, 432<br />
jConnect, 429<br />
modèle, 406<br />
ODBC, 421<br />
Open Client, 430<br />
outil d'administration, 431<br />
paramètre <strong>de</strong> registre, 422, 424<br />
paramètre ODBC, 422, 424<br />
passerelle JDBC-ODBC, 429<br />
pilote ODBC, 422<br />
présentation, 406<br />
serveur <strong>de</strong> base <strong>de</strong> données, 432<br />
serveur <strong>de</strong> base <strong>de</strong> données personnel, 435<br />
serveur <strong>de</strong> synchronisation MobiLink, 416<br />
SQL Remote, 436<br />
<strong>Sybase</strong> Central, 431<br />
System Management <strong>Server</strong>, 418<br />
utilitaire dbconsole, 431<br />
DESCRIBE, instruction<br />
champ SQLDA, 228<br />
champ sqllen, 230<br />
champ sqltype, 230<br />
généralités, 224<br />
jeux <strong>de</strong> résultats multiples, 244<br />
<strong>de</strong>scripteur, 45<br />
allocation, 286<br />
ODBC, 285<br />
<strong>de</strong>scription<br />
jeu <strong>de</strong> résultats, 45<br />
<strong>de</strong>structeur<br />
Java, 70<br />
détection et résolution <strong>de</strong>s problèmes<br />
Java dans la base <strong>de</strong> données, 121<br />
position du curseur, 21<br />
DISTINCT, mot-clé<br />
Java dans la base <strong>de</strong> données, 117<br />
D–D<br />
469
E–E<br />
distinction majuscules/minuscules<br />
Java dans la base <strong>de</strong> données et SQL, 76<br />
type <strong>de</strong> données Java dans la base <strong>de</strong> données,<br />
106<br />
Distributed Transaction Coordinator<br />
architecture à trois niveaux, 397<br />
distributeur <strong>de</strong> ressources<br />
architecture à trois niveaux, 396<br />
DLL<br />
zones SQLCA multiples, 209<br />
DLL <strong>de</strong> langue<br />
comment l'obtenir, 411<br />
documentation<br />
conventions, xi<br />
SQL <strong>Anywhere</strong> Studio, viii<br />
DT_BIGINT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_BINARY<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 193<br />
DT_BIT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_DATE<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_DECIMAL<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_DOUBLE<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_FIXCHAR<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 193<br />
DT_FLOAT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_INT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_LONGBINARY<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 194<br />
DT_LONGVARCHAR<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 193<br />
DT_SMALLINT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_STRING, type <strong>de</strong> données, 268<br />
470<br />
DT_TIME<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_TIMESTAMP<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 193<br />
DT_TIMESTAMP_STRUCT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 194<br />
DT_TINYINT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_UNSINT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_UNSSMALLINT<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 192<br />
DT_VARCHAR<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 193<br />
DT_VARIABLE<br />
type <strong>de</strong> données Embed<strong>de</strong>d SQL, 195<br />
DTC<br />
architecture à trois niveaux, 397<br />
durée<br />
classe Java dans la base <strong>de</strong> données, 78<br />
DYNAMIC SCROLL, curseur<br />
détection et résolution <strong>de</strong>s problèmes, 21<br />
Embed<strong>de</strong>d SQL, 27<br />
E<br />
EA<strong>Server</strong><br />
architecture à trois niveaux, 397<br />
attribut <strong>de</strong> transaction d'un composant, 402<br />
coordinateur <strong>de</strong> transactions, 401<br />
transaction distribuée, 401<br />
Embed<strong>de</strong>d SQL<br />
autorisation, 249<br />
bibliothèque d'importation, 181<br />
chaîne <strong>de</strong> caractères, 249<br />
curseur, 27, 186, 212<br />
curseur dynamique, 189<br />
développement, 178<br />
fichier d'en-tête, 181<br />
fonction, 251<br />
fonction <strong>de</strong> sauvegar<strong>de</strong>, 245<br />
généralités, 177<br />
instruction dynamique, 221
instruction SQL, 10<br />
instruction statique, 221<br />
lecture <strong>de</strong> données, 211<br />
mo<strong>de</strong> autocommit, 47<br />
numéro <strong>de</strong> ligne, 249<br />
présentation, 4<br />
procédure stockée, 241<br />
processus <strong>de</strong> compilation et <strong>de</strong> liaison, 179<br />
programme exemple, 182<br />
récapitulatif <strong>de</strong>s comman<strong>de</strong>s, 270<br />
sauvegar<strong>de</strong> en ligne, 245<br />
type <strong>de</strong> curseur, 25<br />
variable hôte, 196<br />
entité<br />
Java dans la base <strong>de</strong> données, 130<br />
environnement d'exécution<br />
Java dans la base <strong>de</strong> données, 94<br />
erreur<br />
champ SQLCA sqlco<strong>de</strong>, 205<br />
co<strong>de</strong>, 205<br />
SQLCODE, 205<br />
erreur <strong>de</strong> procédure introuvable<br />
Java dans la base <strong>de</strong> données, 121<br />
métho<strong>de</strong> Java, 165<br />
erreur d'overflow<br />
conversion <strong>de</strong>s types <strong>de</strong> données, 387<br />
espace disque<br />
Java dans la base <strong>de</strong> données, 127<br />
espace nom<br />
Java dans la base <strong>de</strong> données, 138<br />
exception<br />
Java, 70<br />
EXEC SQL<br />
développement Embed<strong>de</strong>d SQL, 183<br />
EXECUTE, instruction, 221<br />
procédure stockée dans Embed<strong>de</strong>d SQL, 241<br />
executeQuery, métho<strong>de</strong><br />
généralités, 166<br />
executeUpdate<br />
métho<strong>de</strong> JDBC, 14<br />
executeUpdate, métho<strong>de</strong> JDBC<br />
généralités, 163<br />
exemple<br />
application Embed<strong>de</strong>d SQL, 186<br />
curseur statique dans Embed<strong>de</strong>d SQL, 189<br />
Embed<strong>de</strong>d SQL, 187<br />
esqldll.c, 184<br />
ODBC, 283<br />
programme DBTools, 316<br />
service Windows, 284<br />
extraction<br />
curseur, 21<br />
curseur avec défilement, 23<br />
limites, 20<br />
multiligne, 22, 215<br />
objet, 171<br />
ODBC, 298<br />
SQLDA, 233<br />
extraction étendue, 22<br />
généralités, 215<br />
É<br />
égalité entre objets<br />
Java dans la base <strong>de</strong> données, 116<br />
énumération<br />
interface DBTools, 364<br />
énumération du mo<strong>de</strong> <strong>de</strong> sortie, 364<br />
énumération du remplissage avec <strong>de</strong>s blancs, 364<br />
F<br />
fat, curseur, 22<br />
FETCH, instruction<br />
extraction étendue, 215<br />
extraction multiligne, 215<br />
généralités, 211, 212<br />
requête dynamique, 224<br />
fichier<br />
conventions <strong>de</strong> dénomination, 410<br />
emplacement <strong>de</strong> déploiement, 409<br />
fichier <strong>de</strong> réponse<br />
définition, 416<br />
fichier d'écriture<br />
déploiement, 412<br />
É–F<br />
471
G–I<br />
fichier d'en-tête<br />
Embed<strong>de</strong>d SQL, 181<br />
ODBC, 278<br />
fill_s_sqlda, fonction<br />
généralités, 266<br />
fill_sqlda, fonction<br />
généralités, 267<br />
FIXCHAR, type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL, 197<br />
fonction<br />
appel <strong>de</strong>s fonctions DBTools, 312<br />
callback, 245<br />
DBTools, 320<br />
Embed<strong>de</strong>d SQL, 251<br />
fonction d'agrégat<br />
Java dans la base <strong>de</strong> données, 117<br />
fonction <strong>de</strong> bibliothèque<br />
Embed<strong>de</strong>d SQL, 251<br />
fonctionnalité<br />
support, 392<br />
ForceStart [FORCESTART], paramètre <strong>de</strong><br />
connexion<br />
db_start_engine, 263<br />
format<br />
objet Java dans la base <strong>de</strong> données, 127<br />
forums<br />
support technique, xv<br />
free_filled_sqlda, fonction<br />
généralités, 267<br />
free_sqlda, fonction<br />
généralités, 267<br />
free_sqlda_noind, fonction<br />
généralités, 267<br />
G<br />
gestion<br />
erreur ODBC, 304<br />
gestion <strong>de</strong> la sécurité Java<br />
présentation, 126<br />
472<br />
gestionnaire <strong>de</strong> ressources<br />
architecture à trois niveaux, 396<br />
généralités, 394<br />
getConnection, métho<strong>de</strong><br />
instance, 160<br />
getObject, métho<strong>de</strong><br />
utilisation, 173<br />
GRANT, instruction<br />
JDBC, 170<br />
GROUP BY, clause<br />
Java dans la base <strong>de</strong> données, 117<br />
guillemet<br />
chaîne Java dans la base <strong>de</strong> données, 76<br />
I<br />
icône<br />
utilisation dans les manuels, xii<br />
i<strong>de</strong>ntificateur<br />
fonction SQL_needs_quotes, 268<br />
guillemets nécessaires, 268<br />
import, instruction<br />
jConnect, 148<br />
IMPORT, instruction<br />
Java, 69<br />
Java dans la base <strong>de</strong> données, 79<br />
INCLUDE, instruction<br />
SQLCA, 205<br />
in<strong>de</strong>x<br />
Java dans la base <strong>de</strong> données, 117, 127, 134<br />
informations<br />
documentation, xv<br />
obtention, xv<br />
INOUT, paramètre<br />
Java dans la base <strong>de</strong> données, 124<br />
INSENSITIVE, curseur<br />
Embed<strong>de</strong>d SQL, 27<br />
INSERT, instruction<br />
insertion étendue, 215<br />
insertion multiligne, 215<br />
Java dans la base <strong>de</strong> données, 109
JDBC, 163, 164<br />
objet, 169<br />
performances, 12<br />
insertion<br />
étendue, 215<br />
multiligne, 215<br />
insertion étendue, 215<br />
insertion multiligne, 215<br />
INSTALL, instruction<br />
généralités, 74<br />
utilisation, 102, 103<br />
version <strong>de</strong> classe, 129<br />
installation<br />
classe Java dans une base <strong>de</strong> données, 101, 102<br />
fichier JAR dans une base <strong>de</strong> données, 103<br />
silencieuse, 416<br />
InstallShield<br />
déploiement d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, 414<br />
installation silencieuse, 416<br />
instance<br />
classe Java, 68<br />
instance, champ<br />
généralités, 65<br />
instanciation<br />
définition, 68<br />
instruction<br />
COMMIT, 49<br />
DELETE positionnée, 23<br />
INSERT, 12<br />
PUT, 23<br />
ROLLBACK, 49<br />
SQL, 389<br />
UPDATE positionnée, 23<br />
instruction préparée<br />
curseur, 19<br />
JDBC, 167<br />
objet Java dans la base <strong>de</strong> données, 111<br />
ODBC, 295<br />
Open Client, 389<br />
paramètre <strong>de</strong> liaison, 13<br />
suppression, 13<br />
utilisation, 12<br />
Interactive SQL<br />
déploiement, 431<br />
interface<br />
Java, 70<br />
J<br />
Jaguar<br />
EA<strong>Server</strong>, 401<br />
JAR, fichier<br />
ajout, 103<br />
installation, 101, 103<br />
Java, 69<br />
mise à jour, 104<br />
suppression, 112<br />
version, 104<br />
Java<br />
bloc catch, 71<br />
bloc finally, 71<br />
bloc try, 71<br />
classe, 68<br />
constructeur, 69<br />
<strong>de</strong>structeur, 70<br />
interface, 70<br />
JDBC, 140<br />
requête sur un objet, 171<br />
traitement <strong>de</strong>s erreurs, 70<br />
Java 2<br />
version supportée, 73<br />
Java dans base <strong>de</strong> données<br />
insertion, 109<br />
présentation, 92<br />
J–J<br />
Java dans la base <strong>de</strong> données<br />
API, 58, 73<br />
caractère d'échappement, 78<br />
champ, 64<br />
classe <strong>de</strong> compilation, 62<br />
classe d'exécution, 95<br />
classe supportée, 59<br />
colonne calculée, 134<br />
comparaison d'objets, 116<br />
conception d'une base <strong>de</strong> données, 130<br />
configuration d'une base <strong>de</strong> données, 95, 97, 99<br />
création <strong>de</strong> colonnes, 106<br />
déchargement et rechargement d'objet, 129<br />
déploiement, 432<br />
didacticiel, 82<br />
durée, 78<br />
environnement d'exécution, 73, 94<br />
473
J–J<br />
espace nom, 138<br />
FAQ, 55<br />
fonctionnalités clés, 55<br />
gestion <strong>de</strong> la sécurité, 125<br />
in<strong>de</strong>x, 117, 127<br />
insertion d'objet, 111<br />
installation <strong>de</strong> classes, 101<br />
introduction, 52, 62<br />
machine virtuelle, 55, 56, 138<br />
métho<strong>de</strong>, 64<br />
métho<strong>de</strong> compareTo, 117<br />
métho<strong>de</strong> main, 77, 120<br />
mise à jour, 112<br />
mise à jour <strong>de</strong> valeur, 111<br />
NULL, 106<br />
objet, 63<br />
performances, 127<br />
plate-forme supportée, 57<br />
problème <strong>de</strong> mémoire, 137<br />
réplication d'objet, 129<br />
requête, 114<br />
stockage, 127<br />
suppression <strong>de</strong> classe, 112<br />
suppression <strong>de</strong> ligne, 112<br />
table exemple, 92<br />
taille du segment <strong>de</strong> mémoire, 138<br />
type <strong>de</strong> données, 106<br />
utilisation <strong>de</strong> la documentation, 53<br />
valeur par défaut, 106<br />
version, 73<br />
version <strong>de</strong> classe, 128<br />
Java, package<br />
classe d'exécution, 95<br />
Java, procédure stockée<br />
généralités, 122<br />
JAVA_HEAP_SIZE, option, 138<br />
JAVA_NAMESPACE_SIZE, option<br />
utilisation, 138<br />
jcatalog.sql, fichier<br />
jConnect, 148<br />
jConnect<br />
base <strong>de</strong> données, 148<br />
chargement, 149<br />
choix d'un pilote JDBC, 141<br />
connexion, 154, 158<br />
déploiement <strong>de</strong> clients JDBC, 429<br />
généralités, 147<br />
objet système, 148<br />
474<br />
package, 148<br />
URL, 149<br />
variable d'environnement CLASSPATH, 147<br />
version fournie, 147<br />
JDBC<br />
accès aux données, 162<br />
autocommit, 160<br />
autorisation, 170<br />
classe d'exécution, 95<br />
classe non standard, 142, 143<br />
co<strong>de</strong> <strong>de</strong> connexion, 154<br />
connexion, 145, 154<br />
connexion à une base <strong>de</strong> données, 150<br />
connexion cliente, 154<br />
connexion côté serveur, 158<br />
côté client, 145<br />
côté serveur, 145<br />
déploiement <strong>de</strong> clients JDBC, 429<br />
exemple, 140, 154<br />
élément requis, 140<br />
généralités, 140<br />
instruction INSERT, 163, 164<br />
instruction préparée, 167<br />
instruction SELECT, 166<br />
instruction SQL, 10<br />
jConnect, 147<br />
mo<strong>de</strong> autocommit, 47<br />
présentation, 5<br />
présentation <strong>de</strong>s applications, 141<br />
type <strong>de</strong> curseur, 25<br />
utilisation, 140<br />
valeurs <strong>de</strong> connexion par défaut, 160<br />
version, 73, 142, 143<br />
version 2.0, 142, 143<br />
JDBCExamples, classe<br />
généralités, 162<br />
JDBCExamples.java, fichier, 140<br />
j<strong>de</strong>mo.sql<br />
table exemple, 92<br />
JDK<br />
définition, 58<br />
version, 73, 95<br />
jeu <strong>de</strong> résultat<br />
procédure stockée, 242<br />
jeu <strong>de</strong> résultats<br />
curseur, 15<br />
extraction ODBC, 298
métadonnées, 45<br />
métho<strong>de</strong> Java dans la base <strong>de</strong> données, 122<br />
objet Recordset d'ADO, 373, 375<br />
ODBC, 297, 302<br />
Open Client, 391<br />
procédure stockée Java dans la base <strong>de</strong> données,<br />
122<br />
utilisation, 20<br />
jeux <strong>de</strong> résultats multiples<br />
instruction DESCRIBE, 244<br />
L<br />
lancement, base <strong>de</strong> données<br />
utilisation <strong>de</strong> jConnect, 150<br />
langage <strong>de</strong> <strong>programmation</strong> C<br />
type <strong>de</strong> données, 197<br />
langue<br />
nom <strong>de</strong> fichier, 410<br />
lecture<br />
Embed<strong>de</strong>d SQL, 211<br />
lecture <strong>de</strong> tableau<br />
généralités, 215<br />
lecture seule<br />
déploiement <strong>de</strong> bases <strong>de</strong> données, 433<br />
length, champ SQLDA<br />
généralités, 228, 229<br />
ligne <strong>de</strong> comman<strong>de</strong>, utilitaire<br />
déploiement, 436<br />
logiciel<br />
co<strong>de</strong> <strong>de</strong> retour, 313<br />
LONG BINARY, type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL, 197, 235<br />
envoi dans Embed<strong>de</strong>d SQL, 238<br />
récupération dans Embed<strong>de</strong>d SQL, 236<br />
LONG VARCHAR, type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL, 197, 235<br />
envoi dans Embed<strong>de</strong>d SQL, 238<br />
récupération dans Embed<strong>de</strong>d SQL, 236<br />
longueur <strong>de</strong> ligne<br />
résultat du préprocesseur SQL, 248<br />
M<br />
machine virtuelle<br />
arrêt, 138<br />
démarrage, 138<br />
macro<br />
_SQL_OS_NETWARE, 184<br />
_SQL_OS_UNIX, 184<br />
_SQL_OS_WINNT, 184<br />
marque <strong>de</strong> réservation<br />
SQL dynamique, 221<br />
MAX, fonction<br />
Java dans la base <strong>de</strong> données, 117<br />
mémoire<br />
Java dans la base <strong>de</strong> données, 137<br />
message<br />
rappel, 261<br />
serveur, 261<br />
message d'erreur<br />
fonction Embed<strong>de</strong>d SQL, 268<br />
métho<strong>de</strong><br />
>>, 75<br />
classe, 65<br />
déclaration, 66<br />
instance, 65<br />
Java dans la base <strong>de</strong> données, 64<br />
opérateur point, 74<br />
privée, 69<br />
protégée, 69<br />
publique, 69<br />
statique, 65<br />
type <strong>de</strong> renvoi void, 122<br />
métho<strong>de</strong> <strong>de</strong> classe<br />
généralités, 65<br />
métho<strong>de</strong> d'instance<br />
généralités, 65<br />
métho<strong>de</strong> main<br />
Java dans la base <strong>de</strong> données, 77, 120<br />
métho<strong>de</strong> statique<br />
généralités, 65<br />
Microsoft Transaction <strong>Server</strong><br />
architecture à trois niveaux, 397<br />
L–M<br />
475
N–O<br />
Microsoft Visual C++<br />
support, 180<br />
MIN, fonction<br />
Java dans la base <strong>de</strong> données, 117<br />
mise à jour<br />
curseur, 375<br />
mise à jour <strong>de</strong> base <strong>de</strong> données, assistant<br />
configuration <strong>de</strong> la base <strong>de</strong> données pour Java, 99<br />
mise à jour positionnée, 23<br />
généralités, 21<br />
mlxtract, utilitaire<br />
création personnelle, 357<br />
fichier d'en-tête, 357<br />
mo<strong>de</strong> chaîné<br />
contrôle, 47<br />
mise en oeuvre, 48<br />
transaction, 47<br />
mo<strong>de</strong> commit manuel<br />
contrôle, 47<br />
mise en oeuvre, 48<br />
transaction, 47<br />
mo<strong>de</strong> non chaîné<br />
contrôle, 47<br />
mise en oeuvre, 48<br />
transaction, 47<br />
modificateur d'accès<br />
Java, 69<br />
modification visible<br />
curseur, 30<br />
mot réservé<br />
SQL et Java dans la base <strong>de</strong> données, 79<br />
mot-clé<br />
SQL et Java dans la base <strong>de</strong> données, 79<br />
MSDASQL<br />
fournisseur OLE DB, 368<br />
multiples<br />
jeu <strong>de</strong> résultats ODBC, 302<br />
476<br />
N<br />
name, champ SQLDA<br />
généralités, 228<br />
NetWare<br />
programme Embed<strong>de</strong>d SQL, 185<br />
niveau d'isolement<br />
application, 49<br />
curseur, 21<br />
sensibilité du curseur, 44<br />
NLM<br />
programme Embed<strong>de</strong>d SQL, 185<br />
NO SCROLL, curseur<br />
Embed<strong>de</strong>d SQL, 27<br />
nom <strong>de</strong> fichier<br />
langue, 410<br />
numéro <strong>de</strong> version, 410<br />
norme<br />
SQLJ, 52<br />
norme SQLJ<br />
généralités, 52<br />
ntodbc.h, 278<br />
NULL<br />
Java dans la base <strong>de</strong> données, 106<br />
SQL dynamique, 226<br />
variable indicateur, 201<br />
numéro <strong>de</strong> ligne<br />
préprocesseur SQL, 249<br />
numéro <strong>de</strong> version<br />
nom <strong>de</strong> fichier, 410<br />
O<br />
objet<br />
déchargement et rechargement, 129<br />
extraction, 169<br />
format <strong>de</strong> stockage, 105<br />
insertion, 169<br />
Java dans la base <strong>de</strong> données, 63<br />
réplication, 129<br />
requête, 171<br />
type, 63<br />
version <strong>de</strong> classe, 128
objet Recordset<br />
ADO, 375<br />
ODBC<br />
application exemple, 287<br />
application multithread, 291<br />
bibliothèque d'importation, 278<br />
compatibilité, 277<br />
compatibilité <strong>de</strong>scendante, 277<br />
conformité, 276<br />
curseur, 26, 297<br />
déploiement, 421<br />
déploiement du pilote, 422<br />
<strong>de</strong>scripteur, 285<br />
<strong>de</strong>scripteur <strong>de</strong> connexion, 285<br />
<strong>de</strong>scripteur d'environnement, 285<br />
<strong>de</strong>scripteur d'instruction, 285<br />
développement UNIX, 280, 282<br />
entrée <strong>de</strong> registre, 425<br />
exemple <strong>de</strong> programme, 283<br />
fichier d'en-tête, 278<br />
instruction préparée, 295<br />
instruction SQL, 10<br />
introduction à la <strong>programmation</strong>, 2<br />
jeu <strong>de</strong> résultats, 302<br />
jeux <strong>de</strong> résultats multiples, 302<br />
liaison, 278<br />
mo<strong>de</strong> autocommit, 47<br />
présentation, 276<br />
procédure stockée, 302<br />
<strong>programmation</strong>, 275<br />
sans gestionnaire <strong>de</strong> pilotes, 282<br />
source <strong>de</strong> données, 425<br />
type <strong>de</strong> curseur, 25<br />
UNIX, 280, 281<br />
vérification d'erreurs, 304<br />
version supportée, 276<br />
Windows CE, 279, 280<br />
ODBC, paramètre<br />
déploiement, 422, 424<br />
odbc.h, 278<br />
OLE DB<br />
<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, 368<br />
curseur, 26, 375<br />
déploiement, 420<br />
déploiement <strong>de</strong> fournisseurs, 420<br />
généralités, 368<br />
interface supportée, 378<br />
introduction à la <strong>programmation</strong>, 3<br />
mise à jour, 375<br />
ODBC, 368<br />
plate-forme supportée, 368<br />
type <strong>de</strong> curseur, 25<br />
OLE, transaction<br />
architecture à trois niveaux, 396<br />
Open Client<br />
compatibilité <strong>de</strong>s types <strong>de</strong> données, 387<br />
configuration requise, 386<br />
déploiement d'applications Open Client, 430<br />
instruction SQL, 10<br />
interface, 385<br />
intervalles <strong>de</strong> types <strong>de</strong> données, 387<br />
limites, 392<br />
limites d'<strong>Adaptive</strong> <strong>Server</strong> <strong>Anywhere</strong>, 392<br />
mo<strong>de</strong> autocommit, 47<br />
présentation, 6<br />
SQL, 389<br />
type <strong>de</strong> curseur, 25<br />
type <strong>de</strong> données, 387<br />
OPEN, instruction<br />
généralités, 212<br />
opérateur point<br />
Java et SQL, 74, 75<br />
option -gn<br />
thread, 121<br />
option QUOTED_IDENTIFIER<br />
définition jConnect, 151<br />
options <strong>de</strong> base <strong>de</strong> données<br />
défintion pour jConnect, 151<br />
ORDER BY, clause<br />
Java dans la base <strong>de</strong> données, 117<br />
OUT, paramètre<br />
Java dans la base <strong>de</strong> données, 124<br />
O–O<br />
outil <strong>de</strong> base <strong>de</strong> données, interface<br />
dbxtract, 330<br />
énumération a_validate_type, 366<br />
énumération dbtran_userlist_type, 365<br />
énumération dbunload_type, 365<br />
énumération du mo<strong>de</strong> <strong>de</strong> sortie, 364<br />
énumération du remplissage avec <strong>de</strong>s blancs, 364<br />
fonction DBBackup, 320<br />
fonction DBChangeLogName, 320<br />
fonction DBChangeWriteFile, 321<br />
fonction DBCollate, 321<br />
fonction DBCompress, 322<br />
477
P–P<br />
P<br />
478<br />
fonction DBCreate, 322<br />
fonction DBCreateWriteFile, 323<br />
fonction DBCrypt, 323<br />
fonction DBErase, 323<br />
fonction DBExpand, 324<br />
fonction DBInfo, 324<br />
fonction DBInfoDump, 325<br />
fonction DBInfoFree, 325<br />
fonction DBLicense, 326<br />
fonction DBStatusWriteFile, 326<br />
fonction DBToolsFini, 327<br />
fonction DBToolsInit, 328<br />
fonction DBToolsVersion, 328<br />
fonction DBTranslateLog, 329<br />
fonction DBTruncateLog, 329<br />
fonction DBUnload, 330<br />
fonction DBUpgra<strong>de</strong>, 330<br />
fonction DBValidate, 331<br />
généralités, 309<br />
structure a_backup_db, 332<br />
structure a_change_log, 334<br />
structure a_compress_db, 336<br />
structure a_compress_stats, 337<br />
structure a_create_db, 338<br />
structure a_crypt_db, 340<br />
structure a_db_collation, 341<br />
structure a_db_info, 343<br />
structure a_dblic_info, 346<br />
structure a_dbtools_info, 347<br />
structure a_name, 349<br />
structure a_stats_line, 349<br />
structure a_sync_db, 350<br />
structure a_syncpub, 352<br />
structure a_sysinfo, 352<br />
structure a_table_info, 353<br />
structure a_translate_log, 354<br />
structure a_truncate_log, 356<br />
structure a_validate_db, 360<br />
structure a_writefile, 361<br />
structure an_erase_db, 347<br />
structure an_expand_db, 348<br />
structure an_unload_db, 357<br />
structure an_upgra<strong>de</strong>_db, 359<br />
package<br />
installation, 103<br />
Java, 69<br />
Java dans la base <strong>de</strong> données, 79<br />
jConnect, 148<br />
paramètre <strong>de</strong> liaison<br />
instruction préparée, 13<br />
passerelle JDBC-ODBC<br />
choix d'un pilote JDBC, 141<br />
connexion, 152<br />
déploiement <strong>de</strong> clients JDBC, 429<br />
fichiers requis, 152<br />
utilisation, 152<br />
performance<br />
JDBC, 167<br />
performances<br />
curseur, 42, 43<br />
instruction préparée, 12, 295<br />
pilotes JDBC, 141<br />
valeur Java dans la base <strong>de</strong> données, 127<br />
pilote ODBC<br />
UNIX, 281<br />
pilotes JDBC<br />
choix, 141<br />
comptabilité, 141<br />
performances, 141<br />
plate-forme<br />
curseur, 25<br />
plate-forme supportée<br />
Java dans la base <strong>de</strong> données, 57<br />
OLE DB, 368<br />
point <strong>de</strong> sauvegar<strong>de</strong><br />
curseur, 50<br />
point d'entrée<br />
appel <strong>de</strong>s fonctions DBTools, 312<br />
point d'entrée <strong>de</strong> DLL, 251<br />
portée<br />
Java, 69<br />
position du curseur<br />
détection et résolution <strong>de</strong>s problèmes, 21<br />
préextraction<br />
curseur, 43<br />
extraction multiligne, 22<br />
performances du curseur, 42
PREFETCH, option<br />
curseur, 43<br />
préparation<br />
commit, 397<br />
PREPARE TRANSACTION, instruction<br />
Open Client, 392<br />
PREPARE, instruction, 221<br />
PreparedStatement, classe<br />
métho<strong>de</strong> setObject, 111<br />
PreparedStatement, interface<br />
généralités, 167<br />
prepareStatement, métho<strong>de</strong>, 14<br />
préprocesseur<br />
exécution, 180<br />
généralités, 178<br />
préprocesseur SQL<br />
exécution, 180<br />
généralités, 247<br />
ligne <strong>de</strong> comman<strong>de</strong>, 247<br />
println, métho<strong>de</strong><br />
Java dans la base <strong>de</strong> données, 77<br />
procédure<br />
Embed<strong>de</strong>d SQL, 241<br />
jeu <strong>de</strong> résultats, 242<br />
ODBC, 302<br />
procédure d'environnement système sp_tsql_<br />
définition <strong>de</strong>s options pour jConnect, 151<br />
procédure stockée<br />
création dans Embed<strong>de</strong>d SQL, 241<br />
exécution dans Embed<strong>de</strong>d SQL, 241<br />
Java dans la base <strong>de</strong> données, 122<br />
jeu <strong>de</strong> résultats, 242<br />
paramètre INOUT et Java, 124<br />
paramètre OUT et Java, 124<br />
procédure stockée Java<br />
exemple, 123<br />
procédure stockée spt_mda<br />
définition <strong>de</strong>s options pour jConnect, 151<br />
processus <strong>de</strong> compilation et <strong>de</strong> liaison, 179<br />
<strong>programmation</strong> orientée objet<br />
Java dans la base <strong>de</strong> données, 68<br />
style, 81<br />
programme d'installation<br />
déploiement, 407<br />
programme setup<br />
installation silencieuse, 416<br />
propriété<br />
fonction db_get_property, 256<br />
propriété <strong>de</strong> base <strong>de</strong> données<br />
fonction db_get_property, 256<br />
protégé<br />
Java, 69<br />
PUT, instruction, 23<br />
insertion étendue, 215<br />
insertion multiligne, 215<br />
PUT, opération, 23<br />
R<br />
rappel<br />
DB_CALLBACK_CONN_DROPPED, 260<br />
Recordset, objet<br />
ADO, 373<br />
récupération<br />
ODBC, 298<br />
registre<br />
déploiement, 422, 424<br />
ODBC, 425<br />
réinscription<br />
transaction distribuée, 396<br />
REMOTEPWD, paramètre, 150<br />
remplissage <strong>de</strong> blancs<br />
chaîne dans Embed<strong>de</strong>d SQL, 192<br />
réplication<br />
objet Java dans la base <strong>de</strong> données, 129<br />
reprise<br />
transaction distribuée, 400<br />
requête<br />
annulation, 255<br />
Embed<strong>de</strong>d SQL, 245<br />
Java dans la base <strong>de</strong> données, 114<br />
JDBC, 166<br />
R–R<br />
479
S–S<br />
ligne unique, 211<br />
objet Recordset d’ADO, 373, 375<br />
requête multiligne<br />
curseur, 212<br />
ROLLBACK TO SAVEPOINT, instruction, 50<br />
curseur, 50<br />
ROLLBACK, instruction<br />
curseur, 49<br />
rt.jar<br />
classe d'exécution, 95<br />
S<br />
sauvegar<strong>de</strong><br />
exemple DBTools, 316<br />
fonction DBTools DBBackup, 320<br />
SCROLL, curseur<br />
Embed<strong>de</strong>d SQL, 27<br />
section <strong>de</strong> déclaration<br />
généralités, 196<br />
sécurité<br />
Java dans la base <strong>de</strong> données, 125, 126<br />
SecurityManager, classe<br />
généralités, 125, 126<br />
SELECT, instruction<br />
dynamique, 224<br />
Java dans la base <strong>de</strong> données, 114<br />
JDBC, 166<br />
ligne unique, 211<br />
objet, 169<br />
sensibilité<br />
curseur, 29, 30<br />
exemple <strong>de</strong> mise à jour, 33<br />
exemple <strong>de</strong> suppression, 31<br />
niveau d'isolement, 44<br />
SENSITIVE, curseur<br />
Embed<strong>de</strong>d SQL, 27<br />
sérialisation<br />
informatique distribuée, 173<br />
objet, 172<br />
objet <strong>de</strong> table, 105<br />
objet Java dans la base <strong>de</strong> données, 127<br />
480<br />
serveur<br />
localisation, 266<br />
serveur <strong>de</strong> base <strong>de</strong> données<br />
déploiement, 432<br />
fonction, 265<br />
serveur <strong>de</strong> synchronisation MobiLink<br />
déploiement, 416<br />
serveur personnel<br />
déploiement, 435<br />
service<br />
co<strong>de</strong> exemple, 191, 284<br />
service Windows<br />
co<strong>de</strong> exemple, 191<br />
setAutocommit, métho<strong>de</strong><br />
généralités, 160<br />
setObject, métho<strong>de</strong><br />
utilisation, 173<br />
signet, 28<br />
curseur ODBC, 300<br />
sortie standard<br />
Java dans la base <strong>de</strong> données, 77<br />
SQL<br />
application, 10<br />
application ADO, 10<br />
application Embed<strong>de</strong>d SQL, 10<br />
application JDBC, 10<br />
application ODBC, 10<br />
application Open Client, 10<br />
SQL <strong>Anywhere</strong> Studio<br />
documentation, viii<br />
SQL dynamique<br />
généralités, 221<br />
SQLDA, 226<br />
SQL Remote<br />
déploiement, 436<br />
objet Java dans la base <strong>de</strong> données, 129<br />
SQL statique<br />
généralités, 221<br />
SQL/92<br />
préprocesseur SQL, 248<br />
SQL_ATTR_MAX_LENGTH, attribut<br />
généralités, 298
SQL_CALLBACK<br />
déclaration <strong>de</strong> type, 259<br />
SQL_CALLBACK_PARM<br />
déclaration <strong>de</strong> type, 259<br />
SQL_ERROR<br />
co<strong>de</strong> <strong>de</strong> retour ODBC, 304<br />
SQL_INVALID_HANDLE<br />
co<strong>de</strong> <strong>de</strong> retour ODBC, 304<br />
SQL_NEED_DATA<br />
co<strong>de</strong> <strong>de</strong> retour ODBC, 304<br />
sql_needs_quotes, fonction<br />
généralités, 268<br />
SQL_NO_DATA_FOUND<br />
co<strong>de</strong> <strong>de</strong> retour ODBC, 304<br />
SQL_SUCCESS<br />
co<strong>de</strong> <strong>de</strong> retour ODBC, 304<br />
SQL_SUCCESS_WITH_INFO<br />
co<strong>de</strong> <strong>de</strong> retour ODBC, 304<br />
SQL92<br />
préprocesseur SQL, 248<br />
SQLAllocHandle, fonction ODBC<br />
généralités, 285, 292<br />
paramètres <strong>de</strong> liaison, 293<br />
utilisation, 286<br />
SQLBindCol, fonction ODBC<br />
généralités, 297, 298<br />
SQLBindParameter<br />
fonction ODBC, 14<br />
SQLBindParameter, fonction ODBC<br />
généralités, 293<br />
instruction préparée, 295<br />
procédures stockées, 302<br />
SQLBrowseConnect, fonction ODBC<br />
généralités, 288<br />
SQLCA<br />
champ, 205<br />
généralités, 205<br />
longueur, 205<br />
modification, 208<br />
threads, 208<br />
zones multiples, 208, 209<br />
sqlcabc, champ SQLCA<br />
généralités, 205<br />
sqlcaid, champ SQLCA<br />
généralités, 205<br />
sqlco<strong>de</strong>, champ SQLCA<br />
généralités, 205<br />
SQLConnect, fonction ODBC<br />
généralités, 288<br />
SQLCOUNT<br />
élément <strong>de</strong> champ SQLCA, 207<br />
sqld, champ SQLDA<br />
généralités, 227<br />
SQLDA<br />
allocation, 251<br />
chaînes, 267<br />
champ sqllen, 229<br />
<strong>de</strong>scripteur, 46<br />
généralités, 221, 226<br />
libération, 266<br />
remplissage, 267<br />
variable hôte, 228<br />
sqlda_storage, fonction<br />
généralités, 268<br />
sqlda_string_length, fonction<br />
généralités, 268<br />
sqldabc, champ SQLDA<br />
généralités, 227<br />
sqldaif, champ SQLDA<br />
généralités, 227<br />
sqldata, champ SQLDA<br />
généralités, 228<br />
sql<strong>de</strong>f.h<br />
type <strong>de</strong> données, 192<br />
SQLDriverConnect, fonction ODBC<br />
généralités, 288<br />
sqlerrd, champ SQLCA<br />
généralités, 206<br />
sqlerrmc, champ SQLCA<br />
généralités, 206<br />
sqlerrml, champ SQLCA<br />
généralités, 206<br />
S–S<br />
481
S–S<br />
sqlerror, champ SQLCA<br />
élément, 206<br />
SQLCOUNT, 207<br />
SQLIOCOUNT, 206<br />
SQLIOESTIMATE, 208<br />
SQLError, fonction ODBC<br />
généralités, 304<br />
sqlerror_message, fonction<br />
généralités, 268<br />
sqlerrp, champ SQLCA<br />
généralités, 206<br />
SQLExecDirect, fonction ODBC<br />
généralités, 292<br />
paramètres <strong>de</strong> liaison, 293<br />
SQLExecute<br />
fonction ODBC, 14<br />
SQLExten<strong>de</strong>dFetch, fonction ODBC<br />
généralités, 298<br />
procédures stockées, 302<br />
SQLFetch, fonction ODBC<br />
généralités, 298<br />
procédures stockées, 302<br />
SQLFreeHandle, fonction ODBC<br />
utilisation, 286<br />
SQLFreeStmt<br />
fonction ODBC, 14<br />
SQLGetData, fonction ODBC<br />
généralités, 297, 298<br />
sqlind, champ SQLDA<br />
généralités, 228<br />
SQLIOCOUNT<br />
élément <strong>de</strong> champ SQLCA, 206<br />
SQLIOESTIMATE<br />
élément <strong>de</strong> champ SQLCA, 208<br />
sqllen, champ SQLDA<br />
<strong>de</strong>scription <strong>de</strong> valeurs, 230<br />
envoi <strong>de</strong> valeurs, 231<br />
extraction <strong>de</strong> valeurs, 233<br />
généralités, 228, 229<br />
instruction DESCRIBE, 230<br />
sqlname, champ SQLDA<br />
généralités, 228<br />
482<br />
SQLNumResultCols, fonction ODBC<br />
procédures stockées, 302<br />
SQLPP<br />
généralités, 178<br />
ligne <strong>de</strong> comman<strong>de</strong>, 247<br />
SQLPrepare<br />
fonction ODBC, 14<br />
SQLPrepare, fonction ODBC<br />
généralités, 295<br />
SQLRETURN<br />
co<strong>de</strong> <strong>de</strong> retour ODBC, 304<br />
SQLSetConnectAttr, fonction ODBC<br />
généralités, 290<br />
SQLSetPos, fonction ODBC<br />
généralités, 300<br />
SQLSetStmtAttr, fonction ODBC<br />
caractéristiques d'un curseur, 297<br />
sqlstate, champ SQLCA<br />
généralités, 206<br />
SQLTransact, fonction ODBC<br />
généralités, 287<br />
sqltype, champ SQLDA<br />
généralités, 228<br />
instruction DESCRIBE, 230<br />
sqlvar, champ SQLDA<br />
contenu, 228<br />
généralités, 227, 228<br />
sqlwarn, champ SQLCA<br />
généralités, 206<br />
START JAVA, instruction<br />
utilisation, 138<br />
stockage<br />
objet Java dans la base <strong>de</strong> données, 127<br />
stockage d'objet<br />
Java dans la base <strong>de</strong> données, 127<br />
STOP JAVA, instruction<br />
utilisation, 138<br />
structure <strong>de</strong> répertoires<br />
UNIX, 409<br />
structure <strong>de</strong>s programmes<br />
Embed<strong>de</strong>d SQL, 183
Sun, package<br />
classe d'exécution, 95<br />
support<br />
forums, xv<br />
support technique<br />
forums, xv<br />
suppression<br />
classe Java, 112<br />
fichier JAR, 112<br />
suppression positionnée, 23<br />
<strong>Sybase</strong> Central<br />
ajout <strong>de</strong> classes Java, 102<br />
ajout <strong>de</strong> fichiers JAR, 103<br />
ajout <strong>de</strong> fichiers ZIP, 103<br />
configuration <strong>de</strong> la base <strong>de</strong> données pour Java, 99<br />
déploiement, 431<br />
sybase.sql, package<br />
classe d'exécution, 95<br />
sybase.sql.ASA, package<br />
JDBC 2.0, 143<br />
System Management <strong>Server</strong><br />
déploiement, 418<br />
système d'exploitation<br />
nom <strong>de</strong> fichier, 410<br />
T<br />
table <strong>de</strong> travail<br />
performances du curseur, 42<br />
taille du segment <strong>de</strong> mémoire<br />
Java dans la base <strong>de</strong> données, 138<br />
this<br />
métho<strong>de</strong> Java dans la base <strong>de</strong> données, 122<br />
thread<br />
application ODBC, 291<br />
développement UNIX, 280<br />
Embed<strong>de</strong>d SQL, 208<br />
Java dans la base <strong>de</strong> données, 121<br />
ODBC, 276<br />
TIMESTAMP, type <strong>de</strong> données<br />
conversion, 387<br />
traitement <strong>de</strong>s erreurs<br />
Java, 70<br />
traitement en arrière-plan<br />
fonctions callback, 245<br />
transaction<br />
curseur, 49<br />
développement d'applications, 47<br />
distribuée, 399<br />
mo<strong>de</strong> autocommit, 47<br />
niveau d'isolement, 49<br />
ODBC, 287<br />
transaction distribuée, 394<br />
architecture, 396, 397<br />
architecture à trois niveaux, 396<br />
EA<strong>Server</strong>, 401<br />
généralités, 393, 394, 399<br />
réinscription, 396<br />
reprise, 400<br />
transférabilité<br />
définition, 137<br />
troncature<br />
instruction FETCH, 202<br />
sur FETCH, 202<br />
variable indicateur, 202<br />
type<br />
objet, 63<br />
type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL, 192<br />
intervalles, 387<br />
Java dans la base <strong>de</strong> données, 106<br />
langage C, 197<br />
mappage, 387<br />
Open Client, 387<br />
SQL dynamique, 226<br />
SQLDA, 228<br />
variable hôte, 197<br />
type <strong>de</strong> données Java<br />
extraction, 169<br />
insertion, 169<br />
type <strong>de</strong> données, conversion<br />
variable indicateur, 203<br />
T–T<br />
483
U–Z<br />
U<br />
Unico<strong>de</strong><br />
ODBC, 279<br />
Windows CE, 279<br />
UNIX<br />
application multithread, 410<br />
application ODBC, 282<br />
remarque sur le déploiement, 409<br />
structure <strong>de</strong> répertoires, 409<br />
unixodbc.h, 278<br />
UPDATE, instruction<br />
Java dans la base <strong>de</strong> données, 111<br />
métho<strong>de</strong> SET, 112<br />
positionnée, 23<br />
URL<br />
base <strong>de</strong> données, 150<br />
jConnect, 149<br />
utilisation <strong>de</strong> Java dans la base <strong>de</strong> données, 91<br />
utilitaire<br />
déploiement d'utilitaires <strong>de</strong> base <strong>de</strong> données, 436<br />
préprocesseur SQL, 247<br />
V<br />
valeur par défaut<br />
Java dans la base <strong>de</strong> données, 106<br />
VARCHAR, type <strong>de</strong> données<br />
Embed<strong>de</strong>d SQL, 197<br />
variable <strong>de</strong> liaison<br />
généralités, 221<br />
variable hôte<br />
déclaration, 196<br />
généralités, 196<br />
SQLDA, 228<br />
type <strong>de</strong> données, 197<br />
utilisation, 200<br />
variable indicateur<br />
conversion <strong>de</strong>s types <strong>de</strong> données, 203<br />
généralités, 201<br />
NULL, 201<br />
484<br />
récapitulatif <strong>de</strong>s valeurs, 203<br />
SQLDA, 228<br />
troncature, 202<br />
version<br />
classe, 128<br />
Java dans la base <strong>de</strong> données, 73<br />
JDBC, 73<br />
JDK, 73<br />
Visual C++<br />
support, 180<br />
VM<br />
machine virtuelle Java, 56<br />
void<br />
métho<strong>de</strong> Java dans la base <strong>de</strong> données, 64, 122<br />
W<br />
Watcom C/C++<br />
support, 180<br />
Windows<br />
service, 284<br />
Windows CE<br />
dbtool8.dll, 310<br />
Java dans la base <strong>de</strong> données non supporté, 57<br />
ODBC, 279, 280<br />
OLE DB, 368<br />
version supportée, 368<br />
WITH HOLD, clause<br />
curseur, 21<br />
Z<br />
zip, fichier<br />
Java, 69<br />
zone <strong>de</strong> communication SQL<br />
généralités, 205