MySQl starten nach FileOpenDialog nicht möglich

  • Hallo,

    ich erstelle gerade ein Tool, dass Hostnamen und IP-Adressen aus einem Excel-Sheet einliest und in eine MySQL-Datenbank importiert. Bevor ich das jedoch mache, will ich erstmal überprüfen, ob es diesen Hostnamen bereits in der Datenbank gibt.
    Problem: wenn ich alles so ausführe, wie es im Code steht, dann bricht das Skript in der Funktion determineHosts beim Befehl
    _MySQL_InitLibrary()
    ab. Die Library befindet sich im Skriptverzeichnis und wird immer mit FileInstall mitgeliefert. Schließe ich somit aus. Die Daten für die SQL-Verbindung werden per Global Const nach den #include's und globalen Variablen-Definitionen definiert.
    Gleich vorweg. Der Zugriff auf die Datenbank funktioniert an anderer Stelle im gleichen Skript mit gleichem Query ohne Probleme (im Code aktuell auskommentiert). Selbst in der gleichen Funktion, 2 Zeilen bevor ich das Excelsheet öffne und einlese, kann ich den gleichen Select absetzen. Lasse ich den Part des Excelsheet-Einlesens weg, funktioniert auch der SQL-Befehl. Hier mal ein Ausschnitt des Codes:

    Spoiler anzeigen
    [autoit]


    While 1
    $nMsg = GUIGetMsg($GuiSchrank)
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $btnClose
    Exit
    Case $btnImport ; es wurde der Button "Importieren" gedrückt
    ;~ $schrankHostname = "Hostname" ; hier steht der Hostname des Schrankes zum Test
    ;~ $query = "SELECT * FROM mt2db_neu.netzdaten WHERE netzdaten.dnsname LIKE '" & $schrankHostname & "%';" ; gibt es den Namen schon in der Datenbank - Abfrage?
    ;~ determineHosts($query, "Netzdaten des Schranks ermitteln", $edtSchrankArray) ; Abfrage ausführen
    $tempInt = MsgBox(4, "Excel-Sheet importieren", "Sind Sie sich sicher, dass das Excel-Sheet aus zwei Spalten (Hostname, IP-Adresse) besteht?")
    If $tempInt = "6" Then
    $fileImport = FileOpenDialog("Bitte Excel-Sheet auswählen", "d:\Job\01-MT2-Client\01-Zarsen", "Alle (*.*)", 1) ; Datei zum auslesen auswählen
    $excelSheetHandle = _ExcelBookOpen($fileImport , 0, True) ; Datei öffnen ...
    $excelSheetArray = _ExcelReadSheetToArray($excelSheetHandle, 1, 1, 0, 2, True) ; ... in ein Array einlesen ...
    _ExcelBookClose($excelSheetHandle) ; ... und anschließend wieder schließen
    _ArrayDisplay($excelSheetArray) ; mal schauen, was da drin war
    $schrankHostname = StringStripWS($excelSheetArray[1][0], 8) ; in [0][1] steht der Hostname des Schrankes und den will ich ohne Leerzeichen
    $query = "SELECT * FROM mt2db_neu.netzdaten WHERE netzdaten.dnsname LIKE '" & $schrankHostname & "%';" ; gibt es den Namen schon in der Datenbank - Abfrage?
    determineHosts($query, "Netzdaten des Schranks ermitteln", $edtSchrankArray) ; Abfrage ausführen
    If UBound($edtSchrankArray) > 1 Then ; wird ein Array mit Inhalt zurückgeliefert?
    _text("Dieser Hostname existiert bereits in der Datenbank.")
    Else
    _text(UBound($edtSchrankArray))
    EndIf
    EndIf
    EndSwitch
    WEnd

    [/autoit]

    Und damit alle wissen, was sich hinter der Funktion "determineHosts" verbirgt. Es ist eine kleine Funktion, die als Parameter den SQL-Befehl, einen String (für evtl. Log-Einträge) und ein 2D-Array für die Ergebnisse entgegen nimmt.

    Spoiler anzeigen
    [autoit]


    ;#################### Funktion zum ausführen von MySQL-Abfragen der oben definierten Datenbank ####################
    Func determineHosts($query, $SuchString, ByRef $array)
    Local $data2
    Local $hostArray[1][2] ;Überbleibsel eines anderen Tools
    Local $functionName = "Ermitteln von " & $SuchString & ": " ;Überbleibsel eines anderen Tools

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Starten von MySQL
    _MySQL_InitLibrary()
    If @error Then
    Return
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Initialisierung der MySQL-Instanz
    $MysqlConnect = _MySQL_Init()
    If @error Then
    Return
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Verbindung zum MySQL-Server aufbauen
    $connected = _MySQL_Real_Connect($MysqlConnect, $db_server, $db_user, $db_password , $db_database)
    If $connected = 0 Then
    Return
    Endif

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Durchführen der Abfrage für die Zars-Zentralen (siehe Globale Variablendeklaration query1)
    If _MySQL_Real_Query($MysqlConnect, $query) = 0 Then
    $res = _MySQL_Store_Result($MysqlConnect)
    $fields = _MySQL_Num_Fields($res)
    $rows = _MySQL_Num_Rows($res)
    Else
    Return
    EndIf
    For $k = 1 To $rows
    $data2 = ""
    ;~ nächste Zeile des Ergebnissets holen
    $mysqlrow = _MySQL_Fetch_Row($res,$fields)
    ;~ Länge der Spalten der aktuellen Zeile ermitteln
    $lenthsStruct = _MySQL_Fetch_Lengths($res)
    ;~ Durchgehen der einzelnen Felder und speichern derer Inhalte im Array
    For $i = 1 To $fields
    $length = DllStructGetData($lenthsStruct, 1, $i)
    $fieldPtr = DllStructGetData($mysqlrow, 1, $i)
    $data = DllStructGetData(DllStructCreate("char[" & $length & "]", $fieldPtr), 1)
    If $i = $fields Then
    $data2 = $data2 & $data
    Else
    $data2 = $data2 & $data & "|"
    EndIf
    Next
    _Array2DAdd($array, $data2)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ;~ MySQL-Verbindung trennen
    _MySQL_Close($MysqlConnect)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ MySQL-Bibliothek schließen
    _MySQL_EndLibrary()
    Return $hostArray
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit]

    Was mache ich verkehrt? Vielleicht bin ich inzwischen AutoIt-Blind. Ein kleiner Anstoß in die richtige Richtung reicht schon. Bloß keine kompletten Lösungen. Danke. ;)

    Nachtrag:
    Bei weiteren Test's hat sich herausgestellt, dass der Excelprozess, der durch _ExcelBookOpen gestartet wird, nicht mit _ExcelBookClose geschlossen wird. Erst, wenn das Skript beendet wird, wird auch der Excel-Prozess beendet. Gibt es eine Möglichkeit den Prozess anders zu schließen (kein ProzessClose, da noch weitere Excel-Prozesse mit gleichem Titel laufen könnten). Vielleicht eine Option -f wie force? Ich weiß, diese Option gibt es nicht. 8) Hat aber eigentlich nichts mit dem eigentlichen Problem zu tun.

    Nachtrag 2:
    Damit die Funktion trotzdem ein "halbwegs" akzeptables Ergebnis liefert, habe ich den SQL-Befehl geändert und an eine andere Position verschoben. Die SQL-Abfrage sieht jetzt so aus:

    [autoit]


    $query = "SELECT * FROM mt2db_neu.netzdaten;"
    determineHosts($query, "Netzdaten des Schranks ermitteln", $edtSchrankArray) ; Abfrage ausführen

    [/autoit]

    Zuerst (eigentlich aus Versehen) direkt nach dem FileOpenDialog. Da stellte sich jedoch heraus, dass die Abfrage trotzdem nicht funktioniert. Anschließend habe ich den FileOpenDialog unter die Ausführung der SQL-Abfrage gesetzt und siehe da... es funktioniert. Bleibt am Ende also die Frage, Was macht dieser FileOpenDialog so dass eine SQL-Session nicht gestartet werden kann? Und werde ich jemals eine Antwort auf meine Fragen bekommen? Ich weiß, dass viele in diesem Forum helle Köpfchen sind. Aber den Grund für dieses Verhalten kennt wahrscheinlich niemand. ;(

    Nachtrag 3:
    Dieser Nachtrag untermauert eigentlich schon das, was ich im Nachtrag 2 geschrieben habe. Ich habe zum Test den FileOpenDialog entfernt und die Variable, in die der Dateiname geschieben wird, hardcoded gesetzt. Die Excel-Funktionen laufen durch und das anschließende SQL-Statement gibt auch das erwartete Ergebnis zurück.

    Gibt es eine Möglichkeit die Entwickler von AutoIt zu kontaktieren?

    7 Mal editiert, zuletzt von Grandpa (18. März 2014 um 07:53)

  • Hi,

    an alle, die sich den Kopf zerbrochen haben:

    Problem war, FileOpenDialog verändert bei Erfolg das Makro @WorkingDir und setzt den Wert auf das Verzeichnis, in dem die geöffnete Datei liegt. Da die Funktion _MySQL_InitLibrary() standardmäßig die dll im Arbeitsverzeichnis sucht, konnte die dll nicht gefunden werden. Es hat somit gereicht die Funktion zum initialisieren der MySQL-dll wie folgt aufzurufen:_MySQL_InitLibrary(@ScriptDir & "\libmysql.dll")

    Und wieder etwas schlauer. Der Thread kann also geschlossen werden. Danke trotzdem. 8)

  • Hier werden grundsätzlich keine Threads geschlossen, es genügt, wenn du den Präfix des Threads auf "gelöst" setzt.
    Dazu einfach den 1. Beitrag bearbeiten.

    There's a joke that C has the speed and efficieny of assembly language combined with readability of....assembly language. In other words, it's just a glorified assembly language. - Teh Interwebz

    C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, you blow off your whole leg. - Bjarne Stroustrup
    Genie zu sein, bedeutet für mich, alles zu tun, was ich will. - Klaus Kinski