interbase borland data provider

Upload: anonymous-wpl47bwu4

Post on 02-Jun-2018

257 views

Category:

Documents


1 download

TRANSCRIPT

  • 8/10/2019 Interbase Borland Data Provider

    1/124

    Interbase Borland Data Provider- John COLIBRI.

    abstract:utilisation du Borland Data Providersous WindowsFormspour grer enDelphi 8des donnesInterbase

    mots cl:BDP - Borland Data Provider - .Net SDK -WindowsForms-Delphi 8-Interbase-Firebird

    logiciel utilis: Windows XP, Delphi 8, Interbase 6 matriel utilis: Pentium 1.400Mhz, 256 M de mmoire

    champ d'application: Delphi 8 sur Windows, Interbase, Firebird niveau: dbutant Delphi et Base de Donnes plan:

    o Introductiono Architectureo Connexion la baseo Crer une Tableo Ajouter des Donneso Lire et Affichero Modifier des Donneso Evaluationo Tlcharger les Exempleso Conclusion

    1 - Introduction

    J'ai choisi de prsenter Borcon2004 les diffrents moyens d'utiliserInterbase:

    pourDelphi5 6, les API, le BDEet SqlLinks,InterbaseExpress, dbExpressetAdo

    pourDelphi 8:

    o en mode VCL.Net, dbExpress.Net,Ibx.Neto en mode WindowsForms,Ado.Net et leBDP

    Cet article va se concentrer sur le mode WindowsFormsetle Borland Data Provider.

    Pour les autres faons d'utiliserInterbase, vous pouvez consulter sur ce site:

    le tutorial interbase:comment utiliser des bases de donnes en

    mode ClientServeur(Delphi 6,Ibx). L'article d'initiation le plus complet Interbase dbExpresss:le mode dbExpress(Delphi 6, dbExpress). Le mode

    qui permet le mieux de comprendre l'architectureAdo.Netqui en est

    directement issue

    http://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#introductionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#introductionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#architecturehttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#architecturehttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#connectionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#connectionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#crer_une_tablehttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#crer_une_tablehttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#ajouter_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#ajouter_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#lire_et_afficherhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#lire_et_afficherhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#modifier_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#modifier_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#evaluationhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#evaluationhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#telechargerhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#telechargerhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#conclusionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#conclusionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress/interbase_dbexpress.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress/interbase_dbexpress.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress/interbase_dbexpress.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress/interbase_dbexpress.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#conclusionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#telechargerhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#evaluationhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#modifier_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#lire_et_afficherhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#ajouter_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#crer_une_tablehttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#connectionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#architecturehttp://www.jcolibri.com/articles/bdd/interbase/interbase_borland_data_provider/interbase_borland_data_provider.html#introduction
  • 8/10/2019 Interbase Borland Data Provider

    2/124

    InterbaseIbx.Net:le portage sous .Netde lamcaniqueIbx(Delphi 8,Ibx.Net). Le moyen le plus simpled'utiliserInterbaseetDelphi 8. Contient aussi un comparatif de toutes cesarchitectures avec les schmas correspondants

    InterbasedbExpress.Net:le portage sous .Netde lamcanique dbExpress(Delphi 8, dbExpress.Net). L'utilisation destechniques VCLpourInterbaseET pour les autres serveurs(Oracle, SqlServer,MyBaseetc)

    Nous nous adressons pour cet article un programmeur Delphi ayant une idelmentaire de Delphi:Palette,Inspecteur, OnClick. Tout le reste sera expliqu.

    Nous supposons:

    queDelphi 8est install (la version "dveloppeur": pas la version "tudiant"qui n'a pas les bases de donnes, et pas besoin de la version "Entreprise" ou"Architecte", mais tout marche aussi avec ces deux dernires)

    qu'Interbaseest install (voyezle tutorial interbasequi dtaille cetteinstallation). J'ai utilis la versionInterbase 6que j'ai installe et que j'utilisecouremment avecDelphi 6, mais tout fonctionne bien sr avec les versions 7etFireBird.

    2 - Architecture

    Une fois les librairies .Netinstalles, nous pouvons utiliser des Serveursde basesde donnes en utilisant une couche appeleAdo.Net. Cette couche dfinit descomposant pour communiquer avec des "sources de donnes". Ces sources sont trsgnrales: des courriers Outlook, des donnesExcelet des donnes provenant

    d'un ServeurSql.

    Pour les bases de donnes,Ado.Netpermet de grer:

    de faon nativeo "Sql Data Provider" pour SqlServer

    en ajoutant des modules supplmentaires, d'autres bases de donnes:

    o pour Oracle, le module "Oracle Data Provider"o pour les serveurs pour lesquels existe un pilote ODBC, le module

    "ODBC Data Provider"

    http://www.jcolibri.com/articles/bdd/interbase/interbase_ibx_net/interbase_ibx_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_ibx_net/interbase_ibx_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_ibx_net/interbase_ibx_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_ibx_net/interbase_ibx_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_ibx_net/interbase_ibx_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_ibx_net/interbase_ibx_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress_net/interbase_dbexpress_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress_net/interbase_dbexpress_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress_net/interbase_dbexpress_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress_net/interbase_dbexpress_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress_net/interbase_dbexpress_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress_net/interbase_dbexpress_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_dbexpress_net/interbase_dbexpress_net.htmlhttp://www.jcolibri.com/articles/bdd/interbase/interbase_ibx_net/interbase_ibx_net.html
  • 8/10/2019 Interbase Borland Data Provider

    3/124

    o pour les serveurs ayant un pilote OleDbCOM, le module "OleDbData Provider"

    o le module "Borland Data Provider" qui est un provider gnrique pourplusieurs serveurs, telsque SqlServer, Oracle,DB2,FireBirdetInterbase.

    Pour accder Interbase, nous pouvons donc:

    acheter un pilote ODBC (EasySoft) acheter un pilote OleDb(IbProvider)

    utiliser leBDPfourni avecDelphi 8

    Notez aussi que leBDPest un module .Netgnral: il peut tre utilis avecn'importe quel langage qui communique avec les librairies .Net(Delphi 8, bien sr,

    mais aussi les autres langages via les divers outils de dveloppement).L'architecture gnrale a donc l'allure suivante:

  • 8/10/2019 Interbase Borland Data Provider

    4/124

    3 - La connection

    3.1 - Prparation

    LeBDPne sait pas crer de base vierge. SeulIbx, en modeDelphi 6, ouIbx.NetenmodeDelphi 8peuvent le faire. Nous allons donc utiliser une base creauparavant, en la copiant dans un rpertoire proche pour viter de la rechercherniches dans des rpertoires dpendant de chaque installation. Nous allons:

    crer un rpertoire _DATA au mme niveau que nos sources (dans n'importe quelrpertoire qui vous convient)

    copier une baseInterbasedans ce rpertoire. Par exemple INSTITUT_PASCAL.GDBprovenant de nos tutoriaux antrieurs, ou EMPLOYEE.GDB provenant de "FICHIERSCOMMUNS" etc

    renommer cette base INSTITUT_PASCAL_5.GDB

    3.2 - La connection

    Commenons par nous connecter note baseInterbase:

    lancezDelphi 8

    crez une nouvelle application en cliquant "Fichiers | Nouveau | Windows Forms" etrenommez-la "p_ib_bdp_connection"

    dans la page "Borland Data Provider" slectionnez unBdpConnection:

  • 8/10/2019 Interbase Borland Data Provider

    5/124

    et posez-le sur leForme

    comme d'habitude, leBdpConnectionest affich sous la WindowsForms:

    slectionnerBdpConnection1, et avec un Click droit souris, ouvrezl'Editeurde Connections. Par dfaut il affiche les proprits du serveurDB2:

  • 8/10/2019 Interbase Borland Data Provider

    6/124

    tapez les proprits de notre base:

    slectionnez le pilote IbConn1

    tapez le chemin

    _DATA\INSTITUT_PASCAL_5.GDB

    testez la connection en cliquant "Test"

    Si le chemin et le nom de la base sont corrects, un dialogue "ConnectionSuccessful" apparat. Fermez-le

    fermez le dialogue de connection en cliquant "OK"

    Notez que

    j'ai eu le plaisir de voir que le "UserName" et "Password" sont dj remplis, etque leLoginPromptestFalsepar dfaut. Passer sa journe, sur sa propremachine, taper les sempiternels "SYSDBA" et "masterkey" n'est pas

    particulirement productif. le dialecte 3 est dj initialis (nous avons cr notre base avec ce dialecte).

    Delphia rempli les proprits ConnectionStringet ConnectionOptionsdansl'Inspecteurd'Objet:

  • 8/10/2019 Interbase Borland Data Provider

    7/124

    ConnectionStringcontient:

    assembly=Borland.Data.Interbase,Version=1.5.0.0,

    Culture=neutral,PublicKeyToken=91d62ebb5b0d1b1b;vendorclient=gds32.dll;database=..\_data\INSTITUT_PASCAL_5.GDB;

    provider=Interbase;username=sysdba;

    password=masterkey

    ConnectionOptioncontient:

    waitonlocks=False;commitretain=False;sqldialect=3;transaction isolation=ReadCommitted;servercharset=;rolename=myrole

    4 - Crer et remplir une Table

    4.1 - Principe

    Nous allons crer une table contenant pour chaque formation:

    un code (par exemple 8)

    un nom (par exemple "Delphi Interbase") le nombre de jours (par exemple 3)

    un prix (par exemple 1.400)

    La syntaxe de la requte SQL envoyer vers le Serverest la suivante:

    CREATE TABLEformations_5(f_numero INTEGER, f_nom CHARACTER(23), f_jours INTEGER,

    f_prixNUMERIC(5, 2) )

    Pour envoyer cette requte vers le Serveur:

  • 8/10/2019 Interbase Borland Data Provider

    8/124

    nous utilisons unBdpConnectionqui assurera la connection vers le Serveur nous crons un objetBdpCommanden utilisant:

    my_c_bdp_command:= my_c_bdp_connection.CreateCommand;

    nous remplissons la requte par:

    my_c_bdp_command.CommandText:= 'CREATE etc';

    nous envoyons la requte vers le Serveurpar:

    my_c_bdp_command.ExecuteNonQuery;

    Nous pouvons aussi ajouter des transactions pour encadrer cette cration.

    Donc:

    crez une nouvelle application WindowsFormset appelez-la "p_ib_bdp_create_table"

    posez unButton, appelez-le "create_", crez son vnement OnClicket tapez lesinstructions de cration de table:

    constk_database_file= '..\_data\INSTITUT_PASCAL_5.GDB';

    k_table_name= 'formations_5';

    k_connection_string= 'assembly=Borland.Data.Interbase, Version=1.5.0.0, '+ 'Culture=neutral,PublicKeyToken=91d62ebb5b0d1b1b;vendorclient=gds32.dll

    ;'+ 'database='+ k_database_file+ ';'+ 'provider=Interbase;username=sysdba;password=masterkey' ;

    k_sql_create= 'CREATE TABLE '+ k_table_name+ ' (f_id INTEGER, f_name CHAR(28), f_days INTEGER, f_price DOUBLE P

    RECISION )';

    procedureTWinForm.create_transaction__Click(sender: System.Object; e: System.EventArgs);varl_c_bdp_connection:BdpCOnnection;

    l_c_bdp_transaction:BdpTransaction;l_c_bdp_command:BdpCommand;

    begintrytryl_c_bdp_connection:=BdpConnection.Create(k_connection_string);

    Include(l_c_bdp_connection.StateChange,BdpConnection1_StateChange);l_c_bdp_connection.Open;

  • 8/10/2019 Interbase Borland Data Provider

    9/124

    l_c_bdp_transaction:= l_c_bdp_connection.BeginTransaction;

    l_c_bdp_command:= l_c_bdp_connection.CreateCommand;l_c_bdp_command.CommandText:= k_sql_create;

    l_c_bdp_command.Connection:= l_c_bdp_connection;l_c_bdp_command.Transaction:= l_c_bdp_transaction;

    l_c_bdp_command.ExecuteNonQuery;finallyl_c_bdp_transaction.Commit;l_c_bdp_connection.Close;

    end;exceptone:exceptiondobegin

    l_c_bdp_transaction.RollBack;display_bug_stop(e.Message);

    end;end; // try ... except

    end; // create_transaction__Click

    compilez, excutez, et cliquez le bouton

    Dans la foule, nous pouvons effacer la mme table avec la requte Sqlsuivante:

    DROP TABLEformations_5

    Donc:

    placez un autre tButtonsur laForme, nommez-le "drop_table" et placez-y la requte desuppression:

    constk_sql_drop= 'DROP TABLE '+ k_table_name;

    procedureTWinForm.drop_transaction__Click(sender: System.Object; e: System.EventArgs);varl_c_bdp_connection:BdpCOnnection;

    l_c_bdp_transaction:BdpTransaction;l_c_bdp_command:BdpCommand;

    begintrytry

    l_c_bdp_connection:=BdpConnection.Create(k_connection_string);Include(l_c_bdp_connection.StateChange,BdpConnection1_StateChange);

  • 8/10/2019 Interbase Borland Data Provider

    10/124

    l_c_bdp_connection.Open;

    l_c_bdp_transaction:= l_c_bdp_connection.BeginTransaction;

    l_c_bdp_command:= l_c_bdp_connection.CreateCommand;l_c_bdp_command.CommandText:= k_sql_drop;l_c_bdp_command.Connection:= l_c_bdp_connection;l_c_bdp_command.Transaction:= l_c_bdp_transaction;

    l_c_bdp_command.ExecuteNonQuery;finally

    l_c_bdp_transaction.Commit;l_c_bdp_connection.Close;

    end;except

    one:exceptiondobeginl_c_bdp_transaction.RollBack;display_bug_stop(e.Message);

    end;end; // try ... except

    end; // drop_transaction__Click

    compilez, excutez, et cliquez le bouton

    Vous pouvez tlcharger le sources du projet "win_bdp_create_table.zip".

    4.2 - Vrifier la cration

    Nous pouvons vrifier que la cration a t effectue en utilisant lafonction GetMetaDatadeBdpConnection. La technique est similaire celle utilise

    partSession.GetTableNames du temps de l'antique BDE.

    Dans notre cas:

    crez une nouvelle application en cliquant "Fichiers | Nouveau | Windows Forms" etrenommez-la "p_win_bdp_metadata"

    posez uneListBoxsur laFormeposez unButton, nommez-le "table_", crez son vnement OnClickqui va afficher

  • 8/10/2019 Interbase Borland Data Provider

    11/124

    dansListBox1le nom des tables:

    procedureTWinForm.tables_Click(sender: System.Object; e: System.EventArgs);varl_c_bdp_connection:BdpCOnnection;

    l_c_data_table:DataTable;

    l_table_index: integer;begintryDatagrid1.DataSource:= nil;

    l_c_bdp_connection:=BdpConnection.Create(k_connection_string);Include(l_c_bdp_connection.StateChange,BdpConnection1_StateChange);l_c_bdp_connection.Open;

    tryl_c_data_table:= l_c_bdp_connection.GetMetaData.GetTables('',

    Borland.Data.Schema.TableType.Table);DataGrid1.DataSource:= l_c_data_table;ListBox2.Items.Clear;forl_table_index:=0 tol_c_data_table.Rows.Count-1 doListBox2.Items.Add(l_c_data_table.Rows[l_table_index].Item['TableName']);

    finallyl_c_bdp_connection.Close;

    end;exceptone:exceptiondoDataGrid1.CaptionText:= e.Message;

    end; // try ... exceptend; // tables_Click

    posez unDataGridsur laForme

    slectionnezListBox1, crez son vnementMouseDownet affichez le contenu de la tableslectionne:

    procedureTWinForm.ListBox2_MouseDown(sender: System.Object; e: System.Windows.Forms.MouseEventArgs);varl_c_bdp_connection:BdpCOnnection;

    l_c_data_table:DataTable;l_table_name: String;

    begintryDatagrid1.DataSource:= nil;

    Text:= k_database_file;

    l_c_bdp_connection:=BdpConnection.Create(k_connection_string);Include(l_c_bdp_connection.StateChange,BdpConnection1_StateChange);l_c_bdp_connection.Open;

  • 8/10/2019 Interbase Borland Data Provider

    12/124

    tryl_table_name:=ListBox2.Items[ListBox2.SelectedIndex].ToString;l_c_data_table:= l_c_bdp_connection.GetMetaData.GetColumns(l_table_name,

    '',Borland.Data.Schema.ColumnType.Unknown);

    DataGrid1.DataSource:= l_c_data_table;finallyl_c_bdp_connection.Close;

    end;except

    one:exceptiondoDataGrid1.CaptionText:=e.Message;

    end;end; // ListBox2_MouseDown

    compilez et excutez. Cliquez "table_" et cliquez "FORMATIONS_5"

    voici le rsultat:

    5 - Ajouter des Donnes

    Pour ajouter un enregistrement

    3, Interbase Delphi

    l'instruction SQL excuter est:

  • 8/10/2019 Interbase Borland Data Provider

    13/124

    INSERT INTOformations(f_numero,f_nom)VALUES(3, 'Interbase Delphi')

    Crons une nouvelle application pour pouvoir ajouter quelques lignes:

    crez une nouvelle application WindowsFormset appelez-la "p_win_bdp_insert_data"

    posez unButton, appelez-le "insert_", crez son vnement OnClicket tapez lesinstructions qui insreront une ligne:

    constk_sql_insert='INSERT INTO '+ k_table_name

    + ' (f_id, f_name, f_days, f_price)'+ ' VALUES (3, ''Delphi Interbase'', 3, 1400)';

    procedureTWinForm.insert_Click(sender: System.Object; e: System.EventArgs);varl_c_bdp_connection:BdpCOnnection;

    l_c_bdp_command:BdpCommand;begin

    trytry

    l_c_bdp_connection:=BdpConnection.Create(k_connection_string);Include(l_c_bdp_connection.StateChange,BdpConnection1_StateChange);l_c_bdp_connection.Open;

    l_c_bdp_command:= l_c_bdp_connection.CreateCommand;l_c_bdp_command.CommandText:= k_sql_insert;l_c_bdp_command.ExecuteNonQuery;

    finallyl_c_bdp_connection.Close;

    end;exceptone:exceptiondo

    display_bug_stop(e.Message);end; // try ... except

    end; // insert_Click

    compilez, excutez, et cliquez le bouton

    Nous pouvons automatiser ces ajouts en paramtrant la procdure qui envoie lesvaleurs littrales. Voici un exemple:

    posez unButton, appelez-le "insert_several_", crez son vnement OnClicket tapez les

  • 8/10/2019 Interbase Borland Data Provider

    14/124

    instructions qui insreront plusieurs lignes:

    procedureTWinForm.insert_several__Click(sender: System.Object; e: System.EventArgs);

    varl_c_bdp_connection:BdpCOnnection;

    l_c_bdp_command:BdpCommand;

    procedureinsert_generic(p_number:Integer;p_name: String;p_days:Integer;p_price:Double);

    varl_sql_text: String;beginDecimalSeparator:= '.';l_sql_text:=

    'INSERT INTO '+ k_table_name+ ' (f_id, f_name, f_days, f_price)'+ ' VALUES '

    + ' ('+ IntToStr(p_number)+ ', '+ QuotedStr(p_name)+ ', '+ IntToStr(p_days)+ ', '+FloatToStr(p_price)+ ' )';

    DecimalSeparator:= ',';

    display(l_sql_text);l_c_bdp_command.CommandText:= l_sql_text;

    Tryl_c_bdp_command.ExecuteNonQuery;

    Exceptone:Exceptiondo

    display(' *** pb_insert '+ e.Message);end;

    end; // insert_generic

    begin// insert_several__Clicktry

    tryl_c_bdp_connection:=BdpConnection.Create(k_connection_string);

    Include(l_c_bdp_connection.StateChange,BdpConnection1_StateChange);l_c_bdp_connection.Open;

    l_c_bdp_command:= l_c_bdp_connection.CreateCommand;

    insert_generic(1, 'Initiation Delphi', 3, 1400.40);insert_generic(2, 'Bases de Donnes Delphi', 3, 1400);insert_generic(3, 'Interbase Delphi', 3, 1400);insert_generic(4, 'Composants Delphi', 3, 1400);insert_generic(5, 'UML et Patterns Delphi', 3, 1400);insert_generic(6, 'Delphi Asp', 3, 1400);

    finallyl_c_bdp_connection.Close;

  • 8/10/2019 Interbase Borland Data Provider

    15/124

    end;except

    one:exceptiondodisplay_bug_stop(e.Message);

    end; // try ... exceptend; // insert_several__Click

    compilez, excutez, et cliquez le bouton

    6 - Lire et Afficher6.1 - Affichage par code

    Nous allons maintenant afficher les donnes.

    Une premire technique consiste lire les donnes en utilisant unDataReader.Plaons cet affichage dans le projet prcdent:

    posez unButton, appelez-le "select_", crez son vnement OnClicket tapez lesinstructions qui afficheront les lignes dans un TextBox:

    procedureTWinForm.select__Click(sender: System.Object; e: System.EventArgs);varl_c_bdp_connection:BdpConnection;

    l_c_bdp_command:BdpCommand;l_c_data_reader:BdpDataReader;l_field_index:Integer;l_line: String;l_formatted_value: String;

    begintrytry

    l_c_bdp_connection:=BdpConnection.Create(k_connection_string);Include(l_c_bdp_connection.StateChange,BdpConnection1_StateChange);l_c_bdp_connection.Open;

    l_c_bdp_command:= l_c_bdp_connection.CreateCommand;l_c_bdp_command.CommandText:= k_sql_select;

    l_c_data_reader:= l_c_bdp_command.ExecuteReader;

    whilel_c_data_reader.Readdo

    beginl_line:= '';

  • 8/10/2019 Interbase Borland Data Provider

    16/124

    forl_field_index:= 0 tol_c_data_reader.FieldCount- 1 dobegin

    l_formatted_value:= l_c_data_reader.GetValue(l_field_index).ToString;Casel_field_indexof

    0 : l_formatted_value:=Format('%-3s', [l_formatted_value]);1 : l_formatted_value:=Format('%-28s', [l_formatted_value]);2 : l_formatted_value:=Format('%-3s', [l_formatted_value]);3 : l_formatted_value:=Format('%-6s', [l_formatted_value]);

    end; // casel_line:= l_line+ l_formatted_value+ '|'

    end; // for all fields

    display(l_line);end; // while Read

    Finally

    l_c_data_reader.Close;End; // try ... finally

    ExceptOne:Exceptiondo

    display('*** '+ e.Message)end; // try ... except

    display('< select');end; // select__Click

    compilez, excutez, et cliquez le bouton

    voici le rsultat:

    6.2 - Affichage en mode conception

    Nous allons aussi utiliser des composants poss sur laFormeau lieu d'utiliser lacration dynamique par code:

    crez une nouvelle application WindowsFormset appelez-la "p_win_bdp_select"

  • 8/10/2019 Interbase Borland Data Provider

    17/124

    connectez le Serveur:

    dans la page "Borland Data Provider" slectionnez unBdpConnectionet posez-lesur leForme

    slectionnerBdpConnection1, et avec un Click droit souris, ouvrez

    l'Editeurde Connectionso slectionnez le pilote IbConn1o tapez le chemin _DATA\INSTITUT_PASCAL_5.GDBo testez la connection en cliquant "Test"o fermez le dialogue de connection en cliquant "OK"

    dans la page "Borland Data Provider" slectionnez unBdpDataAdapter:

    et posez-le sur leForme

    Dfinissez la requte de slection:

    slectionnez leBdpDataAdapter1, cliquez sur le bouton droit, slectionnez"Configure Data Adapter" le ConfigurateurdeDataAdapterest affich:

  • 8/10/2019 Interbase Borland Data Provider

    18/124

    slectionnez FORMATIONS_5, puis "Generate Sql" le code "SELECT ... " est gnr

  • 8/10/2019 Interbase Borland Data Provider

    19/124

    slectionnez l'onglet "Preview Data" cliquez "Refresh" les donnes de la table sont affichs:

  • 8/10/2019 Interbase Borland Data Provider

    20/124

    pour afficher les donnes sur laForme, nous crons unDataSetqui sera rempli

    par leBdpDataprovider.

    Pour cela, slectionnez l'onglet "Dataset" du configurateur, choisissez le bouton"New Data":

  • 8/10/2019 Interbase Borland Data Provider

    21/124

    Fermez le Configurateuren cliquant "OK"

    DataSet1est automatiquement ajout aux composants

    De plus sur disque est apparu DataSet1Unit.pas (19 K, tout de mme) avec,semble-t-il, les champs persistents et des vnements de gestion desmodifications et de traitements .XML

    dans l'onglet "Data Controls" slectionnez unDataGrid:

  • 8/10/2019 Interbase Borland Data Provider

    22/124

    et posez le sur laForme.

    Puis:

    slectionnez sa propritDataSourceet mettez-yDataSet1

    slectionnez sa propritDataMemberet mettez-y FORMATIONS_5

    ouvrez leDataAdapter1: slectionnez sa propritActiveet basculez-la sur True

    les donnes sont affiches dansDataGrid1:

  • 8/10/2019 Interbase Borland Data Provider

    23/124

    7 - Modifier des Donnes

    Nous allons prsent mettre en place la modification de donnes. Commenons parune application qui affiche des donnes dans unDataGrid:

    crez une nouvelle application WindowsFormset appelez-la "p_win_bdp_update_data"

    connectez le Serveur:

    dans la page "Borland Data Provider" slectionnez unBdpConnectionet posez-lesur leForme

    slectionnerBdpConnection1, et avec un Click droit souris, ouvrezl'Editeurde Connections

    o slectionnez le pilote IbConn1o

    tapez le chemin _DATA\INSTITUT_PASCAL_5.GDBo testez la connection en cliquant "Test"

  • 8/10/2019 Interbase Borland Data Provider

    24/124

    o fermez le dialogue de connection en cliquant "OK"

    dans la page "Borland Data Provider" slectionnez unBdpDataAdapteret posez-le surleForme

    Dfinissez la requte de slection:

    slectionnez leBdpDataAdapter1, cliquez sur le bouton droit, slectionnez"Configure Data Adapter"

    slectionnez FORMATIONS_5, toutes ses colonnes, puis "Generate Sql" le code "SELECT ... " est gnr slectionnez l'onglet "Preview Data" cliquez "Refresh"

    les donnes de la table sont affichs pour afficher les donnes sur laForme, nous crons unDataSetqui sera rempli

    par leBdpDataprovider.

    Pour cela, slectionnez l'onglet "Dataset" du configurateur, choisissez le bouton"New Data".

    Fermez le Configurateuren cliquant "OK"

    DataSet1est automatiquement ajout aux composants et DataSet1Unit.pas estgnr sur disque

    dans l'onglet "Data Controls" slectionnez unDataGridet posez le sur laForme.

    Puis:

    slectionnez sa propritDataSourceet mettez-yDataSet1 slectionnez sa propritDataMemberet mettez-y FORMATIONS_5

    ouvrez leDataAdapter1: slectionnez sa propritActiveet basculez-la sur True

    A prsent la partie de mise jour:slectionnezDataAdapter1et sa proprit UpdateCommand: vous voyez dans sa

    proprit CommandTextla requte Sqlsuivante:

    UPDATE FORMATIONS_5SETF_ID = ?, F_NAME = ?, F_DAYS = ?, F_PRICE = ?WHEREF_ID = ? AND F_NAME = ? AND F_DAYS = ?

    AND F_PRICE = ?

    Cette requte a en fait t gnre automatiquement lorsque nous avons cre larequte SELECT.

    Si cette requte ne nous convient pas, nous pourrions la modifier (changer

  • 8/10/2019 Interbase Borland Data Provider

    25/124

    le WHEREpour retrouver l'ancienne ligne sur la cl uniquement, par exemple)

    ajoutons l'instruction de mise jour: posez unButtonsur laForme, nommez-le "update_"et crez son vnement OnClick:

    constk_table_name= 'formations_5';

    procedureTWinForm.update__Click(sender: System.Object; e: System.EventArgs);beginifDataSet1.HasChanges

    thenbeginBdpDataAdapter1.AutoUpdate(DataSet1, k_table_name,BdpUpdateMode.All,

    [], []);end;

    end; // tables_Click

    compilez, excutez. Puis

    modifiez la ligne "Delphi Asp" en "ASP.NET ET DELPHI", par exemple changez de ligne pour poster cliquez "update_"

    fermez et rouvrez: la modification a bien t enregistre

    8 - Evaluation

    Voici quelques commentaires sur cette premire utilisation duBDP

  • 8/10/2019 Interbase Borland Data Provider

    26/124

    le fonctionnement est nettement plus sympathique qu'avecAdo.Net. Freuddirait que j'aurais pu mettre ce commentaire avant de commencer utiliserleBPD. Quel que soit mon biais,l'empilementAdo.Net, ComInteroperabilityLayer, OleDbpuis leclientInterbase(ou autre) ne peut pas tre trs efficace par dfaut

    au niveau de l'interface programmeur:o l'Editeurde ConnectiondeBdpConnectionne se souvient pas toujours

    de la connection courante (il s'ouvre toujours surDb2Conn1) pour les bugs:

    o NUMERIC : j'avais au dbut utilis le typeNUMERIC(5, 2) provenant d'un

    prcdent article pour une raison inconnue, l'affichage via unDataSetne

    fonctionnait pas. De plus toute la mcanique que nous avons

    prsent pour afficher en mode conception n'arrtait pas deprsenter des erreur ("input string not of the correct format")

    j'ai chang le type rel en DOUBLE PRECISIONet tout estrentr dans l'ordre

    o j'ai aussi eu des misres en essayant d'utiliser une table greenDelphi 6et qui comportait des dates.

    Par consquent:

    o il vaut mieux pour le moment s'en tenir aux typesInterbasesimpleso

    le diagnostic de l'erreur a t plus que laborieux. Heureusement quej'avais display: l'affichage de l'indice du champ trait a dbusqu leproblme

    BDPest proche dans sa philosophie de dbExpress, et s'en loigne par la miseen oeuvre. Ce qui est trs proche:

    o nous retrouvons la chane connection(tSqlConnection/BdpConnection) adaptateur(tDataSetProvider/BdpDataAdapter) dataset(tClientDataset/DataSet) puis affichage (tdbGrid/DataGrid)

    o

    la modification se fait en appelant Updateet des paramtres quiguident le mode de mise a jour

    Et ce qui change:

    o avec leBDP, la relation entre l'adaptateur et leDataSetest initialisepar l'Adaptateur. C'est en fait toute l'architecture des composants devisualisation qui a t gnralise, et ceci explique ce changement deliaison

    o leDataGrida 2 proprits (DataSourceETDataMember)

    d'une faon plus gnrale, la masse de code gnre parDelphi 8pour fairefonctionner l'ensemble est la fois impressionnant et, mon avis, un peu

  • 8/10/2019 Interbase Borland Data Provider

    27/124

    inquitant: soit cette masse est imprative et c'est un dfaut, soitBorlandaforc le comportement trs gnral deAdo.Netpour le faonner aumouleDelphi 6et cela m'incite voir quel serait le fonctionnement sans toutcela...

    Delphi 8propose aussi un explorateur de donnes "Voir | Data Explorer":

    et en cliquant "Interbase", "IbConn1" et FORMATIONS_5 nous avons bien notretable et ses donnes:

  • 8/10/2019 Interbase Borland Data Provider

    28/124

    Cet explorateur est en fait un .EXE autonome. Mais je n'ai pas trs bien sul'exploiter:

    comment fournir la base examiner (la chane de connection) les changement de l'applicationDelphisemble slectionner ou modifier la

    base utilise

    Extraction de Script SQL- John COLIBRI.

    rsum: Comment gnrer un script SQL partir d'une base dedonnes Interbase / Firebird

    mots cl: script SQL - Interbase - Firebird -IbExtract logiciel utilis: Windows XP personnel, Delphi 6.0 matriel utilis: Pentium 2.800 Mhz, 512 Meg de mmoire, 250

    Giga disque dur champ d'application: Delphi 1 2006, Turbo Delphi sur Windows niveau: dveloppeur Delphi - dveloppeur Interbase

    plan:o Introductiono Principeo Le Projet Delphio Tlcharger le code source Delphi

    1 - Introduction

    http://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#introductionhttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#introductionhttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#principehttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#principehttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#principehttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.html#introduction
  • 8/10/2019 Interbase Borland Data Provider

    29/124

    Cet article va indiquer comment extraire d'une base de donnes existante un scriptSQL capable de recrer la mme base.

    Cet utilitaire permet:

    de sauvegarder de faon lisible (mais verbeuse) les donnes d'une base

    de porter facilement les donnes d'une version d'un mme moteur une autreversion

    d'adapter et modifier les donnes pour les porter sur un autre moteur, ouchanger son fonctionnement (passer du dialecteInterbase1 au dialecte 3)

    de changer la structure de la base, ou la valeur des donnes de documenter la base (en utilisant des outils de gnration de

    documentation partir du script)

    Nous avons utilis cet utilitaire dans notre article surMastApp,la base dedmonstration deDelphi

    2 - Principe

    Nous pouvons utiliser plusieurs techniques:

    analyser les tables systme qui contiennent tout les informations sur la base utiliser des composantsDelphiqui sont capables d'extraire le schma utiliser des outils externes tels queIbExpert

    CommeDelphifournit, depuisDelphi6, un composant spcifique d'extraction deschma pourInterbase, nous avons opt pour cette technique-l. Notez que si noussouhaitions effectuer une extraction directe partir des tables systme, un moyencommode serait d'examiner le code source d'Ibxet d'adapter ce code pour nos

    propres besoins. Dans notre cas, le composantIbExtractdonne satisfaction, et nous

    nous contenterons de l'utiliser

    3 - Le Projet Delphi

    3.1 - L'Objectif

    Nous devons crer un script qui permettra :

    http://www.jcolibri.com/articles/bdd/mastapp/mastapp.htmlhttp://www.jcolibri.com/articles/bdd/mastapp/mastapp.htmlhttp://www.jcolibri.com/articles/bdd/mastapp/mastapp.htmlhttp://www.jcolibri.com/articles/bdd/mastapp/mastapp.html
  • 8/10/2019 Interbase Borland Data Provider

    30/124

    de crer les tables ainsi que toutes leurs annexes (gnrateurs, triggers etc) de remplir les donnes des tables

    3.2 - Le composant IbExtract

    Ce composant a t construit uniquement pour extraire les donnes d'une base. Jesuppose que Jeff OVERCASH l'a spcialement cr pour crireIbConsole. Ildevrait donc ncessairement permettre de raliser notre travail. Le principal

    problme rsoudre est de trouver les paramtres utiliser.

    La documentation indique que

    la syntaxe de base est:nous appelonsExtractde la faon suivante:

    typeTExtractObjectTypes= (eoDatabase, eoDomain, eoTable,eoView, eoProcedure, eoFunction, eoGenerator,eoException, eoBLOBFilter, eoRole, eoTrigger,eoForeign, eoIndexes, eoChecks, eoData);

    TExtractType= (etDomain, etTable, etRole, etTrigger,etForeign, etIndex, etData, etGrant,etCheck, etAlterProc);

    TExtractTypes= SetofTExtractType;

    procedureExtractObject(ObjectType: TExtractObjectTypes;ObjectName: String;ExtractTypes: TExtractTypes);

    les paramtres sont:o le type de donne extraire: eoDomainpour les

    domaines, eoTablepour les tables etco si nous ciblons un objet particulier (une table, une procdure

    catalogue etc), le nom de cet objeto pour un objet donne, le dernier paramtre spcifie quelle donne (par

    exemple pour une table, le triggers en utilisant etTrigger)

    En ce qui nous concerne, nous esprions pouvoir tout extraire (les requtes decration de tables, les triggers etc et les donnes) par:

    IbExtract1.ExtractObject(eoDataBase, '', []);

    mais cet appel fournit bien le script de toutes les crations, mais pas le script pour

    les donnes.

  • 8/10/2019 Interbase Borland Data Provider

    31/124

    Aprs quelques essais, l'appel:

    IbExtract1.ExtractObject(eoTabke, 'orders', [etData]);

    fournit bien le script des donnes de la table ORDERS, mais aussi au dbut le scriptde cration de cette table. En combinant les deux appels, nous obtenons finalementnotre rsultat.

    3.3 - Le code d'extraction du schma

    Voici le projet:

    crez une nouvelle applicationDelphiet renommez-la "p_extract_ib_script"

    ajoutez un tMemoqui recevra le script du schma

    de la page "Interbase" de laPalette, slectionnezIbTransactionet posez-le sur laForme

    de la page "Interbase" de laPalette, slectionnezIbDataBaseet posez-le sur laForme

    reliezIbTransaction1etIbDataBase1

    double cliquez surIbDatabase1pour afficher l'Editeur de Connection. Remplissez le nomde la base, le nom de l'utilisateur, le mot de passe (SYSDBA), dcochez "LoginPrompt":

    Cliquez "Ok" pour sauvegarder, double-cliquez nouveau et slectionnez "Test" pourvrifier la connection

    de l'onglet "Interbase" de la Palette slectionnezIbExtractet posez-le sur laForme

    posez un tButtonsur laForme, renommez-le "complete_schema_", crez sonvnement OnClicket crivez le code qui extrait toutes les requtes de cration duschma:

    procedureTForm1.complete_schema_Click(Sender: TObject);

  • 8/10/2019 Interbase Borland Data Provider

    32/124

    beginopen_database_Click(Nil);

    withIBExtract1do

    beginExtractObject(eoDataBase, '', []);Memo1.Lines.Assign(Items);end;

    end; // complete_schema_Click

    compilez, excutez et cliquez "complete_schema_"

    le schma complet s'affiche dansMemo1

    3.4 - Le code d'extraction des donnes

    Pour extraire les donnes, nous allons procder en deux tapes:

    trouver le nom de toutes les tables

    pour chaque table, appelerExtractObjectavec le paramtres etData

    L'extraction des noms de Table est ralis en appelant la procdure d'extractioncomplte ci-dessus, et en extrayant le nom situ aprs chaque CREATEDATABASE .

    Voici comment placer le nom de chaque Table dans une tListBox:

    ajoutez une tListBoxau projet

    ajoutez un tButton, renommez-le "tables_", et tapez le code quiutiliseExtractObjectpour rcuprer le script de cration et en extrait les noms de tables:

    procedureTForm1.tables_names_Click(Sender: TObject);varl_item:Integer;

    l_the_line: String;l_index:Integer;l_table_name: String;

    beginopen_database_Click(Nil);

    ListBox1.Clear;

    withIBExtract1dobegin

  • 8/10/2019 Interbase Borland Data Provider

    33/124

    ExtractObject(eoTable, '', []);

    withItemsdoforl_item:= 0 toCount- 1 do

    beginl_the_line:= Trim(Strings[l_item]);ifPos('CREATE TABLE', l_the_line)= 1

    thenbeginSystem.Delete(l_the_line, 1,Length('CREATE TABLE'));l_index:= 1;l_table_name:=

    f_string_extract_non_blank(l_the_line, l_index);ListBox1.Items.Add(l_table_name);

    end;end;

    end;end; // tables_names_Click

    ajoutez un tButton, renommez-le "all_table_data_", et tapez le code quiutiliseExtractObjectpour rcuprer le script d'insertion de donnes pour chaque Table:

    proceduregenerate_insert_into(p_table_name: String;p_c_strings: tStrings);

    varl_item_index:Integer;l_the_line: String;

    begin

    withForm1,IBExtract1dobeginExtractObject(eoTable,p_table_name, [etData]);

    // -- skip the schemawithItemsdobegin

    l_item_index:= 0;whilel_item_index< Countdobeginl_the_line:= Strings[l_item_index];

    ifPos('INSERT INTO', l_the_line)> 0thenBreakelseInc(l_item_index);

    end;

    // -- now get the INSERT INTOwhilel_item_index< Countdobeginl_the_line:= Strings[l_item_index];

    p_c_strings.Add(l_the_line);Inc(l_item_index);

    end; // while l_item_index

  • 8/10/2019 Interbase Borland Data Provider

    34/124

    end; // with Itemsend; // with IBExtract1

    end; // generate_insert_into

    procedureTForm1.all_table_data_Click(Sender: TObject);varl_item_index:Integer;begin

    withListBox1doforl_item_index:= 0 toCount- 1 dogenerate_insert_into(Items[l_item_index],

    Memo1.Lines);end; // all_table_data_Click

    compilez, excutez et cliquez "complete_schema_"

    voici une vue du projet:

    compilez, excutez et cliquez "all_table_data_"

    voici une vue du projet, avec le script pour PARTS:

    Fonctions Utilisateur Interbase (UDF)- John COLIBRI.

    rsum: Cration et utilisation de fonctions utilisateur Interbase en Delphi

    mots cl: UDF - Interbase - User Defined Function - DLL logiciel utilis: Windows XP personnel, Delphi 6.0, Interbase 6

  • 8/10/2019 Interbase Borland Data Provider

    35/124

    matriel utilis: Pentium 2.800 Mhz, 512 Meg de mmoire, 250 Giga

    disque dur

    champ d'application: Delphi 1 2006 sur Windows, Interbase

    niveau: dveloppeur Delphi / Interbase

    plan:o Les UDF Interbase

    o Le Projet Delphi

    o Ajout d'une UDF

    o Tlcharger le code source Delphi

    1 - Les UDF Interbase

    Interbase fut le premier moteur proposer l'ajout de fonctions externes. Les UDF

    (User Defined Functions sont des routines places dans des DLL Windows qui

    peuvent tre utilises dans des requtes SQL.

    Nous nous sommes surtout intresss aux UDF car la base de donne du PortailAsp Net Delphi emploie de telles fonctions. Pour pouvoir intgralement recrer lePortail, il faut ajouter les UDF, d'o le prsent article.

    2 - Ajout d'une UDF

    2.1 - Principe des EXTERNAL FUNCTIONS

    Voici la situation avant l'ajout d'une UDF:

    http://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#interbase_udfhttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#interbase_udfhttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#ajout_d_une_udfhttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#ajout_d_une_udfhttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#ajout_d_une_udfhttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/interbase_udf/interbase_udf.html#interbase_udf
  • 8/10/2019 Interbase Borland Data Provider

    36/124

    Pour ajouter une UDF, il faut

    crire la DLL qui exporte la routine qui nous intresse

    placer la DLL dans le rpertoire des UDF Interbase

  • 8/10/2019 Interbase Borland Data Provider

    37/124

    ajouter la routine en tant que EXTERNAL FUNCTION aux objets des basesqui souhaitent l'utiliser

    utiliser la routine dans nos requtes SQL

  • 8/10/2019 Interbase Borland Data Provider

    38/124

    2.2 - La fonction utilise

    Nous allons crire des UDF qui ajouterons Interbase quelques fonctions de

    traitement de chanes de caractres:

    RTRIM(p_chane) qui supprime les espaces situs aprs une chane

    STRLEN(p_chane) qui retourne la taille d'une chane

    RPAD(p_chane,p_taille_max,p_caractre) qui complte une chane avec

    le caractrep_caractre pour arriver la taille p_taille_max SUBSTR(p_chane,p_position,p_nombre) qui extrait

    dep_nombrecaractres partir de p_position

    3 - Le Projet Delphi

    3.1 - L'criture de l'UDF

    Les fonctions externes doivent tre places dans une .DLL Windows. Cette .DLL

    peut tre ralise avec n'importe quel outil.

    En gnral, n'importe lequel n'est pas assez bon, et c'est pourquoi nousutiliseronsDelphi.

    L'unit qui calcule les chanes est la suivante:

  • 8/10/2019 Interbase Borland Data Provider

    39/124

    unitu_udf_string;

    interface

    usesSysUtils, Windows, Classes;

    functionf_trim_right(p_pchar:PChar):PChar; cdecl; export;functionf_right_pad(p_pchar:PChar; varpv_target_length:Integer;

    p_pad_pchar:PChar):PChar; cdecl; export;functionf_string_length(p_pchar:PChar):Integer; cdecl; export;functionf_sub_string(p_pchar:PChar;

    VARpv_position,pv_length:Integer):PChar; cdecl; export;

    implementationusesu_udf_globals;

    functionf_trim_right(p_pchar:PChar):PChar;

    beginResult:=f_build_pchar(PChar(TrimRight(String(p_pchar))), nil, 0);end; // f_trim_right

    functionf_right_pad(p_pchar:PChar; varpv_target_length:Integer;p_pad_pchar:PChar):PChar; cdecl; export;// -- complement the string to the right up to the desired length

    varl_string, l_padded_string: String;l_padded_length, l_length, l_index:Integer;

    beginl_string:= String(p_pchar);l_length:=Length(l_string);l_padded_string:= String(p_pad_pchar);l_padded_length:=Length(l_padded_string);

    if(l_length

  • 8/10/2019 Interbase Borland Data Provider

    40/124

    functionf_sub_string(p_pchar:PChar;VARpv_position,pv_length:Integer):PChar; cdecl; export;

    varl_string, l_substring: String;beginl_string:= String(p_pchar);l_substring:= Copy(l_string,pv_position,pv_length);

    Result:=f_build_pchar(PChar(l_substring), nil, 0);end; // f_sub_string

    end.

    Cette unit utilise une unit d'allocation depChar:

    unitu_udf_globals;

    interface

    usesWindows, SysUtils;

    functionf_build_pchar(p_source_pchar,p_destination_pchar:PChar;p_length:DWORD):PChar;

    implementation

    functionmalloc(Size:Integer):Pointer; cdecl; external'msvcrt.dll';

    functionf_build_pchar(p_source_pchar,p_destination_pchar:PChar;p_length:DWORD):PChar;beginresult:=p_destination_pchar;

    if(result= nil)thenbegin

    if(p_length= 0)thenp_length:= StrLen(p_source_pchar)+ 1;

    result:= malloc(p_length);

    end;

    if(p_source_pchar result)thenbegin

    if(p_source_pchar= nil) or(p_length= 1)thenresult[0]:= #0elseMove(p_source_pchar , result ,p_length);

    end;end; // f_build_pchar

    end.

  • 8/10/2019 Interbase Borland Data Provider

    41/124

    Et le texte de la DLL est le suivant:

    libraryd_string_udf;

    uses

    SysUtils,Classes,

    u_udf_string;

    exportsf_trim_right,f_right_pad,f_string_length,f_sub_string;

    end.

    Il faut donc

    compiler cette librairie

    compiler le fichier d_string_udf.dll dans le rpertoire d'Interbasequi contient toutes les .DLL qui

    seront intgres au moteur. Dans notre cas, il s'agit de

    C:\Program Files\Borland\InterBase\UDF\

    rebooter le PC pour que le moteur Interbaseprenne cette .DLL en compte

    3.2 - Ajout des EXTERNAL FUNCTIONS

    3.2.1 - Cration d'une base

    Nous allons crer une base spcialement pour tester nos UDF. Vous pouvez trs

    bien utiliser une base prexitante de votre choix.

    Le dtail de la cration de la base, de la cration et du remplissage d'une tablecontenant quelques CHAR et VARCHAR se trouve dans le .ZIP tlchargeable.Quoi qu'il en soit, il s'agit d'une base de cours de formations contenantla table suivante:

    CREATETABLEtraining

  • 8/10/2019 Interbase Borland Data Provider

    42/124

    (

    f_idINTEGER,

    f_nameCHAR(30),

    f_locationVARCHAR(10),

    f_daysINTEGER,

    f_priceFLOAT

    )

    remplie avec les lments suivants:

    100 Interbase Client Server Paris 3 1400

    101 ADO.Net Sql Server London 3 1400

    102 ASP.Net Oracle Hong Kong 3 1400

    103 TCP / IP Internet Montreal 3 1400

    104 Turbo Delphi Design Patterns Sao Paulo 3 1400105 Delphi OO Programming Dallas 3 1400

    Voici d'ailleurs le projet avec la table de test:

    3.2.2 - Ajout des UDF

    Nous allons ajouter aux UDF connues du moteur Interbasela fonction qui calcule

    la taille d'une string:

    le nom de la fonction est StrLen

    la fonction provient de la fonction Delphif_string_length, qui est situe

    dans la .DLL "d_string_udf.dll"

    La requte SQL pour ajouter cette UDF est:

  • 8/10/2019 Interbase Borland Data Provider

    43/124

    DECLAREEXTERNALFUNCTIONStrLen

    CSTRING(32767)

    RETURNSINTEGERBYVALUE

    ENTRY_POINT'f_string_length' MODULE_NAME'd_string_udf'

    Pour ajouter cette UDF, il suffit d'envoyer cette requte au moteur:

    const

    k_create_strlen=

    'DECLARE EXTERNAL FUNCTION STRLEN'

    + ' CSTRING(32767)'

    + ' RETURNS INTEGER BY VALUE'

    + ' ENTRY_POINT ''f_string_length'' MODULE_NAME ''d_string_udf''';

    procedureTForm1.create_udf_Click(Sender: TObject);begin

    initialize_ib_database(k_database_name, k_user, k_password,IbDatabase1);

    iff_open_ib_database('',IbDatabase1)thenbegin

    display('ok_open');

    withIbSql1dobeginClose;

    Database:=IbDatabase1;end;

    iff_execute_ibsql(IbSql1, k_create_strlen)thendisplay('ok_strlen');

    end;end; // create_udf_Click

    3.2.3 - Suppression d'une fonction externe

    Pour retirer cette fonction du moteur Interbase, nous appelons naturellement:

    DROPEXTERNALFUNCTIONStrLen

  • 8/10/2019 Interbase Borland Data Provider

    44/124

    Le code se trouve dans le .ZIP tlchargeable

    3.2.4 - Liste des fonctions

    Et pour vrifier si la fonction est bien enregistrer, nous utilisons un

    composant IbExtracten lui demandant d'afficher les UDF:

    procedureTForm1.display_udf_Click(Sender: TObject);

    // -- extract all the stored procedures

    varl_item: Integer;

    begin

    initialize_ib_database(k_database_name, k_user, k_password, IbDatabase1);

    iff_open_ib_database('', IbDatabase1)

    thenbegin

    withIBExtract1do

    begin

    ExtractObject(eoFunction, '');

    withItemsdo

    forl_item:= 0 toCount- 1 do

    display(Strings[l_item]);

    end; // with IBExtract1

    end;

    end; // display_udf_Click

    Voici le projet ce stade:

  • 8/10/2019 Interbase Borland Data Provider

    45/124

    3.2.5 - Test des UDF

    Pour utiliser une fonction externe, nous l'appelons depuis une requte SQL, que

    celle-ci soit lance depuis le Clientou depuis une procdure catalogue.

    Dans le cas de StrLen, nous pouvons appeler, par exemple:

    SELECTStrLen(f_location) FROMtrainingWHEREf_id= 105

    DepuisDelphi, nous utilisons unIbQueryet rcuprons la valeur dans la premirecolonne de la rponse:

    constk_select_strlen= 'SELECT F_LOCATION, STRLEN(F_LOCATION) '

    + ' FROM TRAINING WHERE f_id= 105';

    procedureTForm1.select_strlen_Click(Sender: TObject);varl_rtrim_name, l_name: String;begin

    initialize_ib_database(k_database_name,k_user, k_password,IbDatabase1);

    iff_open_ib_database('',IbDatabase1)thenbegin

    display('ok_open');

    open_ibquery(display_udf_ibquery_, k_select_strlen);

    l_name:= display_udf_ibquery_.Fields[0].AsString;l_rtrim_name:= display_udf_ibquery_.Fields[1].AsString;

    display(IntToStr(Length(l_name))+ ' |'+ l_name+ '|');display(l_rtrim_name);

    end;end; // select_strlen_Click

    3.2.6 - Test pralable des fonctions

    Pour certaines fonctions (RPad, par exemple), nous avons eu un peu de mal faire

    fonctionner le tout. Nous avons alors test la fonction de la .DLL sparment, pour

    nous assurer que le code tait correct.

    Pour cela nous avons utilis une unit d'importation qui permettait d'appelerfacilement les fonctions de la .DLL:

  • 8/10/2019 Interbase Borland Data Provider

    46/124

    unitu_import_udf_string;

    interface

    constk_udf_string= 'd_string_udf.dll';

    functionf_trim_right(p_pchar:PChar):PChar;cdecl; externalk_udf_string;

    functionf_right_pad(p_pchar:PChar; varp_length:Integer;p_pad_pchar:PChar):PChar; cdecl; externalk_udf_string;

    functionf_string_length(p_pchar:PChar):Integer;cdecl; externalk_udf_string;

    functionf_sub_string(p_pchar:PChar;p_position,p_length:Integer):PChar; cdecl; externalk_udf_string;

    implementation

    end. // u_zzz

    Pour la fonctionRPAD, nous avions mme du mal comprendre ce que la fonctionfaisait (c'tait une fonction que nous n'avions pas crite initialement), et nous avonstest la fonction dans le projet mme (pour bnficier de tous les affichages de miseau point), avant de la rinjecter dans la .DLL

    3.3 - Surprises, Surprises

    Parmi les quelques curiosits:

    les valeurs entires doivent tre passes en paramtre VAR

    aprs avoir plac la .DLL dans le rpertoire UDF d'Interbase, il faut rebooter

    la machine

    comme toujours en Interbase, il vaut mieux rdiger les identificateurs des

    requtes qui crivent sur la base en MAJUSCULES (nous crons tout en

    minuscule, mais quelqu'un passe le tout en majuscules. LesSELECTneposent pas de problmes, mais les DROPou autres exigent des majuscules)

    lorsque nous plaons certaines UDF entre SELECTet FROM, elles ne sont

    pas prises en compte.

    RTRIMn'est pas utile dans le WHERE: apparemment, Interbasesupprime les

    espaces droite sans avoir besoin de RTRIM

    pour SUBSTR, la fonction extrait bien la sous-chane, mais retourne une

    chane de la taille maximale (85 dans notre cas), avec au dbut la sous-

    chane

    la fonction SUBSTRfournie avec Interbasea une autre smantique quenotre SUBSTR: nous utilisons

  • 8/10/2019 Interbase Borland Data Provider

    47/124

    SUBSTR(p_chane,p_position,p_taille)

    et eux

    SUBSTR((p_chane,p_indice_debut,p_indice_fin)

    Car il y a, en effet des UDF fournies par dfaut par Interbase. Pour l'anectdote,

    nous nous en sommes apperus, car le projet fonctionnait sans avoir copier la

    .DLL dans le rpertoire UDF, car les fonctions existaient dans la .DLL par dfaut

    IB_UDF.DLL. Toutes sauf RPAD, qui a donc provoqu une erreur (pas lors

    de CREATE EXTERNAL, mais lors de l'appel dans un SELECT )

    La preuve, voici le rpertoire des UDF (avant ajout de notre .DLL):

    Pour connatre le contenu de ces UDF, nous avons utiliser notre analyseur defichier PE (Portable Executable), qui affiche les fonctions exports par une .DLL(ou tout autre .EXE). Voici ce qu'il nous a fourni pour IB_UDF.DLL:

  • 8/10/2019 Interbase Borland Data Provider

    48/124

    Mais quelle est la syntaxe de ces UDF: en fait elles sont fournies comme exempled'UDF dans le rpertoire:

  • 8/10/2019 Interbase Borland Data Provider

    49/124

    Vous trouverez le source (C) des UDF, avec des commentaires bien crits, ainsique le script qui incorpore ces UDF dans une base quelconque.

    SQL Script Executer- John COLIBRI.

    rsum: un utilitaire qui permet d'excuteur des scripts Sql Interbase

    mots cl: SQL Script - Interbase - excution de script - script parser

    logiciel utilis: Windows XP personnel, Delphi 6.0, Interbase 6/7

    matriel utilis: Pentium 2.800 Mhz, 512 Meg de mmoire, 250 Giga

    disque dur

    champ d'application: Delphi 1 2006, Turbo Delphi sur Windows

    niveau: dveloppeur Delphi / Interbase plan:

    o Introduction

    o Principe

    o Le Projet Delphi

    o Tlcharger le code source Delphi

    1 - Introduction

    http://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#introductionhttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#introductionhttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#principehttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#principehttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#telecharger_les_sources_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#le_programme_delphihttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#principehttp://www.jcolibri.com/articles/bdd/interbase/sql_script_executer/sql_script_executer.html#introduction
  • 8/10/2019 Interbase Borland Data Provider

    50/124

    Un excuteur de script SQL est un programme qui permet d'excuter une ou

    plusieurs requtes SQL provenant d'un fichier ASCII.

    Actuellement, les composants d'accs aux moteurs Sql grs parDelphine

    permettent d'excuter qu'une seule requte la fois. Cela convient parfaitementpour rcuprer par un seul SELECTtoute une Table, ou pour modifier des lignespar un seul UPDATE. Mais lorsqu'il s'agit de crer une nouvelle base, avec crationde Tables, procdures catalogues, Triggers, et remplissage initial des Tables, il est

    plus efficace de recourir des scripts.

    De nombreux outils, dont IbConsole qui est fourni avecDelphi, permettent delancer des scripts.

    Nous prfrons utiliser notre propre mcanique, et pour deux raisons au moins

    la plupart des outils de gestion de base de donnes ncessitent la frappe

    clavier de nombreux paramtres: nom d'utilisateur, mot de passe, nom du

    fichier contenant le script etc. Si tout se pass bien, la rigueur. Mais si le

    script contient des erreurs, il faut morceler le texte en plusieurs parties,

    lancer ces parties les unes aprs les autres, recommencer aprs avoir

    corrig les erreurs du script. Cela devient assez vite fatiguant

    certains de nos clients doivent pouvoir initialiser une base (nouvel exercice,

    ajout d'un tablissement etc). Nous prfrons leur fournir un

    logiciel Delphiqui s'en charge, plutt que de leur demander delancer IbConsolepuis cliquer ici ou l

    2 - Principe

    Le texte du script contient les requtes les unes aprs les autres, avec unterminateur quelconque aprs chaque requte.

    En ce qui concerneInterbase:

    le terminateur initial est ";"

    /* Table: PORTAL_ROLES, Owner: SYSDBA */

    CREATETABLE"PORTAL_ROLES"(

  • 8/10/2019 Interbase Borland Data Provider

    51/124

    "ROLEID" INTEGERNOTNULL,"PORTALID" INTEGERNOTNULL,"ROLENAME" VARCHAR(50),

    PRIMARYKEY("ROLEID"));

    /* Table: PORTAL_USERS, Owner: SYSDBA */

    CREATETABLE"PORTAL_USERS"(

    "USERID" INTEGERNOTNULL,"NAME" VARCHAR(50),"APASSWORD" VARCHAR(50) NOTNULL,"EMAIL" VARCHAR(100) NOTNULL,

    PRIMARYKEY("USERID"),CONSTRAINT"K_PORTAL_USERS_MAIL" UNIQUE("EMAIL")

    );

    Ici les deux crations de table sont termines par ";" comme certaines procdures catalogues contiennent aussi des ";", la

    convention courante (en tout cas celle d'IbConsole) est de changer

    temporairement de terminateur en utilisant la pseudo instruction SET

    TERM(SET TERMinator)

    /* generators */

    CREATEGENERATOR"USER_ITEMID";SETTERM^ ;

    /* Stored procedures */

    CREATEPROCEDURE"CLEANUP"ASBEGINEXIT; END^

    CREATEPROCEDURE"PORTAL_GETSINGLEROLE"(

    "ROLEID" INTEGER)RETURNS(

    "ROLENAME" VARCHAR(50))ASBEGINEXIT; END^

    Notez que

  • 8/10/2019 Interbase Borland Data Provider

    52/124

    o SET TERMse termine (encore) par ";"

    o les deux requtes qui suivent comportent les ";" des procdures

    catalogues, mais ces requtes sont termines prsent par "^"

    Le travail effectuer est alors assez simple:

    supprimer les commentaires (textes entre /* et */)

    dbiter le texte en requtes en analysant ce qui se trouve termin par le

    terminateur courant (";" au dpart, puis la valeur indique parSET

    TERMpar la suite)

    Il suffit donc d'analyser le script et de lancer chaque requte dtecte.

    3 - Le Projet Delphi

    Le travail de l'analyseur

    Il s'agit l d'une version de plus du scanner de base, qui dtecte les commentairesde script, et les mots cls qui nous intressent: SET TERM. Nous avons aussi

    dcouvert que d'autres pseudo instructions devaient tre traites (limines, dans

    notre cas):

    SET SQL DIALECT

    COMMIT WORK

    SET AUTODDL OFF

    Nous incluons donc ces mots cls dans l'analyseur.

    L'analyseur de requte

    Voici l'analyseur

    tout d'abord la dfinition de la CLASSe:

  • 8/10/2019 Interbase Borland Data Provider

    53/124

    t_symbol_type= (e_unknown_symbol,

    e_identifier_symbol, e_integer_symbol, e_operator_symbol,

    e_string_litteral_symbol,

    e_comment_symbol,

    e_end_symbol);

    c_ib_script= class(c_text_file)m_symbol_type: t_symbol_type;m_blank_string, m_symbol_string: String;

    _m_previous_index:Integer;

    m_c_result_list: tStringList;m_request_index:Integer;

    m_is_SET_TERM, m_is_COMMIT_WORK, m_is_SET_AUTODDL:Boolean;m_terminator: Char;

    Constructorcreate_ib_script(p_name,p_file_name: String);

    functionf_initialized:Boolean;procedureinitialize_scanner;functionf_read_symbol:Boolean;proceduretest_scanner;

    functionf_remove_comment: String;

    procedureinitialize_request_scanner;functionf_next_request: String;

    functionf_get_request: String;

    DestructorDestroy; Override;end; // c_ib_script

    puis la fonction qui rcupre une requte:

    functionc_ib_script.f_get_request: String;

    varl_request: String;

    // -- here get_request()

    begin// f_get_requestm_is_SET_TERM:=False;m_is_COMMIT_WORK:=False;m_is_SET_AUTODDL:=False;

  • 8/10/2019 Interbase Borland Data Provider

    54/124

    repeatget_request;until(m_symbol_type= e_end_symbol)

    or(m_symbol_type e_comment_symbol);

    ifm_symbol_type= e_end_symbolthenl_request:= '';

    Result:= l_request;end; // f_get_request

    et cette fonction appelle:

    procedureget_request;

    varl_previous_identifier: String;

    functionf_is_SET_TERM:Boolean;beginResult:= (l_previous_identifier= 'SET')

    and(m_symbol_string= 'TERM')

    end; // f_is_SET_TERM

    functionf_is_COMMIT_WORK:Boolean;begin

    Result:= (l_previous_identifier= 'COMMIT')and(m_symbol_string= 'WORK')

    end; // f_is_COMMIT_WORK

    functionf_is_SET_AUTODDL:Boolean;beginResult:= (l_previous_identifier= 'SET')

    and(m_symbol_string= 'AUTODDL')

    end; // f_is_SET_AUTODDL

    varl_display:Boolean;

    begin// get_requestl_request:= '';l_display:=False;

    // -- break if found m_terminatorrepeatf_read_symbol;ifl_display

  • 8/10/2019 Interbase Borland Data Provider

    55/124

    thendisplay(Format('%7d ', [m_buffer_index])+ m_symbol_string);

    ifm_symbol_type e_comment_symbolthenbegin

    iff_is_SET_TERMthenbegin

    // -- get the terminatorf_read_symbol;m_terminator:= m_symbol_string[1];display('// -- SET TERM '+ m_symbol_string);m_is_SET_TERM:= True;

    // -- skip actual terminator and exit loopf_read_symbol;break;

    endelseiff_is_COMMIT_WORKthenbegin

    m_is_COMMIT_WORK:= True;endelse

    iff_is_SET_AUTODDLthenbegin

    // -- skip "OFF ;"f_read_symbol;m_is_SET_AUTODDL:= True;

    endelse

    ifm_symbol_string= m_terminatorthenbegin

    Break;end

    elsel_request:= l_request+ m_blank_string+ m_symbol_string;

    l_previous_identifier:= m_symbol_string;end;

    ifm_buffer_index=_m_previous_indexthenbegin

    display_bug_stop('no_progress');Break;end;

    _m_previous_index:= m_buffer_index;

    untilm_symbol_type= e_end_symbol;end; // get_request

  • 8/10/2019 Interbase Borland Data Provider

    56/124

    Lancer les requtes

    Le projet principal charge le texte du script et rcupre les requtes

    procedureTForm1.execute_script_Click(Sender: TObject);

    // -- here execute_request()

    varl_request: String;l_trimmed_request: String;

    begin// execute_script_Clickoriginal_memo_.Lines.LoadFromFile(g_script_path+g_script_file_name);

    ifnotFileExists(g_script_path+g_script_file_name)thendisplay_bug_stop('not_found '+g_script_path+g_script_file_name);

    connect_database_Click(Nil);

    withc_ib_script.create_ib_script('ib_script',g_script_path+g_script_file_name) do

    beginiff_initialized

    thenbegininitialize_scanner;

    repeatl_request:=f_get_request;ifnot(m_is_SET_TERMorm_is_COMMIT_WORKorm_is_SET_AUTODDL)

    thenbeginl_trimmed_request:=f_add_return_line_feed(l_request);l_trimmed_request:=f_change_returns_in_spaces(l_trimmed_request);l_trimmed_request:= Trim(f_remove_double_spaces(l_trimmed_request));

    ifexec_.Checkedthenbegin

    if (Pos('DIALECT', l_request)

  • 8/10/2019 Interbase Borland Data Provider

    57/124

    end; // execute_script_Click

    et chaque requte est lance par:

    procedureexecute_request(p_request: String);

    begin

    try

    ifIbDatabase1.DefaultTransaction.InTransaction

    thenIbDatabase1.DefaultTransaction.Commit;

    IbDatabase1.DefaultTransaction.StartTransaction;IbSql1.Sql.Text:=p_request;

    // -- for stored proceduresIbSql1.ParamCheck:=False;

    IbSql1.ExecQuery;IbDatabase1.DefaultTransaction.Commit;exceptone:Exceptiondobegin

    display_bug_stop('*** pb_'+ e.Message);end;

    end; // try except

    end; // execute_request

    Min manuel

    Le script

    Nous avons choisi de recrerla base MASTAPP.

    Le script est obtenu en utilisantl'extracteur de script.Le script est contenu dans lefichier schema_IB_MASTSQL_6.txt (dans le .ZIP tlchargeable ci-dessous)

    HowTo

    Pour utiliser le logiciel

    compilez le projet

    slectionnez le rpertoire et la base l'aide du tDirectoryListBoxde l'onglet "database". Puis

    http://www.jcolibri.com/articles/bdd/mastapp/mastapp.htmlhttp://www.jcolibri.com/articles/bdd/mastapp/mastapp.htmlhttp://www.jcolibri.com/articles/bdd/mastapp/mastapp.htmlhttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.htmlhttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.htmlhttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.htmlhttp://www.jcolibri.com/articles/bdd/interbase/sql_script_extraction/sql_script_extraction.htmlhttp://www.jcolibri.com/articles/bdd/mastapp/mastapp.html
  • 8/10/2019 Interbase Borland Data Provider

    58/124

    si la base existe slectionnez le fichier

    sinon, crez la base en cliquant "create_base_" dans l'onglet "script_"

    slectionnez le script qui vous intresse en utilisant le tDirectoryListBoxet le tFileListBoxde

    l'onglet "script_"

    slectionnez "exec_" puis cliquez "execute_script_"

    Voici l'image du projet:

    Quelques soucis

    Parmi les petites misres:

    il a fallu veiller restaurer les "Return LineFeed" complets (certains scripts

    ne contenaient, ici ou l, que des LineFeed UNIX

  • 8/10/2019 Interbase Borland Data Provider

    59/124

    les valeurs littrales des dates doivent tre un format commestible pour

    le moteur. Donc soit "mois, jour, anne", soit, et c'est nouveau pour nous,

    "anne, mois, jour"

    les guillemets sont placs dans le script du gnrateur de script, mais

    doivent tre retirs pour l'excution des scripts les blobs doivent faire l'objet d'un traitement spar (mettant en oeuvre

    des tStreams)

    En tant un rien cynique, nous pourrions rcuprer les sources deIbConsole, qui

    sait bien franchir toutes ces barrires sans souci. En attendant, cet utilitaire a

    rempli les missions que nous avions envisages.

    Tutorial Interbase- John COLIBRI.

    mots cl:tutorial - Interbase - Client Serveur logiciel utilis: Windows XP, Delphi 6, Interbase 6 matriel utilis: Pentium 1.400Mhz, 256 M de mmoire

    champ d'application: Delphi 1 7 sur Windows, Kylix niveau: dbutant Delphi et Base de Donnes plan:

    o Introductiono Installationo Crer la Baseo Crer une Tableo Ajouter des Donneso Lire et Affichero Modifier des Donneso Effacer de Donneso Plusieurs Tableso Tlcharger les Exemples

    o Conclusion

    1 - Introduction

    Ce tutorial va vous indiquer comment utiliser le ServeurInterbasefourni avecDelphi. Ce tutorial a plusieurs objectifs:

    vous prsenter intgralement comment raliser des applications utilisant des

    bases de donnes Sql en Delphi. Tous les exemples ont t cods et lessources sont tlchargeables.

    http://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#introductionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#introductionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#installationhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#installationhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#crer_la_basehttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#crer_la_basehttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#crer_une_tablehttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#crer_une_tablehttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#ajouter_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#ajouter_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#lire_et_afficherhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#lire_et_afficherhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#modifier_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#modifier_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#effacer_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#effacer_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#plusieurs_tableshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#plusieurs_tableshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#telechargerhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#telechargerhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#conclusionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#conclusionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#conclusionhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#telechargerhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#plusieurs_tableshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#effacer_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#modifier_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#lire_et_afficherhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#ajouter_donneeshttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#crer_une_tablehttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#crer_la_basehttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#installationhttp://www.jcolibri.com/articles/bdd/interbase/interbase_tutorial/interbase_tutorial.html#introduction
  • 8/10/2019 Interbase Borland Data Provider

    60/124

    effectuer toutes les oprations en Delphi, plutt que de prsenter une sried'outils annexes dont la prsentation alongerait l'expos

    insister sur les points qui posent problme (cration d'une base, chane de

    connection, modification de dbGrid) plutt que sur les composants visuelsassez intuitifs au demeurant

    prsenter les composants rellement utiliss pour grer des tables Sql(des tIbQuery) plutt que des composants gnriques (tIbTable) dont lestraitements automatiques masquent le fonctionnement rel d'un ServeurSql

    limiter au maximum le nombre de composants utiliss pour manipuler lesdonnes du Serveursans perdre en fonctionnalit

    Si aprs ce premier contact vous souhaitez approfondir vos connaissances, nousvous proposons soit desformationsou des prestations de programmation etd'assistance.

    Nous nous adressons pour ce tutorial un programmeur Delphi:

    ayant une ide lmentaire de Delphi:Palette,Inspecteur, OnClick. Tout lereste sera expliqu

    n'ayant pas ncessairement de connaissance SQL. Le fonctionnement desrequtes et leur syntaxe sera prsent

    2 - Installation

    2.1 - Principe

    Le logicielInterbasecomporte essentiellement deux parties:

    le programme Serveur(le moteur), qui en gnral est plac sur un PC distant le programme Client, qui dialogue avec les programme applicatifs

    (Delphiou autre).

    Il faut donc installer les deux parties (sur la mme machine ou sur des PC spars).

    Interbase peut fonctionner selon deux modes:

    le mode dit "local", pour lequel le moteur et le programme client sont sur lemme PC. La machine n'a pas besoin d'avoir les couches rseau (TCP\IP,

    Novell ou autre), ni de carte rseau (carte Ethernet ou liaison srie). Leprogramme applicatif communique avec le Client, qui appelle directement

    les routines du serveur (sans passer par des appels TCP\IP)

    http://www.jcolibri.com/formations/formations.htmlhttp://www.jcolibri.com/formations/formations.htmlhttp://www.jcolibri.com/formations/formations.htmlhttp://www.jcolibri.com/formations/formations.html
  • 8/10/2019 Interbase Borland Data Provider

    61/124

    le mode Client Serveuro les communications entre la DLL client et le Serveur passent par les

    couches rseau de Windows: il faut que ces couches rseau soientinstalles (mme si le Serveur et le Client sont sur le mme PC)

    o le programme applicatif devra dsigner le serveur en utilisant l'adresseIP du serveur.

    Dans les deux cas, l'installation se fait en utilisant l'installateur du CDDelphi(oudu CDInterbase). Nous prsenterons l'instalation partir du CDDelphi.

    2.2 - Installation avec Delphi

    Lors de l'installation deDelphi,Installshieldpropose d'installer aussiInterbase.

  • 8/10/2019 Interbase Borland Data Provider

    62/124

    Vous pouvez rpondre oui etInterbasesera install

    Si vous avez rpondu "Non", voici comment procder:

    2.3 - Installation du Mode Local

    Pour installerInterbaseen mode local:insrez le CDDelphi

    slectionnez "Interbase Desktop Edition"

    rpondez oui toutes les questions

    vous pouvez vrifier que

    le rpertoire "c:\Program Files\Borland\" contient bien un sous-rpertoire

    "Interbase" le rpertoire "c:\Windows\SYSTEM\" contient bien la DLL client "gds32.dll" le menu dmarrer propose prsent une option "Interbase" avec "Interbase

    Server Manager". Cliquez sur ce choix, et le gestionnaire du serveur apparat:

    2.4 - Installation du Mode Distant

    Installez le Serveursur le PC serveur, en procdant comme ci-dessus, maisslectionnez "Interbase 6 Server". La partie Clientinstalle sur le PCdu Serveursera utilise pour les logiciels de gestion du Serveur

    Installez le Clientsur le PC client:

    slectionnez "Interbase 6 Server"

    aprs les dialogues de copyright ou autres apparatra:

  • 8/10/2019 Interbase Borland Data Provider

    63/124

    slectionnez "Interbase Client"

    2.5 - Suppression d'Interbase

    Pour supprimerInterbase:ouvrez le Serveur Manageret cliquez "Stop" (pour arrter le moteur)

    ouvrez le panneau de configuration, slectionnez "Ajout / Suppression de logiciel",slectionnez "Interbase" et cliquez Oui partout

    3 - Crer la Base

    3.1 - SQL et la cration de bases

    Pour crer une base, il faut, pour tous les moteurs, utiliser des outils spciaux, lelangage SQL ne contenant pas de requte spcifique pour cette opration

    Pour Interbase, ce sont des primitives de l'API native du moteur qui permettentcette cration. Elle n'est pas possible depuis les composants gnrique d'accs auxdonnes (tTable, tQuery). En revanche, Jeff Overcash a ajout tIbDatabaselamthode qui utilise les APIInterbasenatifs et permet la cration de la base.

  • 8/10/2019 Interbase Borland Data Provider

    64/124

    Les lments fournir sont les suivants;

    le chemin DOS o sera plac le fichier .GDB le dialecteInterbase utiliser. En gros, le dialecte dtermine le traitement de

    certains types de donnesInterbase(en dialecte 3 nous pouvons utiliserdesInteger64 bits et des tTimeStamps, minuscule ou majuscule sontreconnus etc). Nous choisirons le dialecte 3 (le plus rcent).

    le nom d'utilisateur et le mot de passe du Serveur. Ce sont les noms duserveur par dfaut (la base n'tant pas encore cre, elle)

    des paramtres d'optimisation, tels que la taille des pages du cache

    Plus prcisment:

    le chemin est plac dans tIbDatabase.DataBaseName

    le dialecte est plac dans tIbDatabase.SqlDialect

    le nom d'utilisateur et le mot de passe, ainsi que les autres paramtres sontplacs dans la proprit fourre-toutParams

    la mthode de cration est simplement:

    tIbDatabase.CreateDataBase

    3.2 - Cration de la base

    Nous allons crer une base contenant les stages offerts par l'Institut Pascal. Nousplacerons cette base dans le rpertoire "..\data\" (situ au mme niveau que le.EXE. Le .ZIP tlchargeable crera ce rpertoire automatiquement). Le nom dufichier sera "Institut_Pascal.GDB".

    Pour crer la base:

    crez une nouvelle application et appelez-la "p_ib_create_base"

    slectionnez dans la page "Interbase" de laPalettele composant tIbTransaction:

    et posez ce composant sur la tForm

    slectionnez de mme une tIbDatabase

  • 8/10/2019 Interbase Borland Data Provider

    65/124

    et placez-la sur la tForm

    initialisezIbDatabase.DefaultTransactionversIbTransaction1

    utilisez un tButtonpour crer la base:

    placez un tButton, nommez-le create_base_, et crez sa mthode OnClick voici le code de cette mthode:

    procedureTForm1.create_database_Click(Sender: TObject);beginwithIbDatabase1dobeginDatabaseName:= '..\data\Institut_Pascal.gdb';SqlDialect:= 3;

    Params.Add('USER "SYSDBA"');Params.Add('PASSWORD "masterkey"');Params.Add('PAGE_SIZE 4096');

    CreateDatabase;end; // with IbDataBase1

    end; // create_database_Click

    compilez et excutez

    cliquezButton1

    le rpertoire ..\data\ contient bien le fichier "Institut_Pascal.GDB" dont la taille estd'environ 580 K

    Notez que:

    si le fichier formation.gdb existait dj il faut tester sa prsence (FileExists)et l'effacer (Erase)

    si nous souhaitons rpter la cration, il faudrait purger lesParamsavanttout ajout parAdd(Params.Clear)

    Vous pouvez tlcharger ce projet "ib_create_base.zip".

    http://www.jcolibri.com/scripts/fcolibri.exe?a=1?filename=ib_create_base.ziphttp://www.jcolibri.com/scripts/fcolibri.exe?a=1?filename=ib_create_base.ziphttp://www.jcolibri.com/scripts/fcolibri.exe?a=1?filename=ib_create_base.zip
  • 8/10/2019 Interbase Borland Data Provider

    66/124

    3.3 - Connection une base

    tIbDatabaseest utilis par la suite pour assurer les changes entre notre application

    et la base que nous venons de crer.

    Ce composant doit tre initialis avec:

    dansDataBaseName, la chane de connection qui esto si nous travaillons en local, le chemin:

    c:\programs\interbase\data\Institut_Pascal.gdbou

    ..\data\Institut_Pascal.gdbo l'URL du PC qui hberge le Serveur:

    127.0.0.1\ c:\programs\interbase\data\Institut_Pascal.gdbHostName\ c:\programs\interbase\data\Institut_Pascal.gdbwww.jcolibri.com\

    c:\programs\interbase\data\Institut_Pascal.gdb dansParams, les paramtres propres Interbase. Dans notre cas, les

    paramtres par dfaut du Serveur, plus le nom d'utilisateur et le mot depasse.

    Une fois les proprits initialises, nous pouvons tester la connection en

    basculant tIbDatabase.Connected sur True.

    A titre de vrification:

    posez un second tIbDataBasesur la forme

    initialisezIbDatabase2.DatabaseNameavec..\data\Institut_Pascal.gdb

    cliquez deux fois surIbDatabase2pour ouvrir l'diteur de tIbDatabase

    Delphi prsente le dialogue suivant:

  • 8/10/2019 Interbase Borland Data Provider

    67/124

    slectionnez "User Name" et tapez SYSDBA

    slectionnez "Password" et tapez masterkey

    supprimez la coche de "Login Prompt"

    le rsultat est:

    fermez l'diteur

    slectionnez Connectedet basculez sa valeur sur True

    au bout d'un "petit" instant, la valeur bascule sur True

  • 8/10/2019 Interbase Borland Data Provider

    68/124

    Notez que:

    la connection est le test IMPERATIF pour vrifier que nous pouvonstravailler enInterbase. Nous recommandons d'effectuer cette connectionsystmatiquement avant de poser des tonnes de composants sur la tFormoud'crire des milliers de lignes

    si nous connectons la base en mode conception,Delphiouvrira aussi la baselorsque l'excution sera lance. Ces deux connections sont comptabiliss parle gestionnaire de licencesInterbasecomme 2 connections spares (ce sont

    bien deux processus Windows). Si vous travaillez en utilisant laversionDelphid'Interbase, il vaut mieux fermer la connection en modeconception, puis la rouvrir lors de l'excution par:

    tIbDatabase.Open;

    4 - Crer une Table

    4.1 - Principe

    Nous allons crer une table contenant pour chaque formation:

    un code (par exemple 8)

    un nom (par exemple "Delphi Interbase") un prix (par exemple 1.400)

    Pour cela nous devons envoyer une requte en langage SQL versle ServeurInterbase.

    La syntaxe de cette requte est:

    CREATE TABLEformations(f_numero INTEGER, f_nom CHARACTER(11), f_jours INTEGER,f_prixNUMERIC(5, 2) )

    Il suffit donc de choisir un nom de table, et le nom de chaque colonne avec sontype.

    Parmi les types autoriss parInterbasecitons:

    INTEGERpour les valeurs entires 32 bits SMALLINTpour les valeurs entires 16 bits

    NUMERIC(decimales,prcision) pour une valeur numrique flottante

  • 8/10/2019 Interbase Borland Data Provider

    69/124

    DATEpour une date CHARACTER(taille) pour des caractres

    Pour envoyer cette requte vers le Serveur:

    nous utilisons un tIbDataBasequi assurera la connection vers le Serveur

    nous utilisons un tIbQueryo nous le relions tIbDatabaseo nous plaons la requte SQL dans sa propritIbQuery.SQL(via

    l'Inspecteurou en code)o nous appelons tIbQuery.ExecSql

    la cration n'est visible par tout le monde que si la transaction qui est utilisepour la cration de la table est confirme

    4.2 - Utilisation de SQL

    La requte envoyer au Serveurest place dans tIbQuery.Sql. tIbQuery.Sqlest undescendant de tStrings. Nous pouvons donc utiliser, par exemple:

    IbQuery1.Sql.Add('CREATE TABLE formations (f_numero INTEGER, f_nom CHARACTER(11))');

    Pour construire la requte: nous pouvons utiliserAddpour ajouter une ligne de requte, Textpour

    affecter une requte, Clearpour purger tout texte antrieur, oummeLoadFromFilepour lire un fichier .txt contenant la requte:

    IbQuery1.Sql.LoadFromFile('cree_formation.txt');

    La mise en page n'a aucune importance pour le Serveur: la requte peut tre

    rpartie en plusieurs lignes:

    tIbQuery.Sql.Add('CREATE TABLE');tIbQuery.Sql.Add(' formations ');tIbQuery.Sql.Add(' (f_numero INTEGER, f_nom CHARACTER(11))');

    nous pouvons entrer la requte en utilisant l'Inspecteurd'Objet. Si nouscliquons sur Sql,Delphiaffiche:

  • 8/10/2019 Interbase Borland Data Provider

    70/124

    et vous pouvez taper manuellement la requte dans la partie "SQL"

    nous pouvons aussi crer la Stringen plusieurs tapes par toutes lesprimitives de Stringtelles que la concatnation,Insert, le test parPosouautre. Par exemple:

    l_requete:= 'CREATE TABLE '+Edit1.Text+ ' (';l_requete:= l_requete+Edit2.Text+ ')';tIbQuery.Sql.Add(l_requete);

    4.3 - Comment a Marche

    Au niveau fonctionnement:

    lorsque nous construisons la requte parIbQuery.Sql.Add, ce texte derequte est ce stade une tStringsen mmoire de notre PC.

  • 8/10/2019 Interbase Borland Data Provider

    71/124

    C'est une tStringscomme n'importe quelle autre. Ce qui explique qu'aucune

    vrification de syntaxe n'est effectue. Lorsque nous excutons:

    IbQuery1.ExecSql;

    alors:o

    la requte est envoye au Serveurvia le Cliento le Serveurtraite la requte et:

    cre la table si la requte est correcte:

  • 8/10/2019 Interbase Borland Data Provider

    72/124

    retourne une erreur transforme parDelphien exception en cas

    de problme

    Notez que l'envoi de toute requte qui modifie des donnes du Serveur(et lacration d'une nouvelle table est bien une modification) ne peut se faire que par ducode (PAS en basculantIbQuery1.Activesur Trueen mode conception)

    4.4 - Les Transactions

    EnInterbase, toutes les requtes sont cres dans le cadre d'une transaction. Lestransaction sont un mcanisme qui garantit que plusieurs sont ralises en entier ouannules. L'archtype est le transfert bancaire: si nous dbitons DUPOND pourcrditer MARTIN, le systme doit garantir que soit les deux modifications sontralise ou aucune ne l'est.

    EnDelphi, les composants de bases de donnes utilisent par dfaut des transactionstransparentes pour le programmeur, mais nous pouvons grer les transactions nous-mme. C'est ce qui est recommand pourInterbase.

    EnInterbaseExpress, nous utilisons un composant tIbTransactionque nousconnectons tIbDatabase.DefaultTransaction. Les primitives sont:

    tIbTransaction.StartTransactionpour dmarrer une nouvelle transactionavant une ou plusieurs oprations tIbTransaction.Commitpour confirmer la suite d'opration,

    ou tIbTransaction.RollBackpour tout annuler. StartTransactionet