![]() |
Datenbank: Access • Version: ka • Zugriff über: Ado
Adoconnection liest keinen String
Hallöchen allerseits,
ich habe ein seltsames Problem. Seit langem setze ich nun schon Ado mit Access ein. Nun mit einem neuen Projekt tauchen Probleme auf die ich noch nie hatte. Zum Projekt: für die Connection nehme ich eine DatenmodulUnit mit AdoConnection. Auf dem Hauptformular stelle ich die Verbindung her, gespeichert und abgerufen wird der Connectionstring in der Registry. Bisher noch nie ein Problem. Wenn nun die Anwendung auf einem anderen Rechner ausgeführt und sich damit der String ändert wird zwar aufgefordert die Konfiguration neu einzugeben ! die gespeichert wird ! kommt es zu keinem Connect. Es wird immer auf den ursprünglichen String zurückgegriffen der bei der Entwicklung in der Adoconnection stand. Selbst wenn ich den String leere und neu compiliere kommt ein Authentifizierungsfehler beim Start der Anwendung. Fordere ich während der Laufzeit den Connect an (Opendatabase) kommt ein True zurück. Aber arbeiten mit der Db tut es trotzdem nicht -> Fehler bei der Authentifizierung! Beim nächsten Start der Anwendung beginnt das Spiel von vorne. Der Registry Eintrag ist völlig korrekt. Beim Formshow wird der Registryeintrag gelesen aber nicht von der Adoconnection benutzt, so denke ich jedenfalls. Hat jemand eine Idee dazu :) Grüße |
AW: Adoconnection liest keinen String
Hast Du mal mit dem Debugger durchgesteppt ?
2 Stellen als Einstieg, BeforeConnect und das Setzen den ConnectionStrings |
AW: Adoconnection liest keinen String
In der Entwicklungsumgebung funktioniert es doch.
Da kann ich den Fehler nicht nachvollziehen. Wenn ich jedoch den String leere, knallt es beim ersten query. Obwohl beim Anwendungsstart :
Delphi-Quellcode:
mittels SetMinervaDSN die Adoconnection den String (DSN) setzen müsste.
if ReadDSNFromRegistry(DSN)=true then begin
if DataModule1.SetMinervaDSN(DSN)=true then
Delphi-Quellcode:
DSN habe ich geprüft und anzeigen lassen.Alles OK.
SetMinervaDSN:=true;
if Datenbank.Connected=true then if CloseDatabase=false then begin SetMinervaDSN:=false; Exit; end; Datenbank.ConnectionString:=DSN; Aber langsam nähern wir uns dem Problem. Danke für deine Antwort! |
AW: Adoconnection liest keinen String
Hast Du irgendwo eine Leiche im Keller?
Irgendein ADOQuery oder ähnliche, die ja eigene Connectionstrings halten können? In Kombi mit DesignTime Active=True und gespeichertem PW läuft es bei dir und auf dem anderen Rechner nicht (kein zugriff auf die MDB..?) Die Access MDB sollte natürlich auch via Netzlaufwerk identisch erreichbar sein. MSAccess Security, die bei Dir passend eingerichtet ist, bei dem anderen System aber nicht, wäre auch ne Idee... |
AW: Adoconnection liest keinen String
Die gleiche Idee hatte ich auch schon
aber nein leider nicht. Alles Querys sind "sauber". |
AW: Adoconnection liest keinen String
Warum nicht einfach
Delphi-Quellcode:
if ReadDSNFromRegistry(DSN) then
begin AdoConnection.Connected := false; AdoConnection.ConnectionString:= DNS; AdoConnection.Connected := true; end else Messagedlg('FEHLER',mtError,[mbok],0); |
AW: Adoconnection liest keinen String
Leicht OT:
Irgendwer hat hier vor ein paar Monaten propagiert, wann immer es geht mit nur einer Connection zu arbeiten, er scheint zu wissen warum. Gruß K-H |
AW: Adoconnection liest keinen String
Versuche mal vor dem setzen auf DSN
Delphi-Quellcode:
AdoConnection.ConnectionString='';
Ist DSN als Widestring deklariert? Auch so eine mögliche Fehlerquelle. Viele Grüße Sybok Factor |
AW: Adoconnection liest keinen String
Bei ADO Komponenten muss man folgende Regeln beachten!
1.) es darf nur eine einzige ADOConnection pro Datenbank geben 2.) alle ADOQuery, ADOTable, ADOCommand, ADODataset müssen auf diese Connection verweisen und dürfen keinen eigenen ConnectionString haben 3.) Property [ADOConnection].Connected muss zur Entwicklungszeit auf False sein 4.) ALLE Queries, Tables, ... müssen zur Entwicklungszeit inaktiv sein (Active=False) 5.) Sobald man im Objekt-Inspektor an einer Query herumspielt, wird die Query kurzzeitig aktiv. Damit wird aber auch die ADOConnection aktiv. Wenn man nicht aufpasst und einfach nur kompiliert kann Punkt 3.) verletzt werden. Projekt schliesen, neu öffnen und Build-All kann dann helfen. Zur Laufzeit ergibt sich dann folgendes Problem: Irgend eine ADOQuery steht versehentlich auf Active=True. Dies bewirkt automatisch, dass die ADOConnection verbunden wird. Allerdings ist zu diesem Zeitpunkt der ConnectionString noch nicht gesetzt. Damit wird ein falscher ConnectionString (nämlich der der auf die Entwickler DB zeigt) verwendet. Deshalb sollte man die Punkte 1. bis 5. genau beachten. |
AW: Adoconnection liest keinen String
@ shmia:
Im Großen und Ganzen hast du recht, aber ich habe durchaus Tabellen in TAdoDataSet zur Entwicklungszeit aktiv und kann trotzdem den ConnectionString zur Laufzeit umbauen. Ich nehme an, dass die Nichtbeachtung deiner Regeln bei Anwendungen zu Problemen führt, die alle Fenster bereits beim Programmstart erzeugen? Du hast mit deinem Hinweis recht, dass das Umbiegen des ConnectionStrings nur funktioniert, wenn die Connection nicht aktiv ist. Viele Grüße Sybok Factor |
AW: Adoconnection liest keinen String
Zitat:
Nur ist es bei vorallem bei grossen Projekten so, dass man die Reihenfolge in der Datenmodule und Formulare erzeugt werden nicht 100% im Griff hat. Lange Zeit läuft alles gut, aber vielleicht benötigt ein Formular dass frühzeitig erzeugt wird, ein weiteres Datenmodul. Auf diesem Datenmodul sitzt dann vielleicht dummerweise ein aktives ADODataset und schon hat man ein Problem. Noch gemeiner ist folgende Konstellation: In der IDE ist das Datenmodul auf dem die ADOConnection liegt geöffnet. (Connected=False) Jetzt braucht man nur versehentlich das Formular/Datenmodul mit dem aktiven ADODataset öffnen um etwas nachzuschauen und die Connection wird automatisch aktiv. *) Wenn man jetzt nicht aufpasst und in der IDE "Alles speichern" wählt wird die ADOConnection mit Connected=True abgespeichert. Aber man bemerkt das Problem nicht; erst auf dem Zielrechner beim Endbenutzer gibt es Ärger. *) die IDE müsste eine "Schatten"-ADOConnection, also eine Kopie der orginalen Connection benützen, dann wäre das Problem vom Tisch. |
AW: Adoconnection liest keinen String
Vielen Dank für Eure Antworten.
Diese " 5 Gebote" sind mir eigentlich bekannt. Habe aber trotzdem keine aktive Komponente gefunden. Interessant ist aber noch folgendes im OnClose Ereignis der Anwendung schreibe ich die DSN in die Registry, übernommen aus dem connectionstring der Ado. Diese ist aber die korrekte. Es ist aben nur beim Anwendungsstart, dass die "alte" versucht wird aufzubauen. Ist aber der String leer kommt der Authentifizierungsfehler. Es ist echt zum Mäuse melken... |
AW: Adoconnection liest keinen String
Liste der Anhänge anzeigen (Anzahl: 1)
Hast du schon einmal mit
![]() In einer UDL-Datei wird der gesamte ConnectionString gespeichert und kann vom Benutzer leicht (per Doppelklick!) geändert werden. Dein Programm braucht sich darum überhaupt nicht zu kümmern. Im Anhang ist eine UDL-Datei zum Testen. Hier ein Beispiel wie du die Connection herstellen kannst:
Delphi-Quellcode:
Und hier noch die Hilfsfunktionen:
if ADOConnection1.Connected then
// Prüfung, ob ADOConnection schon aktiv ist ShowMessage('Warnung: ADOConnection ist schon aktiv !'); // ConnectionString aus UDL-Datei zuweisen // UDL-Datei heisst genau gleich wie deine EXE; hat aber nur die Endung .udl ADOConnectionSetupUDL(ADOConnection1, ''); ADOConnection1.Connected := True;
Delphi-Quellcode:
uses ...,ADODB;
resourcestring SUDLMissing = 'UDL-Datei "%s" nicht vorhanden !'; // liefert Dateiname inkl. Pfad der Anwendung oder der DLL function GetModuleName: string; var hi : HINST; begin SetLength(Result, MAX_PATH); if IsLibrary then hi := HInstance else hi := 0; SetLength(Result, GetModuleFileName(hi, PChar(Result), length(Result))); end; procedure ADOConnectionSetupUDL(cn: TADOConnection; const UdlFile: string); var FileName: string; begin cn.Connected := False; FileName := UdlFile; if FileName='' then FileName := ChangeFileExt(GetModuleName, '.udl') else if ExtractFilePath(FileName) = '' then // Wenn kein Pfad übergeben wurde => Pfad der Exe eintragen FileName := ExtractFilePath(GetModuleName) + FileName; if not FileExists(FileName) then raise EADOError.CreateFmt('ADOConnectionSetupUDL(%s,%s) '#13#10+ SUDLMissing, [cn.Name,UdlFile, filename]); cn.ConnectionString := 'FILE NAME=' + FileName; end; |
AW: Adoconnection liest keinen String
@shmia
Die immer wieder auftretende Problematik mit geöffneten Datasets zu Entwicklungszeit lassen sich durch eine Flagüberprüfung in BeforeConnect in den Griff bekommen, wenn das Flag nicht gesetzt (gesetzt wir nach dem Lesen des ConnectionsStrings aus der INI/Registry/Konfiguration) ist wird ein Abort abgesetzt. |
AW: Adoconnection liest keinen String
Das seltsame daran ist doch eigentlich
dass ich die prinzipielle Vorgehensweise schon mehrmals eingesetzt habe. Nur diesmal geht irgendwas schief... Vllt. wäre es besser wenn mal jemand einen Blick darauf werfen könnte. Kann ja sein dass ich irgendwas übersehen habe. Grüße |
AW: Adoconnection liest keinen String
Zitat:
Ich setze in dem Event einfach den gewünschten ConnectionString ;) |
AW: Adoconnection liest keinen String
@Sir Rufo
Machen wir in vielen Anwendungen auch so, es gibt aber einige bei denen durch die Erstellungsfolge ein anderes Vorgehen erwünscht ist, daher haben die Templates/Frameworks an diesen Stellen o.g. Code drin, der dann gegf. ersetzt wird, quasi als Sicherung. |
AW: Adoconnection liest keinen String
[QUOTE=shmia;1157838]Hast du schon einmal mit
![]() In einer UDL-Datei wird der gesamte ConnectionString gespeichert und kann vom Benutzer leicht (per Doppelklick!) geändert werden. Dein Programm braucht sich darum überhaupt nicht zu kümmern. Im Anhang ist eine UDL-Datei zum Testen. Vielen Dank für Deine Anregung, ich habe alle Schritte nochmal verfolgt. Das setzen des Strings verläuft ohne Problem erst beim ersten query knallts. Jetzt habe ich keine Idee mehr, es ist wie verhext. .... |
AW: Adoconnection liest keinen String
Zitat:
Ich erschlage sie mit GExperts: Dort kann man einstellen, das Delphi vor dem Compilieren dafür sorgt, das alle Connections und Datasets geschlossen sind (Set Component Properties). Warum man nur eine Connection haben sollte, würde mich mal interessieren. Zum Problem: Abfragen auf true/false = unnötig und gefährlich. (mehr unnötig als gefährlich) Das löst aber nicht das Problem, sieht aber hübscher aus.
Delphi-Quellcode:
Der folgende Code aus Post #1 soll dein 'SetMinervaDSN' sein? So ist es moderner:
if ReadDSNFromRegistry(DSN) then begin
if DataModule1.SetMinervaDSN(DSN) then
Delphi-Quellcode:
Ich hatte solange die gleichen Probleme wie Du, bis ich die 5 Regeln (na ja, 2-5) strikt durch Verwendung der GExperts eingehalten habe.
Result := true;
if Datenbank.Connected then if not CloseDatabase then begin Result := false; Exit; end; Datenbank.ConnectionString := DSN; Bin ich auf einem fremden Delphi ohne GExperts, knallt mir das jedesmal um die Ohren. Zitat:
Das Schöne an unserem Beruf ist doch: So eine SW ist deterministisch. Wenn's gestern lief und heute nicht, ist nicht das Wetter oder die Stimmung Schuld, sondern das gottverdammte System. Du wirst zur Designzeit irgendwo rumgeklickelt haben, oder Delphi von mir aus von ganz alleine oder ein Kobold. Sorge stringent dafür, das beim Start des Programms alle Verbindungen und Datasets tot sind (Lade GExperts oder verwende Bummis Trick, wobei der 'nur' meckert, was aber auch ok ist) Noch ein Trick (auch bei Datasnap oder TCP): Suche per Explorer (Totalcommander, egal) in den (Text-)DFM-Dateien nach "Connected=True" oder "Active=True" usw. Wenn ich eine Stelle gefunden habe, war ich mir jedesmal sicher, das ich das unter Delphi geprüft hatte. Merke: Je komplexer die IDE, desto mehr unsichtbare Kobolde frickeln an deinem Code rum ;-) |
AW: Adoconnection liest keinen String
Manchmal stellt man sich auch selbst ein Bein, wenn Du einen ConnectionString in folgender Art aufbaust
Code:
und LoginPrompt auf false setzt bekommt man den beschrieben Fehler auch, in dem Fall das Speichern des Kennwortes zulassen oder LoginPromt auf True setzen oder den String über ein eigenes Loginfenster ergänzen lassen.
Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=test;Data Source=BUMMI-MOBI
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz