Exécution de scripts SQL (FireDAC)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Utilisation des commandes (FireDAC)

Rubriques

Rubrique Description
Commandes de contrôle de scripts SQL TFDScript et l'utilitaire FDExecutor supportent une liste étendue de commandes de contrôle d'exécution de scripts SQL.
Développement de commandes personnalisées TFDScript permet l'extension de l'ensemble de commandes de contrôle d'exécution de scripts SQL.

Informations générales

Un script SQL est un ensemble de commandes séparées de scripts SQL, de contrôle d'exécution et de consignation. Les scripts SQL sont utiles pour les tâches de maintenance principales, comme la création d'objets SQL, la suppression, la mise à niveau, le chargement initial des données, et ainsi de suite.

De nombreux SGBD exécutent plusieurs commandes SQL sous forme de groupe via un seul appel à TFDQuery.ExecSQL, mais cela comporte des limitations. Voici les différences entre le script SQL et le groupe de commandes SQL :

  • Le script permet d'utiliser toutes les commandes SQL possibles dans un seul script. Le groupe peut comporter des limitations, en fonction du SGBD. Par exemple, un bloc PL/SQL anonyme Oracle ne peut pas contenir de commande DDL.
  • Le script peut être divisé en plusieurs transactions. Le groupe doit être réalisé en une seule transaction.
  • Le script permet d'utiliser des commandes non SQL et personnalisées. Le groupe inclut uniquement les commandes comprises par le SGBD.
  • Le script peut être divisé en index. Le groupe peut appeler des procédures stockées en tant que blocs de code séparés.
  • L'exécution du script est entièrement contrôlée par le client. L'exécution du groupe est contrôlée uniquement par le SGBD.
  • Contrairement à l'exécution du groupe, l'exécution du script peut être consignée.
  • Contrairement au groupe, le script fournit des informations sur la progression de l'exécution.

TFDScript fournit de nombreux avantages par rapport aux utilitaires standard, comme la capacité d'être entièrement intégré à l'application FireDAC et d'étendre l'ensemble de commandes avec des commandes de script personnalisées. Le composant TFDScript reconnaît plusieurs syntaxes de scripts SQL standard, parmi lesquels :

  • Oracle SQL*Plus ;
  • Microsoft ISQL/OSQL ;
  • MySQL mysql.exe/mysqldump.exe ;
  • Firebird/InterBase ISQL.

Par exemple, le script Firebird suivant crée une base de données et peut être exécuté en utilisant TFDScript :

 SET SQL DIALECT 3;
 SET NAMES UTF8;
 SET CLIENTLIB 'C:\fb25\bin\fbclient.dll';
 CREATE DATABASE 'E:\Test2.ib'
   USER 'sysdba' PASSWORD 'masterkey'
   PAGE_SIZE 16384
   DEFAULT CHARACTER SET NONE;
 
 SET TERM ^ ;
 
 CREATE PROCEDURE MY_PROC RETURNS (aParam INTEGER) AS
 BEGIN
   aParam = 10;
 END^

Exécution du script

TFDScript vous permet d'exécuter un script à partir d'un fichier pointé par SQLScriptFileName, si cela est spécifié. Sinon, vous pouvez l'exécuter à partir d'un script d'index zéro depuis la collection SQLScripts.

Remarque : Vous avez aussi la possibilité d'exécuter un fichier avec un script SQL en utilisant l'utilitaire FDExecutor. Par exemple, pour exécuter un fichier script, utilisez l'extrait de code suivant :
 with FDScript1 do begin
   SQLScriptFileName := 'c:\create.sql';
   ValidateAll;
   ExecuteAll;
 end;

Pour exécuter un script dans une mémoire, utilisez ce qui suit :

 with FDScript1 do begin
   SQLScripts.Clear;
   SQLScripts.Add;
   with SQLScripts[0].SQL do begin
     Add('INSERT INTO Brands VALUES (1, ''Audi'')');
     Add('INSERT INTO Brands VALUES (2, ''BMW'')');
   end;
   ValidateAll;
   ExecuteAll;
 end;

