# Application de workflow EXECSQL

## Aperçu

L'application de workflow **EXECSQL** vous permet d'exécuter une ou plusieurs requêtes SQL dans un processus.&#x20;

Elle vous permet de récupérer des informations au travers de requêtes `SELECT` par exemple, afin de pouvoir utiliser le résultat dans des conditions du processus.&#x20;

## Mode de fonctionnement

* L'application EXECSQL requiert les paramètres `CONNECTION_NAME` (qui correspond au nom de la connexion) et `QUERY` (qui correspond à la requête à exécuter). <br>
* Il est possible de spécifier une ou plusieurs commandes par action EXECSQL. Pour ceci, les paramètres doivent être préfixés par `CMDx_`, où `x` correspond au numéro de la commande (p.ex. : `CMD1_`).<br>
* Les types de requête supportés sont `SELECT`, `INSERT`, `UPDATE`, `DELETE` , `SCALAR` et `PROCEDURE`.<br>
* L'application supporte la gestion des transactions SQL.<br>
* Il est possible d'utiliser une connexion globale pour plusieurs commandes. Pour ceci, il ne faut pas préfixer le paramètre `CONNECTION_NAME` par `CMDx_`. Il n'est pas possible d'utiliser une connexion globale et une connexion locale (p.ex. : `CONNECTION_NAME` et `CMD2_CONNECTION_NAME`).<br>
* Il est possible d'utiliser une transaction globale  pour plusieurs commandes. Pour ceci, il ne faut pas préfixer le paramètre `TRANSACTION` par `CMDx_`. Il n'est pas possible d'utiliser une transaction globale et une transaction locale (ex: `TRANSACTION` et `CMD2_TRANSACTION`). Il est nécessaire de définir une connexion globale pour pouvoir définir une transaction globale.<br>
* Des logs d'application sont disponibles. Ceux-ci peuvent être spécifiés en définissant la valeur du paramètre `ExecSqlLogLevel` dans le fichier `web.config` sur `0` pour désactiver la journalisation, `1` pour les logs d'erreur, `2` pour des logs d'informations ou `3` pour les logs de débogage; la valeur par défaut est `0`.

## Paramètres obligatoires

| Paramètre         | Type | Direction | Description                                                                                                                                     |
| ----------------- | ---- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONNECTION_NAME` | TEXT | IN        | <p>Nom de la connexion à utiliser<br></p><p>Le nom de la connexion doit être défini dans le fichier <code>web.config</code> de WorkflowGen.</p> |
| `QUERY`           | TEXT | IN        | Requête à exécuter                                                                                                                              |

## Paramètres facultatifs

### Général

| Paramètre              | Type    | Direction | Description                                                                                                                                                                                                                                                                           |
| ---------------------- | ------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TYPE`                 | TEXT    | IN        | <p>Type de la requête à exécuter</p><p></p><p>Les types supportés sont :</p><ul><li><code>SELECT</code> (par défaut)</li><li><code>INSERT</code></li><li><code>UPDATE</code></li><li><code>DELETE</code></li><li><code>SCALAR</code></li><li><code>PROCEDURE</code></li></ul>         |
| `TRANSACTION`          | TEXT    | IN        | <p>Lorsque défini sur <code>Y</code> , l'application déclenche une transaction SQL avant l'exécution de la requête et effectuera un commit ou rollback en fonction du résultat</p><p><strong>Par défaut :</strong> <code>N</code></p>                                                 |
| `ON_ERROR`             | TEXT    | IN        | <p>Lorsque défini sur <code>CATCH</code>, l'application ne retournera pas d'erreur à WorkflowGen. Ceci permettra de stocker un message d'erreur dans le paramètre <code>ERROR\_MESSAGE</code> et de continuer l'exécution.   <br><strong>Par défaut :</strong> <code>THROW</code></p> |
| `TIMEOUT`              | NUMERIC | IN        | <p>Indique le nombre de secondes à définir dans le temps d'exécution de la commande<br><strong>Par défaut :</strong> <code>30</code></p>                                                                                                                                              |
| `FORM_DATA`            | FILE    | INOUT     | Fichier `FORM_DATA` contenant la définition XML du processus                                                                                                                                                                                                                          |
| `FORM_DATA_GRIDVIEW`   | TEXT    | IN        | Identifiant du tableau à alimenter dans le `FORM_DATA`                                                                                                                                                                                                                                |
| `RESULT_CSV_SEPARATOR` | TEXT    | IN        | <p>Séparateur utilisé dans la valeur ou fichier CSV de retour</p><p><strong>Par défaut :</strong> <code>,</code> (virgule)</p>                                                                                                                                                        |

