# Application de workflow XMLTODATABASE

## Aperçu  <a href="#apercu" id="apercu"></a>

L’application de workflow **XMLTODATABASE** vous permet d’exporter les données depuis un document XML vers une ou plusieurs bases de données. C’est une application asynchrone qui ne nécessite pas d’action d’un utilisateur. La configuration des transactions SQL est effectuée via un fichier XML qui active les requêtes SQL sur des sources de données ODBC ou OLEDB.

## Mode de fonctionnement

Le moteur WorkflowGen appelle l’application XMLTODATABASE avec le contexte et les paramètres afin d’obtenir les éléments suivants :

* Le document XML contentant les données à exporter<br>
* Le fichier de transaction contenant :
  * Les informations de connexion à la base de données
  * Les informations de localisation des données dans le document XML contenant les données (en utilisant des XPath)

Après que XMLTODATABASE ait rassemblé toutes ces informations, elle est prête à exporter, et retourne ensuite le contexte à WorkflowGen afin que le workflow puisse continuer.

## Description du fichier XML

### Aperçu

Le document de transactions XML spécifie les commandes SQL qui seront exécutées sur les bases de données. Il est utilisé pour deux fonctions principales: la connexion à la base de données et le mappage des champs de la requête aux champs du document de données XML. N'oubliez pas que le document de données XML (généralement nommé `FORM_DATA`) peut être construit de plusieurs façons. Pour cette raison, les XPath sont utilisés pour mapper les champs de base de données aux champs XML.

### Structure

Toute activité XMLTODATABASE peut avoir un nombre illimité de bases de données et un nombre illimité de commandes par base de données. Cela signifie que l'exportation peut être effectuée vers plusieurs bases de données et que chaque base de données peut avoir plusieurs commandes.

#### 📌 Exemple de fichier de transactions XML

```markup
<transactions>
    <transaction name="">
        <databases>
            <database name="" connectionstring="" provider="" transaction="">
                <command type="" loop="" xpath="">
                [REQUÊTE ICI]
                </command>
            </database>
        </databases>
    </transaction>
</transactions>
```

### Attributs

#### Nœud `transaction`

