ODBC - SQLConnection...



  • Hallo zusammen,

    bin schon jetzt schon ewig auf der Suche im Netz und in eurem Forum nach der Funktion "SQLConnection".

    Mein Ziel: Verbindungsaufbau zu einer Datenquelle des ODBC's. (Beispiel: MySQL)

    Ich hab da schon viel zusammenprogrammiert mit C#, komme aber zum Thema Fremdschlüssel nicht weiter und muss wohl oder übel mit C++ weitermachen. Ich wollte mir eine kleine DLL schreiben die ich dann aus C# herraus aufrufe. Die DLL soll sozusagen hauptsächlich dazu da sein mir Fremdschlüssel zurück zu geben.

    Nun, da habe ich mir nun einiges Material angeschaut und komme nun einfach nicht weiter.

    Dabei bin ich auf folgende Seiten gestoßen, die mir den Grundsatz liefern:
    - http://vieka.com/esqldoc/esqlref/htm/odbcsqlconnect.htm
    - http://www.willemer.de/informatik/db/odbcapi.htm

    So... problem ist dass das alles irgendwie nicht komplett funktioniert.

    Ich lasse mir nach jeder Aktion das SQLRETURN zurückgeben.

    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
      // --> SQL_SUCCESS
      SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
      // --> SQL_SUCCESS
      SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDBC);
      // --> SQL_SUCCESS
    

    Soweit so gut.
    Aber nun kommt es zum SQLConnect:

    SQLConnect(hdbc, (SQLCHAR*) "TestMySQL", SQL_NTS,
                      (SQLCHAR*) "user1", SQL_NTS,
                      (SQLCHAR*) "pwd1", SQL_NTS);
    

    Problem hierbei ist gleich, er sagt mir sofort beim compilieren:
    error C2664:
    'SQLConnectW': Konvertierung des Parameters 2 von 'SQLCHAR *' in 'SQLWCHAR *' nicht möglich

    Also habe ich das SQLCHAR in SQLWCHAR umgeändert...

    SQLConnect(hdbc, (SQLWCHAR*) "TestMySQL", SQL_NTS,
                      (SQLWCHAR*) "user1", SQL_NTS,
                      (SQLWCHAR*) "pwd1", SQL_NTS);
    

    Klappt auch, er erstellt mir die Datei.
    So... schaue ich mir dannach das SQLRETURN an, kommt ein SQL_ERROR bei raus...
    Kein Plan. Liegt das daran das ich das auf SQLWCHAR umgeändert habe

    Datenquelle ist angelegt, User ebenfalls mit entsprechenden Passwort.

    Danke schon mal.

    Matscher



  • Offenbar compilierst du dein Projekt als UNICODE. Du übergibst aber keine UNICODE-Zeichenketten, sondern CHARs.



  • BAM! Das wars anscheinend...! 😃 Oha. Peinlich.
    Ähm... Danke! 🙂

    Ich schau mal weiter... vielleicht kommen noch weitere Fragen!

    Scheeen Gruß!
    Matscher



  • Um nicht ein neues Thema aufzumachen gleich die nächste Frage hier rein:

    Also, Verbindung wird aufgebaut und abgebaut.

    Jetzt versuch ich meine bissherigen Kenntnisse in ein Beispiel einzuarbeiten, da mein gefundenes Beispiel so gar nicht funktionieren kann (oder!?).

    Und zwar (vereinfacht):

    #define TAB_LEN SQL_MAX_TABLE_NAME_LEN + 1
    
    ...
    
    HSTMT hStmt;	// das Handle fuer die Anweisung
    HDBC hDBC;
    
    UCHAR szPkTable[TAB_LEN];
    SQLINTEGER lPkTable;
    
    // Verbindung aufbauen.
    SQLConnect(hDBC, ...); // Klappt ;-) Danke nochmal...
    

    So, Verbindung steht und freut sich, weiter ging das Beispiel damit mit SQLBindCol die kommenden Ergebnisse an szPkTable zu koppeln.
    Hier schießt sich das Programm aber ab. Ich dachte mir dass das eventuell daran liegt das der Handle für die Anweisungen noch nicht gestartet wurde. Also:

    SQLAllocHandle(SQL_HANDLE_STMT, hDBC, &hStmt);
    

    So habe ich das bei einen bei mir funktionierenden Beispiel für SELECT's gelesen. Also für die Funktion SQLExecDirect.

    Nun verbinde ich die Spalte und führe SQLPrimaryKeys aus:

    // Spalte verbinden
    SQLBindCol(hStmt, 3, SQL_C_CHAR, szPkTable, TAB_LEN, &lPkTable);
    // --> SQL_SUCCESS
    
    // Primärschlüssel lesen.
    SQLPrimaryKeys(hStmt, NULL, 0, NULL, 0, NULL, 0);
    // --> SQL_ERROR
    

    Anschließend wieder verbindung Handle freigeben und Verbindung abbauen.

    // Handle wieder freigeben
    SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    
    // Verbindung abbauen.
    SQLDisconnect(hDBC); // Klappt auch.
    

    So Problem ist insgesamt wie man sieht das die funktion PrimaryKeys nicht wirklich funktioniert. Ist das schon wieder so ein Problem mit Unicode und so? Sollte glaube ich nicht der Fall sein.

    Bei C# gibt es die Methode .GetSchema für eine OdbcConnection. Bei ihr kann man ebenfalls Argumente angeben u.a. "ForeignKeys" oder "PrimaryKeys" nur funktionieren diese Argumente nicht bei jedem Provider. Ist das bei C++ vielleicht auch der Fall?

    Gruß!

    Matscher



  • Versuch mal die Ergebnisspalten erst nach dem Aufruf von SQLPrimaryKeys0() binden. Vorher weiss die Datenbank ja noch gar nicht, was im Result-Set für Spalten vorhanden sein werden.

    Ausserdem musst du dem SQLPrimaryKeys natürlich sagen für welche Tabelle du die Primärschlüssel haben willst.



  • Mh...

    also hab das jetzt mal nach deinem Vorschlag umgebaut.
    Sieht jetzt folgendermaßen aus:

    ...
    SQLAllocHandle(SQL_HANDLE_STMT, this->hDBC, &this->hStmt);
    // Immernoch SQL_SUCCESS, logisch.
    
    LPSTR name_ = "Tabelle1";
    
    SQLPrimaryKeys(this->hStmt, NULL, 0, NULL, 0, (SQLCHAR *) name_, SQL_NTS);
    // Immernoch SQL_ERROR, unlogisch. :-(
    
    ...
    

    So, die Tabelle "Tabelle1" ist 100%ig vorhanden. Hat auch einen PrimaryKey.
    Das SQLBindCol habe ich erstmal auskommentiert, weiß auch was du meinst mit dem nach unten verschieben.

    Ich weiß nicht was er macht, er gibt mir eben immer ein SQL_ERROR zurück...



  • Tja, dann weiss ich auch nicht weiter. Dann würde ich mal per SQLError() den genauen Grund für den Fehler ermitteln.



  • Ahhh! Alles klaro. Ok, weiß bescheid. Der Treiber den ich verwendet hatte unterstützt die Funktion nicht...
    Hab das mal mit MySQL ausprobiert, dort funktioniert das.
    Wunderbar. Ich bedanke mich bei dir!

    Gruß

    Matscher


Anmelden zum Antworten