SQL et Langages de Programmation SQL est un langage bases de données autonome. Langage ensembliste de haut niveau Il faut un langage de programmation, pour programmer des applications de gestion o Notion de variables, structures de contrôles, etc. o SQL est exécuté à l'intérieur d'un programme d'application Nécessité de coupler SQL avec un langage plus classique (dit langage hôte) « Impedence mismatch » o SQL : haut niveau, traitement ensembliste, données persistantes, accès par valeur o Langage programmation : algorithmique, données temporaires, accès par adresse Couplage fort ou couplage faible ? © Najib Tounsi 1 SQL et Langages de programmation : Couplage Fort SQL est augmenté d’un ensemble de constructions intégrées permettant son usage en programmation. Intégration cohérente, un seul compilatur. o E.g. types tuple, relation, etc… (cf. Pascal-Relationnel) o Traitement ensembliste intégré au langage (e.g. instruction foreach etc. ) Plus ou moins un nouveau langage de programmation (nouveau compilateur, etc.) PL/SQL, entre autres, est un exemple commercial (oracle) Dans une moindre mesure PHP/Mysql, JDBC etc. (voir après) Les L4Gs aussi sont de ce type. Solutions propriétaires © Najib Tounsi 2 SQL et Langages de programmation : Solution type middleware Usage d’une API qui fait l’interface entre le programme et le serveur BD (moteur SQL) PHP/..SQL o mysql_select_db("store",$link); o $result = mysql_query("SELECT * FROM employee",$link); o $row = mysql_fetch_row($result) o echo mysql_result($result,0,ename); o printf("", $row[0], $row[1], $row[2], $row[3], $row[4]); Du coté du programme on manipule des données de types courants du langage hôte. Variables ((e.g. $link, $result, $row...) ) remplies par appel à des fonctions prédéfinies (API orientée SQL). Cf. JDBC © Najib Tounsi 3 SQL et Langages de programmation : Couplage Faible SQL est exécuté à l'intérieur d'un programme d'application. Les requêtes SQL sont incorporées aux instructions d'un programme. On dit « Embedded SQL » ESQL. ESQL/C, ESQL/COBOL, ESQL/Java, ESQL/Fortran , etc. sont tous des produits standards. En principe toute requête SQL directe peut aussi être exécutée dans un programme. Réutilisation des langages existants Principe de préprocesseur. Exemple Pro*C precompiler de Oracle © Najib Tounsi 4 EMBEDDED SQL Source ESQL/C Préprocesseur Code SQL pur Code C pur Processeur SQL Compilateur Plan d'exécution Module Objet Editeur de lien Module exécutable © Najib Tounsi 5 Exemple simple ESQL/C Programme qui supprime de la base le produit "P2" main(){ EXEC SQL char EXEC SQL ... EXEC SQL BEGIN DECALRE SECTION; * SQLSTATE; END DECALRE SECTION; DELETE FROM P WHERE P.NumP = 'P2'; ... if (SQLSTATE == '00000') printf ("%f\n", "Suppression OK"); else /* Erreur ...*/ } A noter: EXEC SQL pour distinguer lignes SQL pure. SQLSTATE pour renseigner sur le déroulement de la requête. Déclarée dans DECALRE SECTION. © Najib Tounsi 6 2e Exemple simple ESQL/C Notion de variable C dans SQL, avec requête à tuple unique. main(){ EXEC SQL BEGIN DECALRE SECTION; char [5] xNumP; float xPrix; char * SQLSTATE; EXEC SQL END DECALRE SECTION; scanf("%s", xNumP); /* ou autre source d'entrée */ EXEC SQL SELECT P.Prix INTO :xPrix FROM P WHERE P.NumP = :xNumP; if (SQLSTATE == '00000') printf ("%f\n", xPrix); else /* Erreur ...*/ } © Najib Tounsi 7 A noter: EXEC SQL pour distinguer lignes SQL pure. Variables C particulières déclarées dans DECALRE SECTION. SQLSTATE pour renseigner sur l'exécution de SQL Requête mono-tuple ici! Résultat récupéré dans variable C. Clause INTO . SQLSTATE 00000 01xxx 02000 autres © Najib Tounsi Succès Warning particulier Succès mais résultat vide Exception SQL 8 3e Exemple simple ESQL/C Requête à résultat multi-tuples. Notion de CURSOR, avec instruction FETCH INTO pour extraire les valeurs retrouvées. SQLSTATE main(){ EXEC SQL BEGIN DECALRE SECTION; char [5] xNumP; float xPrix; char * SQLSTATE; EXEC SQL END DECALRE SECTION; ... EXEC SQL DECLARE X CURSOR FOR SELECT P.Nump, P.Prix FROM P Order by Nump; ... EXEC SQL OPEN X; EXEC SQL FETCH X INTO :xNump, :xPrix; do while (SQLSTATE != '02000'){ printf ("%s, %f\n", xNump, xPrix); EXEC SQL FETCH X INTO :xNump, :xPrix; } ... EXEC SQL CLOSE X; } © Najib Tounsi 9 A noter: X est un curseur qui reçoit le résultat de l'expression SELECT. X sera parcouru ligne par ligne, dans l'ordre pré défini par order by. Ce sera EXEC SQL OPEN X qui exécutera la requête SELECT. Après OPEN, FETCH retrouve une ligne et affecte les champs aux variables INTO. FECTH en suite fait avancer le curseur vers la ligne suivante FECTH doit donc apparaître à l'intérieur d'une boucle. SQLSTATE 02000 est la valeur quand FECTH ne trouve plus de ligne? ... © Najib Tounsi 10 SQL DYNAMIQUE Exemples précédents, requête SQL connue à l'écriture du programme. Cas où la requête n'est connue qu'au moment de l'exécution. Exemple: application ISQL! Tantque (existe requête utilisateur ) Saisir requête LDD / LMD exécuter requête © Najib Tounsi 11 Exemple simple ESQL/C SQL DYNAMIQUE (1) Requête SQL connue à l'exécution. Notion de PREPARE et EXECUTE Exemple 1: Exécution de SQL défini à l'exécution. EXEC SQL BEGIN DECLARE SECTION; char hostVarStmt[50]; EXEC SQL END DECLARE SECTION; strcpy(hostVarStmt, "DELETE FROM P WHERE Nump = 'P24'"); EXEC SQL PREPARE stmt FROM :hostVarStmt; EXEC SQL EXECUTE stmt; A noter: PREPARE compile le contenu défini dans FROM, (comme si EXEC SQL PREPARE Stmt FROM "DELETE FROM P WHERE Nump = 'P24'") et crée le plan d'exécution stmt, exécuté ensuite par SQL EXECUTE . Aspect dynamique: La requête entrée au clavier (ou provient de menu...) scanf("%s", hostVarStmt); EXEC SQL PREPARE stmt FROM :hostVarStmt; EXEC SQL EXECUTE stmt; © Najib Tounsi 12 Exemple simple ESQL/C SQL DYNAMIQUE (2) Cas particulier: On peut faire PREPARE et EXECUTE en une seule instruction EXECUTE IMMEDIATE strcpy(stmt, "CREATE TABLE maTable( maColonne INTEGER)"); EXEC SQL EXECUTE IMMEDIATE :stmt; Sauf pour SELECT. Pour INTO, comment savoir le nombre, le nom et le type des colonnes retournées? Pour plusieurs lignes, on utilise CURSOR et FETCH. Usage de DESCRIBE sur le résultat de PREPARE © Najib Tounsi 13 Exemple simple ESQL/C SQL DYNAMIQUE DESCRIBE offre structure (SQL Dynamic Area, SQLDA) permettant de connaître: (Schéma simplifié) SQLN Nombre de valeurs dans SQLVAR (nombre de colonnes). Retourné par PREPARE, utilisé par DESCRIBE SQLDABC (Taille du SQLDA) SQLD (nombre de colonne retrouvées) SQLVAR ( Tableau descriptif des colonnes retrouvées) SQLTYPE (code pour le type d'une colonne) SQLLEN (Taille d'une colonne) SQLNAME (Nom d'une colonne) © Najib Tounsi 14 Exemple simple ESQL/C squelette de SELECT DYNAMIQUE (3) EXEC SQL BEGIN DECLARE SECTION; char stmt1_str[200]; EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE SQLDA; EXEC SQL DECLARE DYN_CURSOR CURSOR FOR STMT1_NAME; /* reference en avant */ /* code pour avoir une requête SELECT */ EXEC SQL PREPARE STMT1_NAME FROM :stmt_str; /* tester SQLN pour allouer SQLDA */ EXEC SQL DESCRIBE STMT1_NAME INTO :sqlda; /* Verifier si SQLN == SQLD (il n'y a pas de LOB) /* code pour utiliser SQLDA ... */ EXEC SQL OPEN DYN_CURSOR; ... /* boucle d'accès aux données ... */ EXEC SQL FETCH DYN_CURSOR USING DESCRIPTOR :sqlda; .etc. © Najib Tounsi 15 SQL et Langages de programmation : Couplage « fort » Exemple de PL/SQL Voir : TP. © Najib Tounsi 16