| **Attribut** | **Description**                                                                                                                                                                                                                                                                                                                                                                 |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`       | <p>Utilisé pour lier la transaction à l’action (activité) XMLTODATABASE</p><p></p><p>Dans WorkflowGen, un paramètre TRANSACTION (texte) devra être défini pour chaque action (activité) XMLTODATABASE. Le texte saisi dans le paramètre doit correspondre avec le nom de l’attribut de la transaction afin d’utiliser la bonne transaction pour la bonne action (activité).</p> |

#### Nœud `database`

| **Attribut**           | **Description**                                                                                                                                                                                                                                                                                        |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`                 | Le nom de la base de données utilisée pour l’exportation                                                                                                                                                                                                                                               |
| `connectionstringname` | Contient le nom d'une chaîne de connexion gérée de manière centralisée dans le fichier `web.config` de WorkflowGen (voir l'[exemple](#exemple-de-nom-de-chaine-de-connexion) ci-dessous)                                                                                                               |
| `connectionstring`     | Contient le `ConnectionString` pour la connexion à la base de données                                                                                                                                                                                                                                  |
| `provider`             | <p>Utilisé pour informer XMLTODATABASE du espace de noms à utiliser pour accéder à la base de données (<code>System.Dta.OleDb</code> ou <code>System.Data.Odbc</code>)</p><p></p><p>✏️ <strong>Note :</strong> Cet attribut ne peut être utilisé qu'avec l'attribut <code>connectionstring</code>.</p> |
| `transaction`          | Utilisé pour informer XMLTODATABASE de l’utilisation ou non d’une transaction pour l’exportation vers une base de données (valeurs : `yes` ou `no`)                                                                                                                                                    |

{% hint style="info" %}

* Vous pouvez utiliser l'attribut `connectionstringnam`e ou l'attribut `connectionstring`, mais pas les deux.<br>
* Il est fortement recommandé d'utiliser un nom de connexion plutôt qu'une chaîne de connexion pour simplifier la gestion multi-environnement.<br>
  {% endhint %}

#### Nœud `command`

| **Attribut** | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`       | <p>Utilisé pour informer XMLTODATABASE du type de commande exécuté</p><p></p><p>Les valeurs possibles peuvent être n'importe quelle commande SQL valide, sauf si elle appelle une procédure stockée. Dans ce cas, le type doit être <code>PROCEDURE</code>.</p>                                                                                                                                                                                                                                                                                                                                                                              |
| `loop`       | <p>Utilisé pour exécuter un lot de commandes en utilisant toutes les valeurs renvoyées par le XPath dans l'attribut <code>xpath</code> du nœud <code>command</code> (valeurs possibles: <code>yes</code> ou <code>no</code>)</p><p></p><p>Par exemple, si l’attribut <code>loop</code> est réglé sur <code>yes</code> et si un XPath dans la requête retourne 10 résultats, le XPath de la commande sera exécutée 10 fois (une fois pour chaque résultat). Si l’attribut <code>loop</code> est réglé sur <code>no</code>, la commande sera exécutée une seule fois avec le retour du premier nœud pour le XPath contenu dans la requête.</p> |
| `xpath`      | Utilisé pour factoriser une partie des XPath utilisés dans la requête.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

### Exemple de nom de chaîne de connexion

#### Fichier de transactions XMLTODATABASE :

```markup
...
<database name="MYDB" connectionstringname="MYDBSOURCE">
..
```

#### Fichier `web.config` :

```markup
..
<connectionStrings>
    <add name="MYDBSOURCE" connectionString="Data Source=MYSQLSERVER;Initial Catalog=MYDB;User ID=user;password=pwd;" providerName="System.Data.SqlClient"/>
<connectionString>
...
```

## Emplacement du fichier XML de transactions

Il y a quatre possibilités différentes pour stocker la définition de la transaction d’une action de type XMLTODATABASE. Dans tous ces cas, la transaction doit être définie ainsi :

```markup
<transactions>
    <transaction name="MY_TRANSACTION">
        ...
    </transaction>
</transactions>
```

Pour trouver la définition de sa transaction une action de type XMLTODATABASE va effectuer une recherche dans l’ordre suivant :

1. Dans un paramètre nommé `TRANSACTIONS_TEXT`.<br>
2. Dans un fichier dont le chemin est dans un paramètre nommé `TRANSACTIONS_FILE`.<br>
3. Dans un fichier nommé `MyTransaction.xml` placé dans le dossier `..\App_Data\Files\XmlToDatabase`.<br>
4. Dans un fichier nommé `Transactions.xml` placé dans le dossier `..\App_Data\Files\XmlToDatabase`.

L’ordre de priorité est donc :

1. Le paramètre `TRANSACTIONS_TEXT`.<br>
2. Le paramètre `TRANSACTIONS_FILE`.<br>
3. Le fichier `MyTransaction.xml`.<br>
4. Le fichier `Transactions.xml`.

### Définition d’une transaction dans le fichier commun

Le fichier de transaction commun nommé `Transactions.xml` se trouve dans le répertoire `\wfgen\App_Data\Files\XmlToDatabase`. L’application XMLTODATABASE effectue une recherche dans ce fichier pour trouver votre transaction.

L’action de type XMLTODATABASE contient les paramètres suivants :

* `TRANSACTION` : Direction IN, type texte<br>
* `XML` : Direction IN, type fichier

### Définition d’une transaction dans un fichier spécifique

Si la transaction ne se trouve pas dans le fichier `Transactions.xml`, l’application XMLTODATABASE effectue une recherche pour un fichier XML du même nom que votre transaction. La transaction devrait être créée dans le fichier `MyTransaction.xml`.

L’action de type XMLTODATABASE a les mêmes paramètres que pour un fichier commun.

{% hint style="info" %}
Vous pouvez déplacer la définition de transaction d’un fichier commun à un fichier spécifique sans avoir à modifier la définition de processus en supprimant la transaction du fichier `Transactions.xml` et ensuite le copier dans un fichier du même nom que votre transaction.
{% endhint %}

### Dans une donnée de type fichier

Si vous ne pouvez pas accéder au dossier `..\App_Data` du serveur Web, ou si vous souhaitez inclure votre transaction dans la définition de votre processus (pour pouvoir l’exporter et le partager par fichier XPDL), vous pouvez écrire votre transaction dans une donnée de type fichier de votre processus. Pour ce faire :

1. Créez une donnée de type fichier contenant votre transaction.<br>
2. Éditez votre action de type XMLTODATABASE puis ajoutez un nouveau paramètre nommé `TRANSACTIONS_FILE` et liez-le à la donnée précédemment créée.

### Dans une donnée de type texte

Si vous ne pouvez pas accéder au dossier `..\App_Data` du serveur Web, ou si vous souhaitez inclure votre transaction dans la définition de votre processus (pour pouvoir l’exporter et le partager par fichier XPDL), vous pouvez écrire votre transaction dans une donnée de type texte de votre processus.

{% hint style="info" %}
À partir de la version 7.15.0 de WorkflowGen, la transaction XML contenue dans les données de processus de type TEXT n'a plus de limite de 4 000 caractères pour la base de données MS SQL Server.
{% endhint %}

Pour ce faire :

1. Créez une donnée de type texte contenant votre transaction.<br>
2. Éditez votre action de type XMLTODATABASE puis ajoutez un nouveau paramètre nommé `TRANSACTIONS_TEXT` et liez-le à la donnée précédemment créée.

## Format des champs dates et numériques  <a href="#format-champs-dates-et-numeriques" id="format-champs-dates-et-numeriques"></a>

Vous pouvez indiquer à l’application la liste des champs qui doivent avoir un format date ou numérique.

Les paramètres supplémentaires suivants peuvent être utilisés dans les actions qui utilisent XMLTODATABASE:

| **Paramètre**        | **Description**                                                                                                           |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `XML_FIELDS_DATE`    | Liste des champs de type date; doit contenir une liste d'expressions XPath séparées par des caractères `,`(virgule)       |
| `XML_FIELDS_NUMERIC` | Liste des champs de type numérique; doit contenir une liste d'expressions XPath séparées par des caractères `,` (virgule) |
| `XML_LOCALE`         | Code de culture à utiliser pour formater les valeurs date et numériques (ex. : `fr-FR` ou `en-US`)                        |

#### Format date généré dans les requêtes SQL

Les champs de type date sont formatés comme ci-après : `yyyy-mm-dd hh:MM:ss`

#### Format numérique généré dans les requêtes SQL

Les champs de type numérique sont formatés comme ci-après : `XXXX.XX`

#### 📌 Exemple

* **Règle :** Tous les nœuds trouvés dans le document XML avec le nom `REQUEST_DATE` et le nœud spécifique situé à `/MyData/MonExemple/Champ_Date` seront formatés comme des dates.
  * **Méthode :** `XML_FIELDS_DATE = //*/REQUEST_DATE, /MyData/MyExample/Date_Field`

## Détails de l’exécution de la transaction  <a href="#details-execution-transaction" id="details-execution-transaction"></a>

Les commandes SQL peuvent être exécutées dans des transactions. Si des erreurs interviennent, un « rollback » est exécuté et l’état initial de la base de données est restauré. La valeur de l’attribut transaction du nœud database doit être réglée sur `yes`.

Si la transaction agit sur plusieurs bases de données, l’exécution des commandes sera multi-transactionnelle : si une erreur intervient dans une commande d’une des bases de données, une restauration générale sera exécutée sur la transaction en question.

## Mode test

Les transactions peuvent être testées avant d’être lancées sur les bases de données. La valeur de la constante `XmlToDatabaseTestMode` dans le fichier de configuration doit être réglée sur `Y`.

{% hint style="info" %}
Si cette constante est réglée sur `yes` et que vous avez spécifié l’usage des transactions sur les nœuds de la base de données, les transitions ne seront pas confirmées (committed) à la fin de l’exécution.
{% endhint %}

## Description du fichier log

Si le paramètre `XmlToDatabaseEnableTrace` dans le fichier `web.config` du service Web est réglé sur `Y`, un fichier de log sera généré dans le répertoire `\wfgen\App_Data\LogFiles\XmlToDatabase`.

Les entrées du log sont au format suivant :

`Date; [Database name;] Transaction name; SQL query; Execution result`

Les valeurs `execution result` sont :

* Si la requête a été exécutée avec succès : `OK` <br>
* Si une erreur est intervenue : `ERROR : code erreur – description`

#### 📌 Exemples

```
02/12/2020 4:41:23 PM; ACCESS; TEST_TRANS; INSERT INTO DATA ...; OK
```

```markup
02/12/2020 4:41:24 PM; ACCESS; TEST_TRANS; DELETE FROM DATA2; ERROR: 1234-Table was not found
```

## Erreurs d’exécution possibles  <a href="#erreurs-execution-possibles" id="erreurs-execution-possibles"></a>

Les erreurs suivantes peuvent intervenir lors de l’exécution des transactions :

| **Erreur**                                                                                                                                                     | **Cause**                                                                                                                                                                                                                                                                                      |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Le paramètre du fichier XML est manquant (The XML file parameter is missing)                                                                                   | Le paramètre obligatoire XML a une valeur nulle ou n’est pas défini.                                                                                                                                                                                                                           |
| Le contexte XML ne peut pas être vide (The XML context cannot be empty)                                                                                        | L’application XMLTODATABASE doit recevoir un contexte de WorkflowGen; elle ne peut pas être utilisée sans être associée à un processus WorkflowGen.                                                                                                                                            |
| Erreur d’analyse XML (1) (XML parsing error (1))                                                                                                               | Le paramètre XML point vers un fichier XML invalide.                                                                                                                                                                                                                                           |
| Erreur d’analyse XML (2) (XML parsing error (2))                                                                                                               | Le fichier de transaction XML est un fichier XML invalide.                                                                                                                                                                                                                                     |
| Erreur d’analyse XML. L’attribut du provider est obligatoire. (XML parsing error. The provider attribute is required.)                                         | L’attribut provider de la base de données n’est pas présent dans la transaction.                                                                                                                                                                                                               |
| Impossible de confirmer les transactions (Unable to commit transactions)                                                                                       | L’opération de « commit » n’a pas réussie.                                                                                                                                                                                                                                                     |
| Erreur lors de l’ouverture du fichier de log (Error while opening log file)                                                                                    | Le fichier de log ne peut pas être ouvert.                                                                                                                                                                                                                                                     |
| Le paramètre `TRANSACTION` est manquant (The `TRANSACTION` parameter is missing)                                                                               | Le paramètre obligatoire `TRANSACTION` a une valeur nulle ou n’est pas défini.                                                                                                                                                                                                                 |
| La définition de la transaction n’a par été trouvée (The definition of the transaction has not been found)                                                     | Le fichier `transactions.xml` ne possède pas de transaction avec un nom d’attribut correspondant avec la valeur du paramètre `TRANSACTION`.                                                                                                                                                    |
| Instruction SQL invalide : le paramètre n’a pas été trouvé (SQL Instruction not valid: the parameter has not been found)                                       | Le PARAM {nom du paramètre} n’a pas été trouvé.                                                                                                                                                                                                                                                |
| Erreur d’analyse XML. L’attribut `connectionstring` est obligatoire. (XML parsing error. The `connectionstring` attribute is required)                         | <p>L’attribut <code>connectionstring</code> n’a pas été spécifié dans le nœud de la base de données.</p><p></p><p>✏️ <strong>Note :</strong> Il est fortement recommandé d'utiliser un nom de connexion plutôt qu'une chaîne de connexion pour simplifier la gestion multi-environnements.</p> |
| Le champ XML a été déclaré en tant que date mais sa valeur est invalide (The XML field was expected to be date, but its value is not valid)                    | Un des XPath indiqué dans `XML_FIELDS_DATE` fait référence à un champ qui n’est pas une date.                                                                                                                                                                                                  |
| Le champ XML a été déclaré en tant que numérique mais sa valeur est invalide (The XML field was expected to be numeric, but its value is not valid)            | Un des XPath indiqué dans `XML_FIELDS_NUMERIC` fait référence à un champ qui n’est pas numérique.                                                                                                                                                                                              |
| Le XPath n’est pas une expression XPath valide (The XPath is not a valid XPath expression)                                                                     | Un des XPath indiqué dans le fichier de transaction n'est pas une expression XPath valide.                                                                                                                                                                                                     |
| Le XPath passé en paramètre n’est pas une expression XPath valide (The XPath passed as a parameter is not a valid XPath expression)                            | Un des XPath dans les paramètres `XML_FIELDS_DATE` ou `XML_FIELDS_NUMERIC` n’est pas une expression XPath valide.                                                                                                                                                                              |
| Erreur lors du chargement du fichier XML : fichier non trouvé (Error while loading the XML file: File was not found)                                           | Le paramètre XML ne pointe pas vers un fichier XML.                                                                                                                                                                                                                                            |
| Erreur de connexion à la base de données (Database connection error)                                                                                           | La connexion à la base de données ne peut pas être établie. Vérifiez la validité de la chaîne de connexion contenue dans l’attribut `connectionstring` du nœud de la base de données.                                                                                                          |
| Erreur lors de l’exécution de la commande SQL (Error during the execution of the SQL command)                                                                  | L’exécution de la commande SQL a échoué. Vérifiez la syntaxe de la commande SQL correspondante.                                                                                                                                                                                                |
| Erreur lors de l’exécution de la commande SQL loop (Error during the execution of the SQL loop command)                                                        | L’exécution de la commande SQL a échoué. Vérifiez la syntaxe de la commande SQL correspondante.                                                                                                                                                                                                |
| Instruction SQL non valide : le champ XML n’a pas été trouvé (SQL instruction not valid: the XML field has not been found)                                     | Une des expressions XPath utilisée dans vos paramètres de la commande ne retourne aucun champ. Vérifiez la syntaxe de vos expressions XPath .                                                                                                                                                  |
| Le code culture pour le fichier XML dans le paramètre `XML_LOCALE` n’est pas valide (The culture code for the XML file in the param `XML_LOCALE` is not valid) | Vérifiez que le paramètre `XML_LOCALE` possède le bon format (ex. : `fr-FR` ou `en-US`)                                                                                                                                                                                                        |

## Exemples d’export  <a href="#exemples-export" id="exemples-export"></a>

#### 📌 Exemple 1

Structure du fichier XML :

```markup
<data>
    <request_number>1</request_number>
    <request_first_name>John</request_first_name>
    <request_last_name>Smith</request_last_name>
</data>
```

Le nœud `command` pourrait ressembler à ceci :

```markup
<command type="INSERT" loop="no" xpath="/data/">
    INSERT INTO EXAMPLE (request_number, request_first_name, request_last_name, request_date)
    VALUES (
        {XPATH:request_number},
        {'XPATH:request_first_name'},   
        {'XPATH:request_last_name'},
        {'PARAM:REQUEST_DATE'})
</command>
```

La balise `XPATH:` dans la requête sera remplacée par `/data/` qui est la valeur de l’attribut XPath.

La balise `PARAM:` est utilisée pour identifier un paramètre WorkflowGen à la place d’utiliser un champ XML.

{% hint style="info" %}

* Les XPath ne retournant pas de nœuds utiliseront les valeurs `null`.<br>
* Il n’est pas possible d’utiliser le XPath factorisé en utilisant `XPATH::` à la place de `XPATH:`.
  {% endhint %}

#### 📌 Exemple 2

Voici un exemple plus complexe utilisant la propriété `loop`.

Structure du fichier XML :

```markup
<Library>
    <publishers>
        <publisher>Grasset</publisher>
    </publishers>
    <AUTHORS>
        <author id="100">
            <name>Stephen King</name>
            <description>Auteur de livres d’horreur</description>
            <birth_date>1947-09-21</birth_date>
        </author>
        <author id="200">
            <name>Jean Sologne</name>
            <description>Description de l’auteur</description>
            <birth_date>1972-06-06</birth_date>
        </author>
    </AUTHORS>
    <BOOKS>
        <book id="38">
            <title>Titre du livre no°38</title>
            <description>Description du livre n°38</description>
            <author id="100"/>
        </book>
        <book id="39">
            <title>Titre du livre n°39</title>
            <description>Description du livre n°39</description>
            <author id="200"/>
        </book>
        <book id="40">
            <title>Titre du livre n°40</title>
            <description />   // Insérera une valeur NULL automatiquement</span>
            <author id=""/>   // Insérera une valeur NULL automatiquement</span>
        </book>
    </BOOKS>
</Library>
```

Le nœud `command` pourrait ressembler à ceci :

```markup
<command loop="yes" type="INSERT" xpath="/Library/AUTHORS/">
    INSERT INTO AUTHORS
        ([AUTHOR_ID],[AUTHOR_NAME],[AUTHOR_DESC],[AUTHOR_PUBLISHER])
    VALUES ({XPATH:author/@id},
        '{XPATH:author/name}',
        '{XPATH:author/description}',
        '{XPATH::/Library/publishers/publisher}’ )
</command>
<command loop="yes" type="INSERT" xpath="/Library/BOOKS/">
    INSERT INTO BOOKS 
        ([BOOK_ID],[BOOK_TITLE],[BOOK_DESCRIPTION],[BOOK_AUTHOR_ID])
    VALUES ({XPATH:book/@id},
        '{XPATH:book/title}',
        '{XPATH:book/description}',
        '{XPATH:book/author/@id}')
</command>
```

{% hint style="info" %}
Vous devez utiliser **deux** caractères `:` (deux points) lorsque vous ne voulez pas utiliser le XPath factorisé dans le nœud `command` (voir l’exemple ci-dessus).
{% endhint %}