Il existe également d'autres méthodes qui simplifient l'exécution du script SQL. Vous pouvez contrôler de nombreux autres aspects de l'exécution des scripts comme dans un code Delphi en utilisant ScriptOptions et en utilisant des commandes de contrôle de scripts correspondantes.

Le script peut également appeler d'autres scripts, comme une sous-routine, via les commandes @ <script>, @@ <script>, START <script> ou INPUT <script>. Dans ce cas, <script> est soit le nom de l'élément issu de la collection SQLScripts, soit le nom du fichier externe. Par exemple, le script 'root' exécute les index 'first' et 'second' :

 with FDScript1.SQLScripts do begin
   Clear;
   with Add do begin
     Name := 'root';
     SQL.Add('@first');  // explicitly call 'first' script
     SQL.Add('@second'); // explicitly call 'second' script
   end;
   with Add do begin
     Name := 'first';
     SQL.Add('create table t1 (...);');
     SQL.Add('create table t2 (...);');
   end;
   with Add do begin
     Name := 'second';
     SQL.Add('create procedure p1 (...);');
     SQL.Add('create procedure p2 (...);');
   end;
 end;
 FDScript1.ValidateAll;
 FDScript1.ExecuteAll;

Un script SQL peut être exécuté en intégralité avec un index en utilisant la méthode ExecuteAll, ou en mode pas à pas en utilisant la méthode ExecuteStep. Cette dernière méthode est utile pour les applications GUI, permettant l'exécution des requêtes Ad-hoc. La commande suivante est extraite et exécutée à partir de la position Position dans le script. Pour arrêter l'exécution du script, appelez la méthode AbortJob.

Séparation des commandes

Chaque commande SQL doit se terminer par un séparateur de commande. La valeur par défaut du séparateur est ';', et pour MS SQL Server, il s'agit de 'GO'. Une commande de contrôle ne doit pas se terminer par un séparateur de commande. Le séparateur peut être modifié comme dans un code Delphi en utilisant l'option CommandSeparator, ou comme dans un script SQL en utilisant les commandes SET CMDSEP <sep> ou DELIMiter <sep>. Par exemple, pour SQL Server, utilisez le code suivant :

 INSERT INTO Brands VALUES (1, 'Audi')
 GO
 INSERT INTO Brands VALUES (2, 'BMW')
 GO

Pour Oracle, utilisez :

 INSERT INTO Brands VALUES (1, 'Audi');
 INSERT INTO Brands VALUES (2, 'BMW');

Utilisez un séparateur personnalisé de la manière suivante :

 SET CMDSEP #
 INSERT INTO Brands VALUES (1, 'Audi')#
 INSERT INTO Brands VALUES (2, 'BMW')#

Lorsqu'un script contient des commandes ou des blocs de langage de programmation de base de données, d'autres considérations doivent être prises en compte :

SGBD Commandes SQL Description
Firebird
  • CREATE FUNCTION
  • EXECUTE BLOCK <bloc de code>
Doit se terminer par '/', ou un séparateur différent de ';' doit être défini.
Oracle
  • CREATE PROCEDURE / FUNCTION / PACKAGE / etc.
  • BEGIN <bloc de code> END
Doit se terminer par '/', ou un séparateur différent de ';' doit être défini.
PostgreSQL
  • CREATE FUNCTION
  • DO <bloc de code>
Aucune action n'est requise.

Par exemple, avec Firebird, utilisez le code suivant :

 SET CMDSEP #;
 EXECUTE BLOCK ... #
 SET CMDSEP ;#
 INSERT INTO Brands VALUES (3, 'Mercedes');

Sinon, l'application pourrait déclencher une erreur, telle que :

 [FireDAC][IB] Unexpected end of command line 3

Utilisation des paramètres

