09.02.2013 Views

Adaptive Server Anywhere Guide de programmation - Sybase

Adaptive Server Anywhere Guide de programmation - Sybase

Adaptive Server Anywhere Guide de programmation - Sybase

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!