MySQL UDF - mit libmySQL.dll (kein ODBC)

  • Hallo progandy,


    danke für die schnelle Antwort !


    Ich habe in der Tat ein 64-Bit-Windows 7 intalliert.
    Muss ich dann beim Programmieren irgendwelche Parameter anpassen ?
    Die Software ist nämlich für 32- und 64-Bit-Systeme gedacht.


    Wenn ich das richtig sehe, tritt der Fehler auf, da $connected 0 ist.
    In der UDF wird er aber nicht 0 gesetzt. Die Fehlermeldung wird ja in der If-Verzweigung generiert.


    In meinem Skript befinden sich noch keine MySQL-Abfragen, da ja noch keine Verbindung besteht.
    Ich frage mich gerade allerdings: Kann es sein, dass hier überprüft wird, ob es möglich ist
    $connected = 0 zu setzen. Beim Prüfen auf einen Wert muss doch "<>" verwendet werden, oder ?


    Dann würde die Verbindung ja etabliert, aber dann durch den Wert 0 überschrieben.


    Ich habe jetzt mal @error-Abfragen eingebaut.
    Das Skript sieht nun wie folgt aus (ganze Funktion):

    Func _connect() ;Server-Verbindungen herstellen
    ;FTP-Verbindung
    Local $ftp_connection_data[5] ;Array für FTP-Verbindungsdaten
    $ftp_connection_data[0] = "<>" ;FTP-Server
    $ftp_connection_data[1] = "<>" ;FTP-User
    $ftp_connection_data[2] = "<>" ;FTP-Passwort
    $ftp_connection_data[3] = "1" ;Passiv-Modus
    $ftp_connection_data[4] = "21" ;Server-Port


    Global $ftp_session = _FTP_Open("FTP_SESSION") ;FTP-Session wird geöffnet
    $ftp_connection = _FTP_Connect($ftp_session, $ftp_connection_data[0], $ftp_connection_data[1], $ftp_connection_data[2], $ftp_connection_data[3], $ftp_connection_data[4]) ;FTP-Verbindung herstellen

    ;MySQL-Verbindung
    Local $db_connection_data[5] ;Array für MySQL-Verbindungsdaten
    $db_connection_data[0] = "<>" ;MySQL-Server
    $db_connection_data[1] = "<>" ;MySQL-User
    $db_connection_data[2] = "<>" ;MySQL-Passwort
    $db_connection_data[3] = "<>" ;MySQL-Datenbank
    $db_connection_data[4] = "3306" ;Datenbank-Port


    Global $mysql = _MySQL_InitLibrary() ;MySQL starten
    If @error Then
    MsgBox(0, "@error-Abfrage nach _MySQL_InitLibrary()", @error)
    EndIf
    Global $db_connection = _MySQL_Init() ;MySQL initialisieren
    If @error Then
    MsgBox(0, "@error-Abfrage nach _MySQL_Init()", @error)
    EndIf
    $connected = _MySQL_Real_Connect($db_connection, $db_connection_data[0], $db_connection_data[1], $db_connection_data[2], $db_connection_data[3], $db_connection_data[4]) ;MySQL-Verbindung herstellen
    If @error Then
    MsgBox(0, "@error-Abfrage nach _MySQL_Real_Connect()", @error)
    EndIf

    If $connected = 0 Then ;prüfen, ob Verbindung erfolgreich hergestellt wurde
    $errno = _MySQL_errno($db_connection)
    MsgBox(0,"Error", $errno & @LF & _MySQL_error($db_connection)) ;Ausgabe einer Fehlermeldung
    If $errno = $CR_UNKNOWN_HOST Then
    MsgBox(0,"Error", "$CR_UNKNOWN_HOST" & @LF & $CR_UNKNOWN_HOST) ;Ausgabe einer Fehlermeldung
    _exit() ;Programm beenden
    Endif
    EndIf
    EndFunc


    Es kommen folgende Error-Meldungen:

    • nach _MySQL_InitLibrary(): 2
    • nach _MySQL_Init(): 1
    • nach _MySQL_Real_Connect(): 3
    • später: 0


    Viele Grüße
    sgfan

  • Du hast 3 Möglichkeiten:
    1) Immer als x86 kompilieren / ausfühern
    2) libmysql_x64.dll in das Skriptverzeichnis legen
    3) libMySQLdll.au3 inkludieren und bei InitLibrary den Parameter UseEmbedded auf true stellen.

  • Ich habe es nun als x86-Programm kompiliert, und es läuft einwandfrei.
    Vielen Dank für die schnelle Hilfe !!!



    Viele Grüße
    sgfan

  • Hallo progandy,
    gute Arbeit, aber kann das sein das die MySql Udf von dir kein Unicode Support hat? ;(



    _MySQL_Set_Character_Set($MySqlId, 'utf8')
    _MySQL_Real_Query($MySqlId, "INSERT INTO `Tabelle` (`Col1`, `Col2`) VALUES ('Unicode Zeichen: ♜' ,'Test')")

    Denn in der Tabelle kommt leider auch nur "Unicode: ?" an, und ja die Tabelle und Spalte ist auch mit "utf8_general_ci" deklariert.
    Bin so langsam am verzewifeln.


    Gruß
    Taz77

  • Taz77: Wenn du auf UTF8 stellst, musst du die Abfrage in UTF-8 übergeben. Um UTF8 statt eines normalen Strings zu verwende, mache folgendes:
    BinaryToString(StringToBinary($string, 4), 1)

  • gmmg über die console klappt alles wunderbar.


    @progandy
    danke dir das scheint zu funktionien, wobei das ganze jetzt ziemlich umständlich bzw performance lastig ist, wenn ich die daten aus der datenbank hohle und zb. in einem listview packe.
    Bei ca. 20 spalten und min. 500 daten.
    geht das nicht ggf auch anders?
    Mit der sqllite udf geht es ja auch einfach so, ohne das die daten doppelt umgewandelt werden müssen.
    Wenn ich das richtig verstehe wird der string von utf8 nach ansi umgewandelt, oder?

  • Anders funktioniert es nicht, höchstens du fängst an, DLLStructs zu verwenden und dort ist der Zugriff so weit ich weiß langsamer als die Konvertierung von Binary nach ASCII.


    Zitat

    Wenn ich das richtig verstehe wird der string von utf8 nach ansi umgewandelt, oder?


    Die Befehlskette macht folgendes.
    - Eingabe ist ein Unicode-String (AutoIt verwendet Unicode strings) --> Schritt kann nicht umgangen werden
    - Unicode wird in UTF-8 bytes gewandelt --> muss gemacht werden
    - Die UTF-8 bytes werden als ASCII interpretiert und in einen Unicode-String kopiert. (z.B. doppelbyte Zeichen in UTF-8 = 2 Zeichen in ASCII)
    - Der DLLCall erwartet einen ASCII-String und wandelt daher Unicode in die ASCII repräsentation. Das geht hier verlustfrei, da nur noch ASCII bytes im String sind.


    Die letzten beiden Schritte könnten durch DLLStructCreate, DLLStructSetData und dem Datentyp struct* statt str ersetzt werden, aber ob das schneller ist weiß ich nicht. Eventuell geht es schneller, wenn man für Schritte 1-3 _WinAPI_WideCharToMultiByte und struct* verwendet.

  • Danke für die Erklärung,
    aber ich bin noch ein wenig verwirrd, denn:
    - Ich habe eine *.au3 Datei die in UTF8 gespeichert ist,
    - dann frage ich die Datenbank ab,
    - welche auch in UTF8 erstellt worden ist.
    - MySql weise ich auch an, das die Daten auch in UTF8 übermittelt werden sollen.


    Also sollte doch dann auch UTF8 ankommen, und nicht ASCII...
    Somit ist _MySQL_Set_Character_Set($MySqlId, 'utf8') doch eigentlich total überflüssig, wenn die Daten auch nicht wie gewünscht ankommen.



    Ich hab ja auch schon mal versucht deine UDF mit der SqlLite zu vergleichen was wo anderes gelöst worden ist.
    Allerdings bin ich auch noch recht neu mit AutoIt unterwegs, und somit nicht wirklich schau daraus geworden,
    speziell was die DLLStructCreate, DLLStructSetData angeht.
    Ich hatte in dem DllCall von dir einfach mal versucht aus dem "str" ein "Wstr" zu machen, aber das hat leider nicht geklapt :whistling:


    Könntest du mir mal ein Beispiel geben, wie ich das ggf mit dem DLLStructCreate, DLLStructSetData und _WinAPI_WideCharToMultiByte machen könnte?
    Dankeschön :)