{% hint style="info" %}

* Si vous souhaitez alimenter un tableau à l'aide du paramètre `FORM_DATA_GRIDVIEW`, il est nécessaire que le contenu du `FORM_DATA` contiennent au moins le schéma XML.\
  &#x20;
* Si la première action du processus est une action EXECSQL, vous devez mettre une valeur par défaut dans le `FORM_DATA`, avec la définition du schéma.
  {% endhint %}

### Paramètres de requête

Il est possible de définir pour chaque requête des paramètres à utiliser lors de l'exécution. Les paramètres peuvent être définis de deux façons, soit en utilisant le préfixe `QUERY_PARAM`,  soit en utilisant un arobase (`@`).

#### 📌 Exemple

Vous pouvez utiliser `QUERY_PARAM_MyParam` ou `@MyParam`, où `MyParam` correspond au nom du paramètre défini dans la requête.&#x20;

| Paramètre                                     | Type | Direction | Description                                          |
| --------------------------------------------- | ---- | --------- | ---------------------------------------------------- |
| `QUERY`                                       | TEXT | IN        | `SELECT * FROM USERS WHERE LASTNAME = @UserLastname` |
| `QUERY_PARAM_UserLastName`  / `@UserLastName` | TEXT | IN        | `Doe`                                                |

### Paramètres de retour

#### Général

