J'ai un petit morceau de code que j'essaie de courir dans lequel je vérifie d'abord si la valeur existe, puis mettez à jour ma base de données si elle ne le fait pas. Mon problème est que je peux exécuter une requête ou l'autre, mais pas les deux, car elle indique que la base de données est ouverte et n'est pas accessible. Je sais bien sûr que je puisse écrire dans la base de données. Il n'est pas lu protégé, situé là où je ne peux pas y accéder, etc. La routine fonctionne si j'essaie juste de mettre à jour et de ne pas vérifier. Le chèque n'entraîne définitivement aucun enregistrement. J'ai essayé des routines distinctes en utilisant des variables complètement différentes pour la connexion. Je suis stupéfié grand temps. J'ai essayé de fermer, d'utiliser, de disposer, mais j'ai besoin de quelqu'un beaucoup plus intelligent que moi de me conseiller de ce que je fais mal ... J'ai essayé des routines séparées, j'ai essayé ouverture, fermeture et re-ouverture. J'ai essayé une connexion, j'ai essayé deux. Est-ce que quelqu'un sait ce que je fais mal et pourquoi ça continue à me dire que la base de données est exclusivement ouverte et pourquoi elle ne me laissera pas l'écrire? P> Merci d'avance à ceux qui aident. P > p>
3 Réponses :
Le message d'erreur réel vous aurait dit qu'il y avait déjà un lecteur ouvert sur la connexion. La solution évidente consiste à fermer le lecteur de données que vous avez ouvert.
Il y a des problèmes graves avec votre code. Vous appelez exécutereader code> et c'est ce qui ouvre le lecteur de données qui bloque votre deuxième commande mais que vous ne faites jamais rien avec ce lecteur de données. Vous n'en attribuez pas à une variable afin que vous ne puissiez pas obtenir de données de celui-ci et vous ne pouvez pas la fermer non plus. Vous pouvez faire ceci: p>
Using connection As New OleDbConnection("connection string here")
connection.Open()
Dim query As New OleDbCommand("SELECT COUNT(*) > 0 FROM MyTable", connection)
If CBool(query.ExecuteScalar()) Then
'The table does contain data.
End If
End Using
J'utilise ce code lorsque j'essaie d'exécuter plusieurs instructions SQL:
Dim ConnectionString As String = ("Connection_String") 'LoginsVal is a Table, Dim SqlStr1 As String = ("Select Count(Accounts.DtCrtd) FROM Accounts WHERE Accounts.DtCrtd > " & Now.Date & ";") Dim SqlStr2 As String = ("INSERT INTO LoginsVal(LoginNm,DtMdfd) VALUES ('Test1'," & Now.Date & ");") 'DtCtrtd is Date DataType, Accounts is the Table Name Dim ThisCmd1, ThisCmd2 As New OleDbCommand Using ThisConn As New OleDbConnection With {.ConnectionString = ConnectionString} ThisConn.Open() 'Open connection With ThisCmd1 .Connection = ThisConn .CommandType = CommandType.Text .CommandText = SqlStr1 End With 'Debug.WriteLine(ThisCmd1.ExecuteScalar) 'use to test only without if statement below. If Convert.ToInt32(ThisCmd1.ExecuteScalar) <= 0 Then Debug.WriteLine("No records found") Else 'Your Next SqlStatement With ThisCmd2 .Connection = ThisConn .CommandType = CommandType.Text .CommandText = SqlStr2 End With Debug.WriteLine("Num of Rows affects is : " & ThisCmd2.ExecuteNonQuery) End If ThisCmd1.Dispose() ThisCmd2.Dispose() ThisConn.Close() 'Close connection End Using
Si un objet de base de données expose une méthode .Dispose, elle doit être appelée. Ceci s'applique aux connexions et commandes. Utilisez à l'aide des blocs. Pourquoi voudriez-vous vérifier l'état d'une connexion que vous venez de créer sur la ligne avant. Vous n'avez pas besoin de la syntaxe. Vous pouvez transmettre la chaîne de connexion directement sur le constructeur de la connexion. Vous exécutez chaque commande deux fois! .Exectescalar renvoie un objet. Vous ne pouvez pas l'écrire car ce n'est pas une chaîne et vous ne pouvez pas le comparer à 0 parce que ce n'est pas un nombre.
Je suis désolé que je ne sois pas silencieux en vous suivant ici, 1) Vous dites "si un objet de base de données expose une méthode .Dispose à laquelle il doit être appelé". Pourquoi tu tellement? Qu'est-ce que cela a à voir avec mon code? 2) Pourquoi voudriez-vous vérifier l'état d'une connexion que vous venez de créer sur la ligne avant ....... de cette connexion. J'ai déjà passé la chaîne de connexion directement au constructeur, encore une fois ce qui ne va pas? 3) Vous exécutez chaque commande deux fois ... Numéro. Comment suis-je exactement exécutant chaque commande deux fois? Oui vous avez raison la ligne debug.writeline () iforgot à omettre avant de commetter la réponse 'Merci
À propos de ExecutesCalar (oui, mais la seule erreur de mon code est '<=' il devrait être '<' seulement ou si ISDBnull () fonctionne à la place, comme ici:
1.) La méthode .Dispose doit être appelée car ces objets peuvent utiliser des ressources non gérées qui sont libérées dans la méthode .Dispose. 2.) `Utilisation de cette nouvelle OLEDBConnection (Connexionstring) est beaucoup plus courte. Inutile de vérifier l'état.
Count () ne retourne pas un dbnull. Cela a toujours une valeur.
S'il vous plaît activer l'option stricte. Ceci est un processus 2 parties. D'abord pour le projet actuel - dans la solution Explorer double-cliquez sur mon projet. Choisissez Compiler à gauche. Dans l'option Sélectionner une liste déroulante stricte sur. Deuxièmement pour les projets futurs - Allez dans le menu Outils -> Options -> Projets et solutions -> VB par défaut. Dans l'option Sélectionner une liste déroulante stricte sur. Cela vous évitera des bugs au moment de l'exécution.
OK @mary, selon Microsoft [ docs.microsoft.com/en-us/dotnet/api/... : Si l'OLEDBConnection est hors de portée, il n'est pas fermé. Par conséquent, vous devez expliquer explicitement la connexion en appelant près ou à éliminer, ou en utilisant la connexion dans une déclaration à l'aide de la déclaration (j'ai utilisé). À propos du code de l'état [OK et merci.] Toujours que cela doit être appelé de toute façon que le constructeur n'accepte que 2 propriétés, comme indiqué ici [ docs.microsoft.com/en-us/dotnet/api/...
Oui, votre connexion est bien en raison de l'utilisation mais la commande nécessite également une utilisation.
Count (): J'utilise mon code tel qu'il est selon cette page Microsoft ( docs.microsoft.com/en-us/dotnet/api/... ) Cette réponse (Stackoverflow.com/a/1999031/13393566 )
Laissez-nous Continuez cette discussion dans le chat .
Merci à tous pour votre aide, mais à 2 heures du matin, j'avais une épiphanie et réalisa que ce n'était pas la base de données qui était le problème. P>
J'avais quitté le StreamReader Open et c'était ce qui causait le problème. p>
J'ai pris à bord de vos commentaires et appréciez l'assistance pour développer un meilleur code. P>
Vous devez vraiment utiliser de meilleurs noms pour les choses. Utilisation de
COMD code> et
cmd code> pour distinguer deux objets de commande est un excellent moyen de provoquer une confusion. Que diriez-vous des noms descriptifs, par exemple
SelectCommand CODE> et
INSERTECOMMAND CODE>?