26
base Management Systems 3ed, R. Ramakrishnan and J. Gehrke Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Embed Size (px)

Citation preview

Page 1: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 1

Développement des Applications des Bases de Données

Chapitre 6

Page 2: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 2

Survol

SQL dans les codes d’application SQL imbriqué Curseurs SQL dynamique JDBC SQLJ Procédures stockées

Page 3: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 3

SQL dans les codes d’Application Les commandes SQL peuvent être appelées à

partir d’un programme d’application («langage hôte» -- C++, Java, etc). Les instructions SQL peuvent référer à des variables

du langage hôte (y compris des variables utilisées pour retourner les statuts).

Doivent inclure une instruction pour connecter à la base de données appropriée.

Deux approches d’intégration existent: Instructions SQL imbriquées dans le langage hôte

(« Embedded SQL », SQLJ) Création d’une API spéciale pour appeler les

commandes SQL (JDBC)

Page 4: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 4

SQL dans les codes d’Application (Suite)

Les relations SQL sont des (multi)ensembles de tuples qui n’imposent aucune limite a priori sur le nombre de tuples. Les langages de programmation traditionnels (C, C++, etc.) n’ont pas une telle structure de données (Exception: STL). Ce probleme est appelé défaut d’adaptation d’impédance (« impedance mismatch ») .

SQL supporte un mécanisme appelé curseur pour résoudre ce problème.

Un curseur est un élément additionnel de SQL qui comble le fossé causé par le défaut de l’adaptation d’impédance.

Page 5: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 5

SQL Imbriqué: VariablesEXEC SQL BEGIN DECLARE SECTIONchar c_sname[20];long c_sid;short c_rating;float c_age;EXEC SQL END DECLARE SECTION

Deux problèmes avec les variables: (i) correspondance des types (solution: casting/correspondance explicite), et (ii) « impedance mismatch » (solution: le mécanisme de curseur).

Deux variables spéciales d’“erreur” (une au moins doit être déclarée): SQLCODE (long, est négative si une erreur est apparue) SQLSTATE (char[6], codes prédéfinies pour des erreurs

usuelles)

Page 6: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 6

SQL Imbriqué: Instructions Approche: instructions SQL imbriquées

dans le langage hôte. préprocesseur convertit les instructions SQL

en des appels API. Ensuite un compilateur régulier prend le relais

pour compiler le code.

Éléments du langage: Pour connecter à une base de données:

EXEC SQL CONNECT Pour exécuter des instructions SQL:

EXEC SQL Statement;

Page 7: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 7

SQL Imbriqué: Instructions (Suite) Exemple:

Insérer une ligne avec des valeurs issues des variables du langage hôte: EXEC SQL INSERT INTO Sailors

VALUES (:c_sname, :c_sid, :c_rating, :c_age);

Commande spéciale pour contrôler les erreurs après des instructions SQL: EXEC SQL

WHENEVER [SQLERROR|NOT FOUND] [CONTINUE|GOTO smt]

Page 8: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 8

Curseurs: Intuition On peut déclarer un curseur sur une relation ou une

instruction de requête (qui en fait génère une relation).

On peut ouvrir un curseur déclaré, et l’utiliser pour puiser (fetch) de manière répétée des tuples et, après, déplacer le curseur, jusqu’à ce que tous les tuples aient été récupérés. On peut utiliser une clause spéciale, appelée ORDER BY, dans

les requêtes accessibles aux curseurs afin de contrôler l’ordre dans le quel les tuples doivent être récupérés.

Les attributs mentionnés dans la clause ORDER BY doivent aussi l’être dans la clause SELECT.

On peut enfin clore un curseur ouvert. On peut aussi modifier/effacer des lignes en utilisant

un curseur. Cependant, INSERT, DELETE, et UPDATE peuvent être utilisés sans curseur.

Page 9: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 9

Exemple d’Utilisation de Curseur

sinfo est le curseur. Il est illégal de remplacer S.sname par S.sid

dans la clause ORDER BY ! (Pourquoi?) Peut-on ajouter S.sid à la clause SELECT et

remplacer S.sname par S.sid dans la clause ORDER BY ?

EXEC SQL DECLARE sinfo CURSOR FORSELECT S.snameFROM Sailors S, Boats B, Reserves RWHERE S.sid=R.sid AND R.bid=B.bid AND B.color=‘red’ORDER BY S.sname

Page 10: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 10

Curseur: Syntaxe Syntaxe générale pour déclarer les curseurs:

