Utilisation du langage SQL dans des événements XML. Novell Pilote DirXML pour JDBC
Novell Confidential Manual (FRA) 28 October 2003
8. Mise à jour de champ (avec retour d’interrogation)
Le tableau ci-dessous montre le contenu de la table de consignation des événements après la mise à jour de la ligne dans la table emp
: Les valeurs anciennes et nouvelles sont omises car elles ne sont pas utilisées.
event_type table
8
8
8 emp emp emp
table_key
empno=1 empno=1 empno=1
column_name
fname lname photo
old_value
NULL
NULL
NULL
new_value
NULL
NULL
NULL
Le XML généré par l’Éditeur figure ci-dessous. Notez que les valeurs reflètent le contenu actuel de la table emp
et pas son contenu initial.
<modify class-name="emp">
<association>empno=1,table=emp,schema=dirxml
</association>
<modify-attr attr-name="fname">
<remove-all-values/>
<add-value>
<value type="string">John</value>
</add-value>
</modify-attr>
<modify-attr attr-name="lname">
<remove-all-values/>
<add-value>
<value type="string">Doe</value>
</add-value>
</modify-attr>
<modify-attr attr-name="photo">
<remove-all-values/>
<add-value>
<value type="octet">u7s=</value>
</add-value>
</modify-attr>
</modify>
Utilisation du langage SQL dans des événements XML
La section suivante contient des informations qui vous permettront d’insérer du code SQL dans les
événements XML.
Tous les exemples font référence à la table emp
ci-dessous. La méthode de génération de clé primaire utilisée pour obtenir des valeurs de clé primaire importe peu dans les exemples de cette section.
CREATE TABLE emp
(
empno NUMERIC(8) NOT NULL,
fname VARCHAR2(64),
lanem VARCHAR2(64),
CONSTRAINT pk_emp_empno PRIMARY KEY(empno)
);
Remarque : le préfixe d’espace de nom jdbc
utilisé dans toute cette section est implicitement lié à l’espace de nom urn:dirxml:jdbc
lorsqu’il est cité en dehors d’un document XML.
Configuration avancée du pilote
65
Novell Confidential Manual (FRA) 28 October 2003
Introduction
Vos pouvez utiliser du code SQL incorporé dans des événements XML. Tout comme il est possible d’installer des déclencheurs de base de données sur une table pour provoquer des effets secondaires dans une base de données, le code SQL incorporé dans des événements XML joue le rôle d’un déclencheur virtuel doté des mêmes fonctionnalités.
Le code SQL est incorporé aux événements XML par l’intermédiaire des éléments
<jdbc:statement>
et
<jdbc:sql>
. L’élément
<jdbc:statement>
peut contenir un ou plusieurs éléments
<jdbc:sql>
.
L’exemple de code XML suivant comporte une instruction SQL incorporée.
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement>
<jdbc:sql> UPDATE dirxml.emp SET fname = 'John'
</jdbc:sql>
</jdbc:statement>
</input>
Comme l’objet Abonné résout les événements d’
<ajout>
pour une ou plusieurs instructions d’insertion, le code XML ci-dessus serait résolu comme suit :
INSERT INTO dirxml.emp(lname)VALUES('Doe');
UPDATE dirxml.emp SET fname = 'John';
Important : utilisez des éléments et attributs qui indiquent l’espace de nom en préfixe pour incorporer du code SQL (sinon, le pilote ne le reconnaîtra pas). Dans l’exemple ci-dessus, l’espace de nom est urn:dirxml:jdbc
. Le préfixe est l’identificateur qui figure à droite de l’identificateur xmlns
. Dans l’exemple ci-dessus, le préfixe est jdbc
. En pratique, le préfixe peut être ce que vous voulez, à condition qu’il soit lié au bon espace de nom.
Substitution de variables
Au lieu de vous imposer une analyse syntaxique des valeurs des champs d’une association, l’objet
Abonné prend en charge la substitution de variable dans les instructions SQL incorporées.
Exemple :
<input xmlns:jdbc="urn:dirxml:jdbc">
<modify class-name="emp">
<association>empno=1,table=emp,schema=dirxml
</association>
<modify-attr name="lname">
<add-value>
<value>DoeRaeMe</value>
</add-value>
</modify-attr>
</modify>
<jdbc:statement>
<jdbc:sql>UPDATE dirml.emp SET fname = 'John' WHERE
empno = {$empno}</jdbc:sql>
</jdbc:statement>
</input>
66
DirXML Driver for JDBC Implementation Guide (Guide d’implémentation du pilote DirXML pour JDBC)
Novell Confidential Manual (FRA) 28 October 2003
Les marques de réservation variables doivent respecter la syntaxe modèle des valeurs d’attribut
XSLT :
{$
nom-champ
}
et l’élément d’association doit précéder l’élément
<jdbc:statement> dans le document XML ou figurer en tant qu’enfant de l’élément
<jdbc:statement>
.
La marque nom-champ doit faire référence à l’un des noms d’attribut RDN dans la valeur d’association. Dans l’exemple ci-dessus, il n’existe qu’un seul attribut de dénomination, empno
.
Un événement d’
<ajout>
est le seul qui n’exige pas d’élément d’association pour traiter les instructions SQL incorporées avec substitution de variable, parce que l’association n’a pas encore
été créée. Par ailleurs, les instructions SQL incorporées qui utilisent la substitution de variable doivent suivre, et non précéder, l’événement d’
<ajout>
. Exemple :
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement>
<jdbc:sql>UPDATE dirxml.emp SET fname = 'John' WHERE
empno = {$empno}</jdbc:sql>
</jdbc:statement>
</input>
Pour empêcher le suivi des informations personnelles, il est possible d’utiliser
{$$password} pour désigner le contenu d’un élément
<password>
dans le même document.
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
<password>Dupont{$empno}</password>
</add>
<jdbc:statement>
<jdbc:sql>CREATE USER Dupont IDENTIFIED BY
{$$password}</jdbc:sql>
</jdbc:statement>
</input>
Placement des instructions
De la même manière que les déclencheurs de base de données peuvent être exécutés avant ou après une instruction qui les déclenche, le code SQL incorporé peut être placé avant ou après l’événement XML déclenchant. Les exemples suivants illustrent comment incorporer du code
SQL avant ou après un événement XML.
Avant le déclencheur
<input xmlns:jdbc"urn:dirxml:jdbc">
<jdbc:statement>
<association>empno=1,table=emp,schema=dirxml
</association>
<jdbc:sql>UPDATE dirxml.emp SET fname = 'John' WHERE
empno = ${empno}</JDBC:SQL>
</jdbc:statement>
<modify class-name="emp">
<association>empno=1,table=emp,schema=dirxml
Configuration avancée du pilote
67
Novell Confidential Manual (FRA) 28 October 2003
</association>
<modify-attr name="lname">
<remove-all-values/>
<add-value>
<value>Doe</value>
</add-value>
</modify-attr>
</modify>
</input>
Les données XML ci-dessus sont converties comme suit :
UPDATE dirxml.emp SET fname = 'John' WHERE empno = 1;
UPDATE dirxml.emp SET lname = 'Doe' WHERE empno = 1;
Après le déclencheur
<input xmlns:jdbc"urn:dirxml:jdbc">
<modify class-name="emp">
<association>empno=1,table=emp,schema=dirxml
</association>
<modify-attr name="lname">
<remove-all-values/>
<add-value>
<value>Doe</value>
</add-value>
</modify-attr>
</modify>
<jdbc:statement>
<jdbc:sql>UPDATE dirxml.emp SET fname = 'John' WHERE
empno = {$empno}</jdbc:sql>
</jdbc:statement>
</input>
Les données XML ci-dessus sont converties comme suit :
UPDATE dirxml.emp SET lname = 'Doe' WHERE empno = 1;
UPDATE dirxml.emp SET fname = 'John' WHERE empno = 1;
Transactions manuelles et automatiques
Vous pouvez regrouper manuellement du code SQL et des événements XML à l’aide des deux attributs personnalisés suivants :
jdbc:transaction-type
jdbc:transaction-id
jdbc:transaction-type
Cet attribut possède deux valeurs : manual
et auto
. Par défaut, la plupart des événements XML qui présentent un intérêt sont des transactions de type manual. Le paramètre « manual » permet aux événements XML d’être convertis en plusieurs instructions SQL.
Le type de transaction auto est attribué par défaut aux événements SQL incorporés, car certaines instructions SQL ne peuvent pas être incluses dans une transaction manuelle.
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp" jdbc:transaction-type="auto">
<add-attr name="lname">
68
DirXML Driver for JDBC Implementation Guide (Guide d’implémentation du pilote DirXML pour JDBC)
Novell Confidential Manual (FRA) 28 October 2003
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement>
<jdbc:sql>UPDATE dirxml.emp SET fname = 'John' WHERE
empno = {$empno}</jdbc:sql>
</jdbc:statement>
</input>
Les données XML ci-dessus sont converties comme suit :
INSERT INTO dirxml.emp(lname) VALUES('Doe');
/* COMMIT; implicit */
UPDATE dirxml.emp SET fname = 'John' WHERE empno = 1;
/* COMMIT; implicit */
jdbc:transaction-id
L’objet Abonné ignore cet attribut, sauf si l’attribut jdbc:transaction-type
de l’élément a par défaut ou explicitement la valeur manual. Le code XML suivant représente un exemple de transaction manuelle :
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp" jdbc:transaction-id="0">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement jdbc:transaction-type="manual"
jdbc:transaction-id="0">
<jdbc:sql>UPDATE dirxml.emp SET fname = 'John' WHERE
empno = {$empno}</jdbc:sql>
</jdbc:statement>
</input>
Le code XML ci-dessus est converti comme suit :
INSERT INTO dirxml.emp(lname) VALUES('Dupont');
UPDATE dirxml.emp SET fname = 'John' WHERE empno = 1;
COMMIT; /* explicit */
Niveau d’isolation de transaction
Outre le regroupement d’instructions, les transactions permettent de préserver l’intégrité des données d’une base de données. Les transactions peuvent verrouiller les données afin d’empêcher tout accès concurrent ou toute modification. Le réglage des verrous est déterminé par le niveau d’isolation d’une transaction. En général, le niveau d’isolation par défaut utilisé par le pilote est suffisant et ne doit pas être modifié.
L’attribut personnalisé jdbc:isolation-level
vous permet de régler le niveau d’isolation de transaction en cas de besoin. Cinq valeurs possibles sont définies dans l’interface java.sql.Connection :
aucune
lecture non validée
lecture validée
Configuration avancée du pilote
69
Novell Confidential Manual (FRA) 28 October 2003
lecture renouvelée
sérialisable
Le niveau d’isolation de transaction par défaut du pilote est lecture validée
. En cas de transaction manuelle, l’attribut jdbc:isolation-level
doit être placé sur le premier élément de la transaction. Cet attribut est ignoré sur les éléments qui suivent. Exemple :
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp" jdbc:transaction-id="0"
jdbc:isolation-level="serializable">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement jdbc:transaction-type="manual"
jdbc:transaction-id="0">
<jdbc:sql>UPDATE dirxml.emp SET fname = 'John'
WHERE empno = {$empno}</jdbc:sql>
</jdbc:statement>
</input>
Les données XML ci-dessus sont converties comme suit :
INSERT INTO dirxml.emp(lname) VALUES('Doe');
UPDATE dirxml.emp SET fname = 'John' WHERE empno = 1;
COMMIT; /* explicit */
Type d’instruction
Le pilote exécute les instructions SQL incorporées, sans les comprendre. L’interface JDBC définit plusieurs méthodes d’exécution de différents types d’instructions SQL. Le tableau suivant recense ces méthodes :
Type d’instruction
SELECT
Méthode d’exécution
Statement.executeQuery(String)
INSERT
UPDATE
Statement.executeUpdate(String)
Statement.executeUpdate(String)
DELETE Statement.executeUpdate(String)
CALL ou EXECUTE
L’une quelconque des instructions ci-dessus
Statement.execute(String)
La solution la plus simple est d’assigner toutes les instructions SQL à la méthode execute().
Par défaut, c’est la méthode retenue par le pilote. Certains pilotes de fabricants tiers, notamment le pilote JDBC d’Oracle, mettent incorrectement en œuvre les méthodes utilisées pour déterminer le nombre de résultats générés par la méthode execute(). En conséquence, le pilote peut être pris dans une boucle infinie qui entraîne une forte utilisation de l’unité centrale. Pour éviter ce problème, il est possible d’utiliser l’attribut jdbc:type
sur n’importe quel élément
<jdbc:statement>
pour en assigner les instructions SQL aux méthodes executeQuery() ou executeUpdate() au lieu de la méthode execute() par défaut.
70
DirXML Driver for JDBC Implementation Guide (Guide d’implémentation du pilote DirXML pour JDBC)
Novell Confidential Manual (FRA) 28 October 2003
L’attribut jdbc:type
possède deux valeurs : update
et query
. Il convient de définir la valeur update
pour les instructions insert, update ou delete et la valeur query
pour les instructions select. En l’absence de cet attribut, le pilote assigne toutes les instructions SQL à la méthode execute(). S’il est placé sur un autre élément que
<jdbc:statement>
, cet attribut est ignoré.
Nous vous recommandons d’affecter la valeur d’attribut jdbc:type="query"
à toutes les instructions select et l’attribut jdbc:type="update"
à toutes les instructions insert, update et delete.
Le code XML suivant contient un exemple d’attribut jdbc:type
:
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement jdbc:type="update">
<jdbc:sql>UPDATE dirxml.emp SET fname = 'John'
WHERE empno = {$empno}</jdbc:sql>
</jdbc:statement>
</input>
Requêtes SQL
Pour prendre pleinement en charge les fonctionnalités de requête d’une base de données et éviter la difficile conversion des requêtes SQL natives au format XML, le pilote prend en charge le traitement des requêtes SQL natives. Les instructions select peuvent être incorporées à des documents XML exactement comme les autres instructions SQL.
Par exemple, si le contenu de la table emp
était le suivant :
empno
1
fname
Jean
lname
Untel
Le document XML ci-dessous donnerait un document de sortie contenant un seul ensemble de résultats.
<input xmlns:jdbc="urn:dirxml:jdbc">
<jdbc:statement jdbc:type="query">
<jdbc:sql>SELECT * FROM dirxml.emp</jdbc:sql>
</jdbc:statement>
</input>
<output xmlns:jdbc="urn:dirxml:jdbc">
<jdbc:result-set jdbc:number-of-rows="1">
<jdbc:row jdbc:number="1">
<jdbc:column jdbc:name="empno"
jdbc:position="1"
jdbc:type="java.sql.Types.DECIMAL"
<jdbc:value>l</jdbc:value>
</jdbc:column>
<jdbc:column jdbc:name="fname"
jdbc:position="2"
jdbc:type="java.sql.Types.VARCHAR">
<jdbc:value>John</jdbc:value>
</jdbc:column>
Configuration avancée du pilote
71
Novell Confidential Manual (FRA) 28 October 2003
<jdbc:column jdbc:name="lname"
jdbc:position="3"
jdbc:type="java.sql.Types.VARCHAR>
<jdbc:value>Doe</jdbc:value>
</jdbc:column>
</jdbc:row>
</jdbc:result-set>
<status level="success"/>
</output>
Les requêtes SQL produisent toujours un élément
<jdbc:result-set>
unique, que l’ensemble de résultats contienne ou non des lignes. Si l’ensemble de résultats est vide, l’attribut jdbc:number-of-rows
sera défini sur zéro.
Il est possible d’incorporer plusieurs requêtes dans un document. Les requêtes SQL n’exigent pas que les tables référencées soient connues du pilote, alors que les requêtes XML l’exigent.
Instructions en langage DDL (Data Definition Language - Langage de définition de données)
Il est généralement impossible d’exécuter une instruction DDL dans un déclencheur de base de données, car la plupart des bases n’autorisent pas les transactions DML et DDL mixtes. Bien que les déclencheurs virtuels ne permettent pas de surmonter cette limite de transaction, ils permettent l’exécution d’instructions DDL en tant qu’effets secondaires d’un événement XML. Exemple :
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement>
<jdbc:sql>CREATE USER dirxml IDENTIFIED BY novell
</jdbc:sql>
</jdbc:statement>
</input>
Les données XML ci-dessus sont converties comme suit :
INSERT INTO dirxml.emp(lname) VALUES('Doe');
/* COMMIT; implicit */
CREATE USER dirxml IDENTIFIED BY novell;
/* COMMIT; implicit */
L’utilisation des attributs jdbc:transaction-id
et jdbc:transaction-type
pour regrouper des instructions DML et DDL en une seule transaction entraînerait l’annulation de cette transaction dans la plupart des bases de données. Comme les instructions DDL sont généralement exécutées en tant que transactions distinctes, il est possible que l’instruction d’insertion de l’exemple ci-dessus aboutisse et que l’instruction de création d’utilisateur soit restaurée à son état initial. Par contre, il est impossible que l’instruction d’insertion échoue et que l’instruction de création d’utilisateur aboutisse. Le pilote arrête d’exécuter des transactions en chaîne dès que la première transaction est annulée.
72
DirXML Driver for JDBC Implementation Guide (Guide d’implémentation du pilote DirXML pour JDBC)
Novell Confidential Manual (FRA) 28 October 2003
Opérations logiques
Comme il est généralement impossible de mélanger des instructions DML et DDL dans une seule transaction, un événement unique peut se composer d’une ou de plusieurs transactions. Les attributs jdbc:op-id
et jdbc:op-type
peuvent être utilisés pour regrouper plusieurs transactions en une seule opération logique. Dans un regroupement de ce type, tous les membres de l’opération sont traités comme une seule entité en ce qui concerne leur état. Autrement dit, si un membre de l’opération échoue, tous les membres renvoient le même niveau d’état. De même, tous les membres partagent le même type d’état.
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp" jdbc:op-id="0"
jdbc:op-type="password-set-operation">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
<password>Doe{$empno}</password>
</add>
<jdbc:statement jdbc:op-id="0">
<jdbc:sql>CREATE USER Doe IDENTIFIED BY {$$password}
</jdbc:sql>
</jdbc:statement>
</input>
L’attribut jdbc:op-type
est ignoré sur tous les éléments à l’exception du premier élément de l’opération.
Meilleures pratiques
Dans un souci de performance, il est préférable d’appeler une seule procédure stockée qui contient plusieurs instructions plutôt que d’incorporer plusieurs instructions SQL dans un document XML.
Exemple :
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement>
<jdbc:sql>CALL PROCEDURE set_fname('John', 'Joe',
'Jimmy')</jdbc:sql>
</jdbc:statement>
</input> est préférable à :
<input xmlns:jdbc="urn:dirxml:jdbc">
<add class-name="emp">
<add-attr name="lname">
<value>Doe</value>
</add-attr>
</add>
<jdbc:statement>
<jdbc:sql>UPDATE dirxml.emp SET fname = 'John'
WHERE empno = {$empno}</jdbc:sql>
</jdbc:statement>
<jdbc:statement>
<jdbc:sql>UPDATE dirxml.emp SET fname = 'Joe'
WHERE empno = {$empno}</jdbc:sql>
Configuration avancée du pilote
73
Novell Confidential Manual (FRA) 28 October 2003
</jdbc:statement>
<jdbc:statement>
<jdbc:sql>UPDATE dirxml.emp SET fname = 'Jimmy'
WHERE empno = {$empno}</jdbc:sql>
</jdbc:statement>
</input>
74
DirXML Driver for JDBC Implementation Guide (Guide d’implémentation du pilote DirXML pour JDBC)

公開リンクが更新されました
あなたのチャットの公開リンクが更新されました。