| Paramètre       | Type | Direction | Description                                                                                                                                        |
| --------------- | ---- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ERROR_MESSAGE` | TEXT | OUT       | Contient le message d'erreur dans le cas où la valeur du paramètre contient `CATCH` et qu'une exception est levée lors de l'exécution              |
| `RESULT_COMMIT` | TEXT | OUT       | <p>Indique si un <code>commit</code> a été exécuté sur la transaction<br><strong>Valeurs possibles :</strong> <code>Y</code> ou <code>N</code></p> |

#### Requête `SELECT`

| Paramètre               | Type                                     | Direction | Description                                                                                                                                                                                                                                                                         |
| ----------------------- | ---------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `RESULT_ROWx_fieldName` | <p>TEXT</p><p>NUMERIC</p><p>DATETIME</p> | OUT       | <p>Contient la valeur de la colonne <code>fieldName</code> pour la ligne <code>x</code></p><p></p><p>Vous devez remplacer <code>fieldname</code> par votre nom de colonne (p.ex. : <code>LASTNAME</code>) et <code>x</code> par le numéro de la ligne (p.ex. : <code>2</code>).</p> |
| `RESULT_ROW_fieldName`  | <p>TEXT</p><p>NUMERIC</p><p>DATETIME</p> | OUT       | Contient la valeur de la colonne `fieldName` pour la première ligne retournée                                                                                                                                                                                                       |
| `RESULT_JSON`           | TEXT                                     | OUT       | Contient le résultat de la requête au format `JSON`                                                                                                                                                                                                                                 |
| `RESULT_JSON_FILE`      | FILE                                     | OUT       | Contient le résultat de la requête au format `JSON` stocké dans un fichier `.json`                                                                                                                                                                                                  |
| `RESULT_XML`            | TEXT                                     | OUT       | Contient le résultat de la requête au format `XML`                                                                                                                                                                                                                                  |
| `RESULT_XML_FILE`       | FILE                                     | OUT       | Contient le résultat de la requête au format `XML` stocké dans un fichier `.xml`                                                                                                                                                                                                    |
| `RESULT_CSV`            | TEXT                                     | OUT       | <p>Contient le résultat de la requête au format <code>CSV</code></p><p></p><p>Les données sont séparées suivant le séparateur défini dans le paramètre <code>RESULT\_CSV\_SEPARATOR</code></p>                                                                                      |
| `RESULT_CSV_FILE`       | FILE                                     | OUT       | <p>Contient le résultat de la requête au format <code>CSV</code> stocké dans un fichier <code>.csv</code></p><p></p><p>Les données sont séparées suivant le séparateur défini dans le paramètre <code>RESULT\_CSV\_SEPARATOR</code></p>                                             |

#### Requête `SCALAR`

| Paramètre | Type    | Direction | Description                                                   |
| --------- | ------- | --------- | ------------------------------------------------------------- |
| `RESULT`  | NUMERIC | OUT       | Contient le résultat numérique d'une requête de type `SCALAR` |

## Exemples

### Requête `SELECT`

#### Stockage du retour dans des données

| Paramètre               | Type | Direction | Valeur                                                                                                                                                                 |
| ----------------------- | ---- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONNECTION_NAME`       | TEXT | IN        | `MainDbSource`                                                                                                                                                         |
| `QUERY`                 | TEXT | IN        | `SELECT LASTNAME, FIRSTNAME, USERNAME FROM USERS`                                                                                                                      |
| `RESULT_JSON`           | TEXT | OUT       | `{ "TABLE":[ { "LASTNAME":"Administrator", "FIRSTNAME":"WorkflowGen", "USERNAME":"wfgen_admin" }, { "LASTNAME":"Doe", "FIRSTNAME":"John", "USERNAME":"john.doe" } ] }` |
| `RESULT_JSON_FILE`      | FILE | OUT       | `result.json`                                                                                                                                                          |
| `RESULT_CSV`            | TEXT | OUT       | <p><code>"LASTNAME","FIRSTNAME","USERNAME" "Administrator","WorkflowGen","wfgen\_admin"</code></p><p><code>"Doe","John","john.doe"</code></p>                          |
| `RESULT_CSV_FILE`       | FILE | OUT       | `result.csv`                                                                                                                                                           |
| `RESULT_ROW_LASTNAME`   | TEXT | OUT       | `Administrator`                                                                                                                                                        |
| `RESULT_ROW1_FIRSTNAME` | TEXT | OUT       | `WorkflowGen`                                                                                                                                                          |
| `RESULT_ROW2_USERNAME`  | TEXT | OUT       | `john.doe`                                                                                                                                                             |

#### Alimentation d'un tableau

| Paramètre            | Type | Direction | Valeur                                                                                                                        |
| -------------------- | ---- | --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `CONNECTION_NAME`    | TEXT | IN        | `MainDbSource`                                                                                                                |
| `QUERY`              | TEXT | IN        | `SELECT LASTNAME as REQUEST_GRID_LASTNAME, FIRSTNAME as REQUEST_GRID_FIRSTNAME, USERNAME as REQUEST_GRID_USERNAME FROM USERS` |
| `FORM_DATA`          | FILE | INOUT     | `FORM_DATA`                                                                                                                   |
| `FORM_DATA_GRIDVIEW` | TEXT | IN        | `REQUEST_GRID`                                                                                                                |

{% hint style="info" %}
Dans le cas où EXECSQL est la première action du processus, vous devez définir une valeur par défaut pour la donnée `FORM_DATA` contenant le schéma du tableau comme dans l'exemple ci-dessous :

```markup
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
    <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
            <xs:complexType>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="Table1">
                        <xs:complexType>
                            <xs:sequence>
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                    <xs:element name="REQUEST_GRID">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="REQUEST_GRID_LASTNAME" type="xs:string" minOccurs="0"/>
                                <xs:element name="REQUEST_GRID_FIRSTNAME" type="xs:string" minOccurs="0"/>
                                <xs:element name="REQUEST_GRID_USERNAME" type="xs:string" minOccurs="0"/>
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                </xs:choice>
            </xs:complexType>
        </xs:element>
    </xs:schema>
    <Table1></Table1>
</NewDataSet>
```

{% endhint %}

### Requête `INSERT`