DECLARE cursorname [INSENSITIVE] [SCROLL] CURSOR [WITH HOLD] FOR query[ORDER BY order-item-list][FOR READ ONLY | FOR UPDATE]

INSENSITIVE: une copie privée du curseur est faiteSCROLL: permet plus de flexibilité pour l’opération FETCHWITH HOLD: curseur n’est pas fermé quand la transaction est validée.

Variante de la commande UPDATE pour les curseurs:UPDATE tableSET expressionWHERE CURRENT OF cursorname

Page 11: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 11

Imbriquer SQL dans C: Exemplechar SQLSTATE[6];

EXEC SQL BEGIN DECLARE SECTIONchar c_sname[20]; short c_minrating; float c_age;EXEC SQL END DECLARE SECTIONc_minrating = random();EXEC SQL DECLARE sinfo CURSOR FOR

SELECT S.sname, S.age FROM Sailors SWHERE S.rating > :c_minratingORDER BY S.sname;

do {EXEC SQL FETCH sinfo INTO :c_sname, :c_age;printf(“%s is %d years old\n”, c_sname, c_age);

} while (SQLSTATE != ‘02000’);EXEC SQL CLOSE sinfo;

Page 12: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 12

SQL Dynamique Les instructions SQL imbriquées sont connues par le

compilateur à l’avance («compile time»). Il y a des situation où ce n’est pas le cas (p.ex.

tableurs, interfaces des SGBDs graphiques); il faut donc permettre la d’instructions SQL en passant (« on-the-fly » /«run time»)!

Deux commandes principales à ce sujet: PREPARE sql_cmd FROM sql_stringEXECUTE sql_cmd

Exemple:char c_sqlstring[]=

{“DELETE FROM Sailors WHERE raiting>5”};EXEC SQL PREPARE deleteCommand FROM :c_sqlstring;EXEC SQL EXECUTE deleteCommand;

Page 13: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 13

APIs en Lieu et Place de l’Imbrication Au lieu de modifier le compilateur, ajouter des

bibliothèques avec des instructions d’appel des bases de données (API).

Interface spéciale standard: procédures/objets Passer les instructions SQL (en forme de chaînes de

caractères) à partir du langage hôte, et présenter les ensembles de résultats dans une manière compréhensible pour le langage hôte.

Exemples: ODBC; JDBC (Sun Coorporation: API Java) JDBC est supposé être indépendant de tout SGBD

Un pilote (“driver”) reçoit les instructions d’appel et les traduit dans le code spécifique du SGBD.

La base de données peut se trouver à un autre bout du réseau.

Page 14: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 14

JDBC: Architecture Quatre composantes architecturales:

Application (initie et termine des connexions, soumet des instructions SQL)

Gestionnaire des pilotes (‘’Driver manager’’) (choisit --‘’loads’’-- un driver JDBC)

Driver (connecte à la source des données, transmet des requêtes et retourne/traduit les résultats et les codes d’erreur)

Source des données (exécute les instructions SQL)

Page 15: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 15

JDBC: Types de Drivers Pont (’’Bridge’’):

Traduit les commandes SQL en une API non native.Exemple: le pont JDBC-ODBC. Le code pour les drivers ODBC et JDBC doivent être présents sur chaque client.

Traduction directe en une API native via un driver hors Java: Traduit les commandes SQL en une API native de la source des

données. Besoin d’un code binaire spécifique à chaque système d’opération sur chaque client.

Pont sur réseau (‘’network bridge’’): Les commandes sont envoyées via le réseau à un module

intermédiaire (‘’middleware’’) qui est un serveur parlant à la source des données. Seul besoin: un petit driver JDBC sur chaque client.

Traduction directe en une API native via un driver Java: Convertit les instructions d’appel JDBC directement dans le

protocole de réseau que le SGBD utilise. Besoin d’un driver Java spécifique à chaque SGBD sur chaque client.

Page 16: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 16

Classes et Interface pour JDBC

Étapes pour soumettre une requête:

1. Choisir le driver JDBC (via un gestionnaire)

2. Connecter à la source de données3. Exécuter les instructions SQL

Page 17: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 17

Gestionnaire des Pilotes JDBC Tous les drivers sont gérés par la classe

DriverManager Choix d’un driver JDBC (3 voies possibles):

Dans le code Java:Class.forName(“oracle/jdbc.driver.Oracledriver”);Retourne l’objet de la classe driver au vu de son nom complet.