Un script SQL peut faire référence aux éléments suivants :

  • Paramètres de la collection TFDScript.Params. Pour définir un paramètre dans un script, utilisez la commande <code>VARiable <name><type>=<value></code>. Pour définir un paramètre dans le code, ajoutez un paramètre à TFDScript.Params avant l'exécution du script.
  • Macros de la collection TFDScript.Macros. Pour définir une macro dans un script, utilisez la commande <code>DEFine <name>=<value></code>. Pour définir une macro dans le code, ajoutez une macro à TFDScript.Macros avant l'exécution du script. Pour activer le traitement de la macro, définissez MacroExpand sur True (par défaut) ou exécutez SET DEFINE ON ou SET SCAN ON.
  • Arguments utilisant la syntaxe &<nombre d'arguments>. Les arguments peuvent être spécifiés dans la propriété TFDScript.Arguments, en tant qu'arguments des méthodes TFDScript.ExecuteFile ou ExecuteScript, ou comme partie des commandes @ / @@.

Par exemple, pour définir et utiliser des paramètres, utilisez le code suivant :

 with FDScript1.SQLScripts[0].SQL do begin
   Add('VARIABLE name CHAR IN = ''aaa''');
   Add('VARIABLE id NUMBER INOUT');
   Add('INSERT INTO master (name) VALUES (:name) RETURNING id {INTO :id};');
   Add('INSERT INTO detail (fk_id, name) VALUES (:id, ''bbb'');');
 end;

Pour définir et faire référence à une macro, utilisez ce qui suit :

 DEF tab=Brands
 INSERT INTO !tab VALUES (1, 'Audi');
 INSERT INTO !tab VALUES (2, 'BMW');

Pour définir et utiliser des arguments, utilisez ce qui suit :

 FDScript1.Arguments.Add('Brands');
 ...
 with FDScript1.SQLScripts[0].SQL do begin
   Add('INSERT INTO &1 VALUES (1, ''Audi'')');
   Add('INSERT INTO &1 VALUES (2, ''BMW'')');
 end;

Obtention d'un retour d'informations

Pour créer un journal d'exécution, vous pouvez activer la mise en file d'attente comme dans un code Delphi en utilisant les options SpoolOutput et SpoolFileName, ou comme dans un script SQL en utilisant les commandes <code>SPOol <name></code> ou <code>OUTput <name></code>. Le contenu de la sortie de file d'attente est contrôlé par les options EchoCommands, FeedbackCommands, AutoPrintParams, FeedbackScript, IgnoreError, Timing, ColumnHeadings, PageSize, ServerOutput.

Vous pouvez utiliser le composant TFDGUIxScriptDialog pour permettre à un moteur d'exécution de script de communiquer avec un utilisateur en utilisant une boîte de dialogue. Pour interagir avec le TFDScript de l'utilisateur, utilisez des événements tels que OnConsoleGet, OnConsolePut, OnGetText, OnPause, etc. Cette boîte de dialogue fournit une implémentation standard de ces événements. Pour afficher la progression de l'exécution, TFDScript doit connaître la longueur totale de tous les scripts à exécuter. Pour cela, appelez la méthode ValidateAll avant de démarrer une exécution de script.


Résolution des incompatibilités

Vous trouverez ci-dessous une liste des incompatibilités de TFDScript avec les utilitaires de scripts d'origine :

  • ISQL de Firebird fonctionne lorsque le mode Validation automatique est désactivé. Par défaut, le mode Validation automatique pour TFDScript/TFDConnection est activé. Pour améliorer la compatibilité, définissez FDConnection.TxOptions.AutoCommit sur False avant l'exécution du script. Ou exécutez la commande de script SET AUTOCOMMIT OFF.
  • ISQL de Microsoft envoie le résultat de la commande PRINT. Par défaut, TFDScript/TFDConnection ne fait pas cela. Pour activer la sortie PRINT, définissez ResourceOptions.ServerOutput sur True ou exécutez la commande de script SET SERVEROUTPUT ON.