Bonjour à tous, et désolé si le sujet à déjà été traité mais je ne l'ai pas trouvé.
En toute honnêteté je n'ai pas dépassé la cinquième page.
J'utilise : Windows 8, Microsoft Visual Studio Express 2013 pour Windows desktop
Mon problème: Je récupère des éléments de type String dans un fichier et je voudrais les stocker dans une base MAIS uniquement s'ils n'existent pas; j'ai plusieurs fichiers (9) et plusieurs types d'éléments différents (3) et plusieurs bases de données (2).
Comme les opérations sont toujours les mêmes, mais pas dans les mêmes tables, j'essaye de développer des procédures communes.
La Table Base a la structure suivante:
Table Base
IndexBase numérique entier long
base texte court
J'ai fait le code suivant:
Ben oui ce n'est pas du texte ASCII; c'est du Sanskrit et du dévanagari d'où la fonction StrToHex qui permet de différencier les lettres Majuscules et minuscules
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 Public Class DataTable ' Table Data ' IndexData as long ' Data as string ' IndexBase as long Private MonIndex As Long Private NomTable As String Private NomIndexData As String Private NomData As String Private NomIndexBase As String Dim MesEnreg As System.Data.OleDb.OleDbDataReader Public Sub New(ByRef LeNomTable As String, _ ByRef LeNomIndexData As String, _ ByRef LeNomData As String, _ ByRef LeNomIndexBase As String) MonIndex = 0 NomTable = LeNomTable NomIndexData = LeNomIndexData NomData = LeNomData NomIndexBase = LeNomIndexBase BaseDétail.SQL_ViderLaTable(NomTable) End Sub Public Function ValeurIndex(ByRef Data As String, ByRef Base As String, ByRef Devanagari As String) As Long ' cette fonction vérifie si la clé Mot existe sinon la créée ' retourne l'index de la clé Dim IndexBase As Long Dim IndexMot As Long Dim Champs(2) As String Dim Valeurs(2) As String Dim Numérique(2) As Boolean ' on récupère l'index de la base; si elle n'existe pas, elle est créée au passage IndexBase = Table_Bases.ValeurIndex(Base, Devanagari) IndexMot = RetrouveIndex(Base) If IndexMot < 0 Then ' Ca n'existe pas, on le créé MonIndex = MonIndex + 1 Champs(0) = NomIndexData Valeurs(0) = MonIndex Numérique(0) = True Champs(1) = NomData Valeurs(1) = Data Numérique(1) = False Champs(2) = NomIndexBase Valeurs(2) = IndexBase Numérique(2) = True BaseDétail.SQL_Add(NomTable, Champs, Valeurs, Numérique) IndexMot = MonIndex Else ' le mot existe déjà dans la base ' on ne fait rien End If ValeurIndex = IndexMot End Function Private Function RetrouveIndex(ByRef Data As String) As Long Dim SQL As String Dim Trouvé As Boolean Dim str As String SQL = "SELECT " & NomIndexData & "," & NomData & " FROM " & NomTable & " WHERE " & NomData & "=""" & Data & """;" BaseDétail.SQL_Select(SQL, MesEnreg) If MesEnreg.HasRows Then str = StrToHex(Data) Trouvé = (str = StrToHex(MesEnreg(NomData))) While Not Trouvé And MesEnreg.Read() Trouvé = (str = StrToHex(MesEnreg(NomData))) End While If Trouvé Then RetrouveIndex = MesEnreg(NomIndexData) Else RetrouveIndex = -1 End If MesEnreg.Close() Else RetrouveIndex = -1 End If End Function End Class
J'ai développé les deux procédures suivantes dans une autre classe dont BaseDétail est une implémentation; cmd est une variable globale
J'utilise aussi plusieurs bases de données différentes, mais elles ont grosso-modo la même fonction; stocker des mots et des caractéristiques dans des tables liées entre elles
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 Public Interface DataBase Sub SQL_Select(ByRef SQL As String, ByRef LesEnreg As System.Data.OleDb.OleDbDataReader) Sub SQL_Add(ByRef NomTable As String, ByRef Champ() As String, ByRef Donnée() As String, ByRef Numérique() As Boolean) Function SQL_NbEnreg(ByRef NomTable As String, ByRef NomChamp As String) As Long Sub SQL_ViderLaTable(ByRef Nomtable As String) Function SQL_ValeurIndex(ByRef LesEnreg As System.Data.OleDb.OleDbDataReader, ByRef nomChampIndex As String, ByRef nomChampClé As String, ByRef Clé As String) As Long End InterfaceMon souci est que j'ai une exception me disant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 Public Class BaseDeDonnées : Implements DataBase ' on n'utilise pas de base intégrée Private Cn As New System.Data.OleDb.OleDbConnection Private Cmd As New System.Data.OleDb.OleDbCommand Private rd As System.Data.OleDb.OleDbDataReader '... pour éviter un texte trop long Public Sub SQL_Select(ByRef SQL As String, ByRef MesEnreg As System.Data.OleDb.OleDbDataReader) Implements DataBase.SQL_Select If Not IsNothing(MesEnreg) Then MesEnreg.Close() ' au cas où Cmd.CommandText = SQL Try MesEnreg = Cmd.ExecuteReader() Catch ex As Exception Alerte("BasedeDonnées.SQL_Select", SQL, ex.ToString) End Try End Sub Public Sub SQL_Add(ByRef NomTable As String, ByRef Champ() As String, ByRef Donnée() As String, ByRef Numérique() As Boolean) Implements DataBase.SQL_Add Dim SQL As String Dim I As Integer Dim NbData As Integer NbData = Donnée.Length - 1 For I = 0 To NbData Formate(Donnée(I)) Formate(Champ(I)) Next I SQL = "Insert InTo " & NomTable SQL = SQL & " (" & Champ(0) For I = 1 To NbData If Champ(I) <> "" Then SQL = SQL & ", " & Champ(I) Next I SQL = SQL + ") Values (" & Enrobe(Donnée(0), Numérique(0)) For I = 1 To NbData If Champ(I) <> "" Then SQL = SQL & ", " & Enrobe(Donnée(I), Numérique(I)) End If Next I SQL = SQL & ")" Try Cmd.ExecuteNonQuery() Catch ex As Exception Alerte("BasedeDonnées.SQL_Add", SQL, ex.ToString) End Try End Sub '... pour éviter un texte trop long Public Sub New(ByRef NomBase As String) Dim Tmp As String Tmp = "PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source =" & NomBase Try Cn.ConnectionString = Tmp Cmd.Connection = Cn Cn.Open() Catch ex As Exception MessageBox.Show("BasedeDonnées.new" & vbCrLf & ex.ToString) End Try End Sub End Class
D'où ma question: auriez vous une (ou des) suggestions, voire un code plus correct ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 System.InvalidOperationException: Un DataReader associé à cette Command est déjà ouvert. Il doit d'abord être fermé. à System.Data.OleDb.OleDbCommand.ValidateConnection(String method) à System.Data.OleDb.OleDbCommand.ValidateConnectionAndTransaction(String method) à System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method) à System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior) à System.Data.OleDb.OleDbCommand.ExecuteReader() à WindowsApplication1.BaseDeDonnées.SQL_Select(String& SQL, OleDbDataReader& MesEnreg) dans C:\Users\Alain\Desktop\Maharabata\VB\DétailSanskrit\BaseDeDonnées.vb:ligne 40
Partager