| Paramètre                 | Type    | Direction | Valeur                                                                                            |
| ------------------------- | ------- | --------- | ------------------------------------------------------------------------------------------------- |
| `CONNECTION_NAME`         | TEXT    | IN        | `MainDbSource`                                                                                    |
| `TYPE`                    | TEXT    | IN        | `INSERT`                                                                                          |
| `QUERY`                   | TEXT    | IN        | `INSERT INTO WFCATEGORY (ID_CATEGORY,NAME,DESCRIPTION) VALUES (@IdCategory, @Name, @Description)` |
| `QUERY_PARAM_IdCategory`  | NUMERIC | IN        | `1`                                                                                               |
| `QUERY_PARAM_Name`        | TEXT    | IN        | `NomCategorie`                                                                                    |
| `QUERY_PARAM_Description` | TEXT    | IN        | `Description de la catégorie`                                                                     |

Voici une autre possibilité pour les paramètres de requête :

| Paramètre         | Type    | Direction | Valeur                                                                                            |
| ----------------- | ------- | --------- | ------------------------------------------------------------------------------------------------- |
| `CONNECTION_NAME` | TEXT    | IN        | `MainDbSource`                                                                                    |
| `TYPE`            | TEXT    | IN        | `INSERT`                                                                                          |
| `QUERY`           | TEXT    | IN        | `INSERT INTO WFCATEGORY (ID_CATEGORY,NAME,DESCRIPTION) VALUES (@IdCategory, @Name, @Description)` |
| `@IdCategory`     | NUMERIC | IN        | `1`                                                                                               |
| `@Name`           | TEXT    | IN        | `NomCategorie`                                                                                    |
| `@Description`    | TEXT    | IN        | `Description de la catégorie`                                                                     |

### Requête `UPDATE`

| Paramètre                | Type    | Direction | Valeur                                                               |
| ------------------------ | ------- | --------- | -------------------------------------------------------------------- |
| `CONNECTION_NAME`        | TEXT    | IN        | `MainDbSource`                                                       |
| `TYPE`                   | TEXT    | IN        | `UPDATE`                                                             |
| `QUERY`                  | TEXT    | IN        | `UPDATE WFCATEGORY SET NAME = @Name WHERE ID_CATEGORY = @IdCategory` |
| `QUERY_PARAM_IdCategory` | NUMERIC | IN        | `1`                                                                  |
| `QUERY_PARAM_Name`       | TEXT    | IN        | `NouveauNomCategorie`                                                |

### Requête `DELETE`

| Paramètre                | Type    | Direction | Valeur                                                   |
| ------------------------ | ------- | --------- | -------------------------------------------------------- |
| `CONNECTION_NAME`        | TEXT    | IN        | `MainDbSource`                                           |
| `TYPE`                   | TEXT    | IN        | `DELETE`                                                 |
| `QUERY`                  | TEXT    | IN        | `DELETE FROM WFCATEGORY WHERE ID_CATEGORY = @IdCategory` |
| `QUERY_PARAM_IdCategory` | NUMERIC | IN        | `1`                                                      |

### Procédure stockée

| Paramètre                 | Type    | Direction | Valeur                        |
| ------------------------- | ------- | --------- | ----------------------------- |
| `CONNECTION_NAME`         | TEXT    | IN        | `MainDbSource`                |
| `TYPE`                    | TEXT    | IN        | `PROCEDURE`                   |
| `QUERY`                   | TEXT    | IN        | `INSERT_CATEGORY`             |
| `QUERY_PARAM_ID_CATEGORY` | NUMERIC | IN        | `1`                           |
| `QUERY_PARAM_NAME`        | TEXT    | IN        | `NomCategorie`                |
| `QUERY_PARAM_DESCRIPTION` | TEXT    | IN        | `Description de la catégorie` |

{% hint style="info" %}
Le type de requête `PROCEDURE` ne permet pas de retourner de valeur. Si vous souhaitez retourner une valeur, il faut utiliser le type `SELECT`.
{% endhint %}

