Remerciements▲
Je remercie Thomas Lebrun pour son tutoriel sur Oracle et .NET qui m'a servi de fil conducteur. Je remercie également phara (les habitués de developpez.com savent de qui je parle) pour la relecture de ce tutoriel.
I. Introduction▲
Dans ce tutoriel, nous supposerons que vous possédez déjà des notions d'ADO.NET.
Pour faire interagir une application .NET et DB2, vous pouvez utiliser les trois méthodes classiques :
- via ODBC, la méthode de connexion à une base de données la plus ancienne et la plus répandue, mais aussi la moins performante ;
- via OLEDB, la méthode la plus courante aujourd'hui et qui offre une certaine portabilité ;
- via un provider spécifique conçu exclusivement pour DB2, la méthode théoriquement la plus performante.
Ici, nous explorerons uniquement la troisième méthode. L'utilisation des deux autres méthodes ne différent en rien de leur utilisation avec une autre base de données si ce n'est la chaîne de connexion et des spécificités au niveau du langage SQL de DB2.
Actuellement, il existe deux providers spécifiques pour DB2. L'un produit par IBM et l'autre créé dans le cadre du projet MONO. Dans ce tutoriel, je parlerai essentiellement du provider DB2 développé par IBM toutefois, pratiquement tous les exemples fonctionnent également avec le provider fourni avec MONO.
II. IBM DB2 Data Provider▲
II-A. Le provider DB2 d'IBM▲
Le provider DB2 créé par IBM est disponible (en version bêta) au moins depuis la version 8.1.3. Il fait partie intégrante du projet « Stinger » qui a abouti à la version 8.2 où il est fourni en version de production. Personnellement, j'ai utilisé la version bêta 8.1.2.1. DB2 peut être téléchargé gratuitement en version personnelle ici. Vous pouvez également trouver la documentation complète du provider dotnet ici.
II-B. Le provider DB2 de Mono▲
Si vous utilisez Mono, ce provider fait partie intégrante du package. Aucune installation complémentaire n'est nécessaire. Si vous le désirez, Mono étant fourni sous licence GPL, vous pouvez extraire le provider du code source et le compiler avec le framework de Microsoft. Vous trouverez le projet Mono ici.
III. DB2 et .NET▲
III-A. Ajout des références▲
Avant d'utiliser le provider, vous devez ajouter une référence dans votre projet. Pour cela, que vous utilisiez VS.NET ou SharpDevelop, faites un clic droit sur références, dans votre explorateur de solution, puis choisissez « Ajouter une référence ». Choisissez « Parcourir » et sélectionnez le fichier IBM.Data.DB2.dll que vous trouverez en principe sous le répertoire c:\Program Files\IBM\SQLLIB\BIN\netf11.
Ultérieurement, vous pourrez retrouver directement la référence dans le premier écran sous l'appellation IBM.DATA.DB2.
III-B. Création de la connexion▲
Comme pour tout accès à une DB depuis .NET, la première chose à faire est de créer une connexion à DB2. Pour y parvenir, vous devez utiliser l'objet DB2Connection. Le paramétrage de votre connexion se fait au moyen de la propriété ConnectionString qui est initialisée via le constructeur.
// Création de la connexion.
string connString = "Database=Test;UID=myUser;PWD=myPassword";
DB2Connection conn = new DB2Connection(connString);' Création de la connexion.
Dim connString As String = "Database=Test;UID=myUser;PWD=myPassword"
Dim conn As DB2Connection = New DB2Connection(connString)Vous pouvez également séparer l'initialisation de la chaîne de connexion du constructeur.
// Création de la connexion.
DB2Connection conn = new DB2Connection();
conn.ConnectionString = "Database=Test;UID=myUser;PWD=myPassword";' Création de la connexion.
Dim conn As DB2Connection = New DB2Connection()
conn.ConnectionString = "Database=Test;UID=myUser;PWD=myPassword"III-C. Ouverture/Fermeture de la connexion▲
Pour ouvrir ou fermer la connexion, il suffit d'utiliser les méthodes Open et Close.
// Ouverture de la connexion.
conn.Open();
...
// Fermeture de la connexion.
conn.Close();
// Libération des ressources.
conn.Dispose();' Ouverture de la connexion.
conn.Open
...
' Fermeture de la connexion.
conn.Close
' Libération des ressources.
conn.DisposeVous pouvez connaitre l'état d'une connexion au moyen de la propriété State. Cette propriété est du type « ConnectionState ».
ConnectionState.Open
ConnectionState.Closed
ConnectionState.Connecting
ConnectionState.Executing
ConnectionState.Fetching
ConnectionState.BrokenIII-D. Exécuter une requête SQL▲
Pour exécuter une commande SQL, vous devez utiliser l'objet DB2Command.
// Création de l'objet DB2Command lié à notre connexion.
DB2Command sqlCmd = conn.CreateCommand();
// Requête SQL à exécuter.
sqlCmd.CommandText = "SELECT nom, prenom FROM monSchema.maTable";
// Type de requête. Les valeurs possibles sont Text, StoredProcedure et TableDirect.
sqlCmd.CommandType = CommandType.Text;' Création de l'objet DB2Command lié à notre connexion.
Dim sqlCmd As DB2Command = conn.CreateCommand
' Requête SQL à exécuter.
sqlCmd.CommandText = "SELECT nom, prenom FROM monSchema.maTable"
' Type de requête. Les valeurs possibles sont Text, StoredProcedure et TableDirect.
sqlCmd.CommandType = CommandType.TextIl ne vous reste alors qu'à appeler une des trois méthodes classiques que sont ExecuteNonQuery, ExecuteReader, ExecuteScalar.
III-E. Lecture des enregistrements▲
Pour lire les enregistrements, il suffit d'utiliser un objet DB2DataReader.
// Instanciation du Db2DataReader.
DB2DataReader reader = sqlCmd.ExecuteReader();
// Lecture des enregistrements.
while (reader.Read()){
MessageBox.Show(reader.GetString(0).Trim() + " "
+ reader.GetString(1).Trim());
}
reader.Close();' Instanciation du Db2DataReader.
Dim reader As DB2DataReader = sqlCmd.ExecuteReader
' Lecture des enregistrements.
While reader.Read
MessageBox.Show(reader.GetString(0).Trim + " " + reader.GetString(1).Trim)
End While
reader.CloseIII-F. Contrôler l'exécution avec une transaction▲
Pour gérer les transactions, vous disposez de l'objet DB2Transaction. Dans son utilisation la plus simple et la plus courante, on instanciera la transaction au moyen de la méthode BeginTransaction de l'objet DB2Connection. La transaction sera terminée au moyen de la méthode Commit ou de la méthode RollBack si celle-ci ne doit finalement pas être réalisée.
// Initialisation de la transaction depuis la connexion.
DB2Transaction trans = conn.BeginTransaction();
// Création et exécution de la/des commandes à exécuter.
DB2Command sqlCmd = conn.CreateCommand();
// La commande est placée sous contrôle de la transaction.
sqlCmd.Transaction = trans;
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = "INSERT INTO db2admin.Test2 (nom, prenom) VALUES ('A','A')";
try
{
if (sqlCmd.ExecuteNonQuery()!=0)
{
// La transaction peut être confirmée.
trans.Commit();
}
else
{
// Les opérations effectuées doivent être annulées.
trans.Rollback();
MessageBox.Show("Erreur d'écriture dans la base de données");
}
}
catch (Exception ex)
{
// Les opérations effectuées doivent être annulées.
trans.Rollback();
MessageBox.Show("Erreur d'écriture dans la base de données: " + ex.Message);
}
sqlCmd.Dispose();' Initialisation de la transaction depuis la connexion.
Dim trans As DB2Transaction = conn.BeginTransaction
' Création et exécution de la/des commandes à exécuter.
Dim sqlCmd As DB2Command = conn.CreateCommand
' La commande est placée sous contrôle de la transaction.
sqlCmd.Transaction = trans
sqlCmd.CommandType = CommandType.Text
sqlCmd.CommandText = "INSERT INTO db2admin.Test2 (nom, prenom) VALUES ('A','A')"
Try
If Not (sqlCmd.ExecuteNonQuery = 0) Then
' La transaction peut être confirmée.
trans.Commit
Else
' Les opérations effectuées doivent être annulées.
trans.Rollback
MessageBox.Show("Erreur d'écriture dans la base de données")
End If
Catch ex As Exception
' Les opérations effectuées doivent être annulées.
trans.Rollback
MessageBox.Show("Erreur d'écriture dans la base de données: " + ex.Message)
End Try
sqlCmd.DisposeIII-G. Les requêtes paramétrées▲
Il est bien évidemment possible de réaliser des requêtes paramétrées. Ce type de requêtes permet d'améliorer les performances, mais aussi d'éviter des problèmes de conversion de données lors de la concaténation de votre chaîne SQL. Vous pouvez constater dans le code ci-dessous qu'une date reste une date. Elles sont également nécessaires pour des raisons de sécurité dans la lutte contre l'injection de code SQL.
// Création de la commande.
Db2Command cmdSql = conn.CreateCommand();
cmdSql.CommandType = CommandType.Text;
cmdSql.CommandText = "SELECT nom, prenom FROM monSchema.maTable WHERE date>? AND pays=?";
// Ajout des paramètres.
cmdSql.Parameters.Add("Date",DB2Type.Date);
cmdSql.Parameters.Add("Pays",DB2Type.Char,2);
// Préparation de la commande sur le serveur.
cmdSql.Prepare();
// Passage des paramètres.
cmdSql.Parameters[0].Value = DateTime.Now;
cmdSql.Parameters[1].Value = "BE";
// Exécution de la commande.
Db2DataReader reader = cmdSql.ExecuteReader();' Création de la commande.
Dim cmdSql As Db2Command = conn.CreateCommand
cmdSql.CommandType = CommandType.Text
cmdSql.CommandText = "SELECT nom, prenom FROM monSchema.maTable WHERE date>? AND pays=?"
' Ajout des paramètres.
cmdSql.Parameters.Add("Date", DB2Type.Char)
cmdSql.Parameters.Add("Pays", DB2Type.Char, 128)
' Préparation de la commande sur le serveur.
cmdSql.Prepare
' Passage des paramètres.
cmdSql.Parameters(0).Value = DateTime.Now
cmdSql.Parameters(1).Value = "BE"
' Exécution de la commande.
Dim reader As Db2DataReader = cmdSql.ExecuteReaderIII-H. Remplir un DataSet▲
Pour remplir un DataSet, il suffit d'utiliser l'objet DB2DataAdapter exactement comme pour le provider OleDb.
// Création de la commande.
DB2Command cmdSql = new DB2Command();
cmdSql.Connection = conn;
cmdSql.CommandText = "SELECT * FROM db2admin.Test2";
// Création du DataAdapter.
DB2DataAdapter da = new DB2DataAdapter();
da.SelectCommand = cmdSql;
// Création du DataSet.
DataSet ds = new DataSet();
// On rempli le DataSet et on ferme le DataAdapter.
da.Fill(ds, "Test2");
da.Dispose();
cmdSql.Dispose();' Création de la commande.
Dim cmdSql As DB2Command = New DB2Command
cmdSql.Connection = conn
cmdSql.CommandText = "SELECT * FROM db2admin.Test2"
' Création du DataAdapter.
Dim da As DB2DataAdapter = New DB2DataAdapter
da.SelectCommand = cmdSql
' Création du DataSet.
Dim ds As DataSet = New DataSet
' On remplit le DataSet et on ferme le DataAdapter.
da.Fill(ds, "Test2")
da.Dispose
cmdSql.DisposeIII-I. Récupérer la structure d'une table▲
Il est très simple de récupérer la structure d'une table, pour cela, nous utilisons simplement la méthode GetSchemaTable. Dans l'exemple, nous afficherons uniquement les noms des champs. À vous de compléter pour obtenir les autres renseignements.
// Création de la commande.
DB2Command sqlCmd = conn.CreateCommand();
sqlCmd.CommandType = CommandType.TableDirect;
sqlCmd.CommandText = "monSchema.maTable";
// Lecture de la structure dans le DataReader.
DB2DataReader reader = sqlCmd.ExecuteReader(CommandBehavior.SchemaOnly);
// Exportation du schéma vers une DataTable.
DataTable schemaTable = reader.GetSchemaTable();
// Lecture du schéma.
Table tbl = (Table)tables["monSchema.maTable"];
foreach (DataRow row in schemaTable.Rows)
{
MessageBox.Show("Nom: " + (string)row["ColumnName"]);
}
reader.Close();' Création de la commande.
Dim sqlCmd As DB2Command = conn.CreateCommand
sqlCmd.CommandType = CommandType.TableDirect
sqlCmd.CommandText = "monSchema.maTable"
' Lecture de la structure dans le DataReader.
Dim reader As DB2DataReader = sqlCmd.ExecuteReader(CommandBehavior.SchemaOnly)
' Exportation du schéma vers une DataTable.
Dim schemaTable As DataTable = reader.GetSchemaTable
' Lecture du schéma.
Dim tbl As Table = CType(tables("monSchema.maTable"), Table)
For Each row As DataRow In schemaTable.Rows
MessageBox.Show("Nom: " + CType(row("ColumnName"), String))
Next
reader.CloseIV. Add-in pour Visual Studio▲
En plus du provider, IBM fournit un Add-in pour Visual Studio. Ce tutoriel n'ayant pas pour but de vous présenter cet Add-in, je vous laisse le découvrir ici.
V. Conclusions▲
Comme vous le voyez, travailler avec le provider spécifique de DB2 ne présente aucune difficulté particulière. Que vous soyez habitués à travailler avec OleDB, SqlServer ou un autre provider, le passage vers le provider DB2 se fera sans heurt. Ce tutoriel est loin de présenter toutes les fonctionnalités offertes, il ne vous reste plus qu'à découvrir le reste.
Il est par ailleurs regrettable qu'IBM ne mette pas plus avant ces possibilités. Je n'ai par exemple pas pu trouver la possibilité de télécharger le provider sans la version complète de DB2. Impossible également de trouver les mises à jour du provider. J'ai tenté également d'obtenir un complément d'information auprès d'eux, mais sans succès.