En démarrant une application Java (à la ligne des commandes):-Djdbc.drivers=oracle/jdbc.driver

En créant un objet driver explicitement

Page 18: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 18

Connexions JDBCL’interaction avec une source de données se fait par

l’entremise d’une session qui est démarrée par la création d’un objet de type ‘’Connection’’. Chaque session est démarrée via un URL JDBC.

URL JDBC(i.e. un URL utilisant le protocole JDBC):

jdbc:<sousprotocole>:<autresParametres>

Exemple: Etablir une connexion à une BD Oracle précise:

String url=“jdbc:oracle:www.bookstore.com:3083”;connexion con;try{

con = DriverManager.getconnexion(url,usedId,password);} catch SQLException excpt { …}

Page 19: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 19

Interface pour les Connexions public int getTransactionIsolation() et void setTransactionIsolation(int level)Détermine le degré d’isolation de la connexion en cours.

public Boolean getReadOnly() et void setReadOnly(boolean b)Spécifie si les transactions dans la connexion sont pour lecture seulement (‘’read-only’’).

public boolean getAutoCommit() et void setAutoCommit(boolean b)Si autocommit est vrai, chaque instruction SQL est considérée comme une transaction autonome. Sinon, la transaction est validée par commit(), ou abandonnée par rollback().

public boolean isClosed()Vérifie si la connexion est encore ouverte.

Page 20: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 20

Exécution des Instructions SQL

Trois manières différentes de le faire (i.e. en utilisant 3 classes appropriées pour des objets de type ‘’statement’’): Statement (permet des requêtes avec soit des

instructions SQL statiques soit dynamiques) PreparedStatement (instructions semi statiques) CallableStatement (procédures stockées)

La classe PreparedStatement:génère dynamiquement des instructions SQL précompilées et paramétrisées: Structure fixe Valeurs des paramètres déterminées pendant

l’exécution

Page 21: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 21

Exécution des Instructions SQL (Suite)

String sql=“INSERT INTO Sailors VALUES(?,?,?,?)”;

PreparedStatment pstmt=con.prepareStatement(sql);

pstmt.clearParameters();pstmt.setInt(1,sid); // Supposons que sid, sname, …

pstmt.setString(2,sname); // sont des vars Java avec

pstmt.setInt(3, rating); // des valeurs à insérer.

pstmt.setFloat(4,age); // Savons que aucune ligne n’est retournées,

// d’où nous utilisons executeUpdate()

int numRows = pstmt.executeUpdate();

Page 22: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 22

Ensembles des Resultats

PreparedStatement.executeUpdate retourne seulement le nombre de ligne affectées.

PreparedStatement.executeQuery retourne les donnees, repris dans un objet ResultSet (un curseur)

ResultSet rs=pstmt.executeQuery(sql);// rs est un curseur; next() puise la prochaine ligneWhile (rs.next()) { // traiter les données }

Page 23: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 23

Ensemble des Resultats (Suite)

Un ResultSet est un curseur très puissant: previous(): reculer d’une ligne absolute(int num): avancer à la ligne

dont le numéro d’ordre est indiqué relative (int num): avancer ou reculer

selon la valeur indiquée first() et last()

Page 24: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 24

Correspondance entre les Types de Données: Java vs SQL

SQL Type Java class ResultSet get method

BIT Boolean getBoolean()

CHAR String getString()

VARCHAR String getString()

DOUBLE Double getDouble()

FLOAT Double getDouble()

INTEGER Integer getInt()

REAL Double getFloat()

DATE java.sql.Date getDate()

TIME java.sql.Time getTime()

TIMESTAMP java.sql.TimeStamp

getTimestamp()

Page 25: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 25

JDBC: Exceptions et Avertissements

java.sql émet des exceptions SQLException si une erreur apparaît.

SQLWarning est une sousclasse de SQLException; (pas du tout émis mais leur existence doit être explicitement testé si on veut les voir)

Méthodes dans la classe SQLException: getMessage(), getSQLState(), getErrorCode(), getNextException(), …

Page 26: Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 Développement des Applications des Bases de Données Chapitre 6

Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke 26

JDBC: Exceptions et Avertissements (Suite)

try { stmt=con.createStatement(); warning=con.getWarnings(); while(warning != null) { // traiter le SQLWarnings; warning = warning.getNextWarning(): } con.clearWarnings(); stmt.executeUpdate(queryString); warning = con.getWarnings(); …} //end trycatch( SQLException SQLe) { // traiter l’exception}