| Paramètre          | Type    | Direction | Valeur                            |
| ------------------ | ------- | --------- | --------------------------------- |
| `CONNECTION_NAME`  | TEXT    | IN        | `MainDbSource`                    |
| `TYPE`             | TEXT    | IN        | `SELECT`                          |
| `QUERY`            | TEXT    | IN        | `EXEC GET_USER @USERNAME = @User` |
| `QUERY_PARAM_User` | NUMERIC | IN        | `wfgen_admin`                     |

### Requête `SCALAR`

| Paramètre         | Type    | Direction | Valeur                       |
| ----------------- | ------- | --------- | ---------------------------- |
| `CONNECTION_NAME` | TEXT    | IN        | `MainDbSource`               |
| `TYPE`            | TEXT    | IN        | `SCALAR`                     |
| `QUERY`           | TEXT    | IN        | `SELECT COUNT(*) FROM USERS` |
| `RESULT`          | NUMERIC | OUT       | `2`                          |

### Lancement de plusieurs requêtes

| Paramètre                      | Type    | Direction | Valeur                                                                                            |
| ------------------------------ | ------- | --------- | ------------------------------------------------------------------------------------------------- |
| `CONNECTION_NAME`              | TEXT    | IN        | `MainDbSource`                                                                                    |
| `CMD1_TYPE`                    | TEXT    | IN        | `INSERT`                                                                                          |
| `CMD1_QUERY`                   | TEXT    | IN        | `INSERT INTO WFCATEGORY (ID_CATEGORY,NAME,DESCRIPTION) VALUES (@IdCategory, @Name, @Description)` |
| `CMD1_QUERY_PARAM_IdCategory`  | NUMERIC | IN        | `1`                                                                                               |
| `CMD1_QUERY_PARAM_Name`        | TEXT    | IN        | `NomCategorie`                                                                                    |
| `CMD1_QUERY_PARAM_Description` | TEXT    | IN        | `Description de la catégorie`                                                                     |
| `CMD2_QUERY`                   | TEXT    | IN        | `SELECT NAME FROM WFCATEGORY WHERE ID_CATEGORY = @IdCategory`                                     |
| `CMD2_@IdCategory`             | NUMERIC | IN        | `1`                                                                                               |
| `CMD2_RESULT_ROW_NAME`         | TEXT    | OUT       | `NomCategorie`                                                                                    |

### Requêtes avec transactions et gestion des erreurs

| Paramètre            | Type | Direction | Valeur                                                                                              |
| -------------------- | ---- | --------- | --------------------------------------------------------------------------------------------------- |
| `CONNECTION_NAME`    | TEXT | IN        | `MainDbSource`                                                                                      |
| `CMD1_TYPE`          | TEXT | IN        | `INSERT`                                                                                            |
| `CMD1_QUERY`         | TEXT | IN        | `INSERT INTO WFCATEGORY (ID_CATEGORY,NAME,DESCRIPTION) VALUES (1, "Nom", "Description")`            |
| `CMD1_TRANSACTION`   | TEXT | IN        | `Y`                                                                                                 |
| `CMD1_ON_ERROR`      | TEXT | IN        | `CATCH`                                                                                             |
| `CMD1_COMMIT`        | TEXT | OUT       | `Y`                                                                                                 |
| `CMD1_ERROR_MESSAGE` | TEXT | OUT       | `NULL`                                                                                              |
| `CMD2_TYPE`          | TEXT | IN        | `INSERT`                                                                                            |
| `CMD2_QUERY`         | TEXT | IN        | `INSERT INTO WFCATEGORY (ID_CATEGORY,NAME,DESCRIPTION) VALUES (1, "AutreNom", "Autre description")` |
| `CMD2_TRANSACTION`   | TEXT | IN        | `Y`                                                                                                 |
| `CMD2_ON_ERROR`      | TEXT | IN        | `CATCH`                                                                                             |
| `CMD2_COMMIT`        | TEXT | OUT       | `N`                                                                                                 |
| `CMD2_ERROR_MESSAGE` | TEXT | OUT       | `Cannot insert duplicate key in object 'dbo.WFCATEGORY'. The duplicate key value is (1).`           |
