Tables jointes Si vous devez lire des données provenant

publicité
Tables jointes
Si vous devez lire des données provenant simultanément de deux tables, vous
pouvez toujours appeler une commande SQL avec une jointure. Le résultat est
cependant une table unique, contenant des champs provenant de plusieurs tables
différentes. C’est très fonctionnel dans le cas où vous vous contentez d’afficher
les données, mais si vous permettez les modifications et voulez éventuellement
effectuer une mise à jour dans la base de données, les choses deviennent plus
compliquées.
Il devient en effet plus difficile de s’assurer que les règles d’intégrité entre les
tables sont respectées.
Il est aussi possible que certaines informations soient manquantes. Il y a peut-être
un sujet « Architecture » dans la table de sujets. Si aucune photo n’est cataloguée
dans ce sujet, il ne fera pas partie du résultat de la requête et vous n’aurez aucune
façon de savoir que ce sujet existe.
Vous perdez l’accès à certains mécanismes qui permettent d’automatiser les mises
à jour, qui ne fonctionnent que quand la commande de sélection est appelée sur
une table unique.
Il est donc souvent plus intéressant de remplacer la requête avec jointure par des
requêtes individuelles sur chacune des tables, et de recréer en mémoire les
relations liant les tables.
Vous pouvez le faire avec une commande SQL pour chaque table et plusieurs Fill
successifs sur le même DataSet, ce qui ajoutera une table à chaque appel :
dad.SelectCommand = comTblSujet
dad.Fill(dts, "Sujets")
dad.SelectCommand = comTblPhoto
dad.Fill(dts, "Photos")
Le DataSet dts contient maintenant une Tables(0) appelée Sujets et une Tables(1)
appelée Photos.
Access vous limite à cette approche, mais les bases de données permettant de
créer des procédures plus complexes permettent de faire le même travail en une
seule procédure.
Cette approche n’est pas utilisée dans l’application d’exemples, mais voici le code
qui récupérerait les tables de photos et de sujets et les lierait ensemble. Nous
créerions tout d’abord dans la base de données une procédure stockée appelant
séparément les deux tables :
CREATE PROCEDURE psPhotosSujet (@Doss varchar(255))
AS
SELECT
FROM
tbSujets.*
tbSujets
SELECT
FROM
WHERE
*
tbPhotos
(Dossier = @Doss)
GO
Vous constaterez que quand vous appelez une procédure stockée contenant
plusieurs commandes SELECT, le DataAdapter crée automatiquement une table
individuelle pour chacune des commandes. Les plus vieux d’entre vous
s’exclameront probablement : « cool ». Les plus jeunes diront plutôt « full au
boutte ».
Dim
Dim
Dim
Dim
Dim
Dim
con As New SqlConnection(pcConnectionString)
com As New SqlCommand
dad As SqlDataAdapter
dts As DataSet
tbPhoto As DataTable
tbSujet As DataTable
com.CommandText = "EXEC psPhotosSujet 'C:\Cours
ADONET\PhotoCatBD\Images'"
com.Connection = con
dad = New SqlDataAdapter(com)
dts = New DataSet
Try
dad.FillSchema(dts, SchemaType.Source)
Catch ex As SqlException
Stop
End Try
tbSujet = dts.Tables(0)
tbPhoto = dts.Tables(1)
tbSujet.PrimaryKey = New DataColumn() {tbSujet.Columns("NoSujet")}
dts.Relations.Add(New DataRelation("FK_tbSujet_tbPhoto", _
tbSujet.Columns("NoSujet"), tbPhoto.Columns("NoSujet")))
dad.Fill(dts)
À partir de ce point, vous êtes protégé comme si vous tentiez d’écrire dans la base
de données. Vous devrez ajouter un sujet inexistant avant de pouvoir l’assigner à
une photo, et ne pourrez détruire par inadvertence un sujet pour lequel vous avez
des photos.
Si, comme dans notre exemple, vous créez la relation avant de faire le Fill, il est
important que la procédure récupère la table de sujets avant la table de photos,
sinon vous aurez une erreur parce que les photos importées référencent des sujets
non existant. Les règles sont en effet actives pendant le Fill.
De même, lors de la mise à jour de la base de données, assurez-vous d’enregistrer
les ajouts faits à la table de sujets avant ceux de la table de photos, pour éviter que
les règles d’intégrités de la BD ne rejettent les photos référençant les nouveaux
sujets.
Téléchargement