[C++ & MySQL]Datenbankverbindung

Cloudchaser

Grünschnabel
Hallo tutorial.de!

Es war eigentlich nicht beabsichtigt, dass mein erster Beitrag direkt eine Frage ist :rolleyes: , aber es soll wohl so sein :eek: .

Also ich versuche im Moment bereits seit ein paar Tagen einen Zugriff durch C++ auf eine lokale MySQL-Datenbank zu realisieren. Ich habe mich bis jetzt durch alle möglichen Internetforen und Seiten gelesen und auch schon viele Fehler entfernen können, doch dass einzige was passiert ist das Auftauchen neuer Fehler. Dabei verwendete ich erstmal zum Testen nur Beispielcode.

Ich wüsste gerne, wie ich den OBCD verstehen muss - was ist es und wie verwende ich es? Habe es in Visual C++ eingebunden als Datenquelle, aber auch nur, weil gesagt wurde, dass man das machen muss. Auf Deutsch gesagt: Ich warte darauf, dass man irgendwo den Ort, den Benutzernamen und das Passwort für den Server eingeben muss...und dann später Befehle als String an die Datenbank schickt...habe es aber bis jetzt nicht gefunden :confused:

In den Code sind mittlerweile alle Headerdateien die gewünscht waren eingebunden (mysql.h und winsock2.h) aber leider haben sich jetzt nur die Fehler geändert und ich weiss im Moment nicht, was er eigentlich von mir will (abgesehen von: "Ich bin der Pc, das passt mir nicht, ändere es!" :p )

Die Fehlermeldung sieht so aus:
Code:
Kompilieren...
stdafx.cpp
Kompilieren...
Datenbankverbindung.cpp
c:\[...]\projects\datenbankverbindung\datenbankverbindung\datenbankverbindung.cpp(47) : warning C4267: 'Argument': Konvertierung von 'size_t' nach 'unsigned long', Datenverlust möglich
Manifest in Ressourcen wird kompiliert...
Verknüpfen...
Datenbankverbindung.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_mysql_error@4" in Funktion ""void __cdecl check_error(void)" (?check_error@@YAXXZ)".
Datenbankverbindung.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_mysql_errno@4" in Funktion ""void __cdecl check_error(void)" (?check_error@@YAXXZ)".
Datenbankverbindung.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_mysql_close@4" in Funktion "_main".
Datenbankverbindung.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_mysql_real_query@12" in Funktion "_main".
Datenbankverbindung.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_mysql_real_connect@32" in Funktion "_main".
Datenbankverbindung.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_mysql_init@4" in Funktion "_main".
C:\[...]\Visual Studio 2005\Projects\Datenbankverbindung\Debug\Datenbankverbindung.exe : fatal error LNK1120: 6 nicht aufgelöste externe Verweise.

"Mein" Code sieht im Moment so aus:
Code:
#include "stdafx.h"
#include <stdio.h> 
#include <stdlib.h>
#include "C:\Programme\Microsoft Platform SDK for Windows Server 2003 R2\Include\WinSock2.h"
#include "C:\Programme\MySQL\MySQL Server 5.0\include\mysql.h"
#include "C:\Programme\Microsoft Platform SDK for Windows Server 2003 R2\Include\Windows.h"


MYSQL  *my; 
void check_error(void)  
{ 
   if (mysql_errno(my) != 0) 
   { 
      fprintf(stderr, "Fehler: %s\n", mysql_error(my)); 
      exit(EXIT_FAILURE); 
   } 
} 

int main () 
{   
  // Handle 
   my = mysql_init(NULL); 
   if(my == NULL) 
   { 
      fprintf(stderr, " Initialisierung fehlgeschlagen\n"); 
      return EXIT_SUCCESS; 
   } 
   // verbindung mit server 
   if( mysql_real_connect(my, "localhost", "root", "root", NULL, 0, NULL, 0))   
   { 
      printf("Fehler"); 
   } else { 
      printf("Erfolgreich mit dem MySQL-Server verbunden\n"); 
   } 
   // mysql code 

   char *argument; 
    argument = "INSERT INTO `test` `id`='1'"; 
    mysql_real_query(my, argument, strlen(argument)); 
    check_error(); 
    
   // verbindung trennen 
   mysql_close (my); 
   return EXIT_SUCCESS; 
}

Muchas Gracias für alle Antworten. Kenne mittlerweile x Foren und Seiten...aber irgendwie scheint mein PC wohl sehr eigenwillig zu sein :suspekt:
 
Interessant, ich habe nur die Standard Bibliotheken von Visual C++ 6.0 verwendet, da ich nicht wusste, wie ich die MySQL++ Klasse einbinden kann...

Hier ist ein Kleines C++ Programm, welches ich geschrieben habe. Allerdings gehen manche SQL Befehle nicht wie "SHOW TABLES FROM databse;".

Hier mal das Programm (zum kompilieren muss es als MFC Programm ausgeführt -> Projekt -> Einstellungen):
Code:
#include <afxwin.h>
#include <afxdb.h>
#include <iostream>
#include <conio.h>
#include <stdio.h>


using namespace std;


void read()
{
	system("cls");

	CString ODBC;

	CDatabase db;
	ODBC = "DRIVER={MySQL ODBC 3.51 Driver};PORT=3306;SERVER=127.0.0.1;DATABASE=sample;USER=root;PWD=";

	db.OpenEx(ODBC, CDatabase::noOdbcDialog); // Connection-Daten: DSN(MySQL), UID(root), PWD(test)
	if(db.IsOpen() == 0)
	{
		cout << "Die Verbindung zur Datenbank konnte nicht hergestellt werden!" << endl; // Ausgabe: Verbindung nicht hergestellt
	}
	else
	{
		CRecordset rs(&db);
		rs.Open(rs.forwardOnly, _T( "SELECT * FROM Users" ));

		CDBVariant varValue;

		int n = rs.GetODBCFieldCount();
		int i = 0;
		int count = 0;

		while( !rs.IsEOF() )
		{
			count++;
			for(i = 0; i < n; i++)
			{
				rs.GetFieldValue(i, varValue, DEFAULT_FIELD_TYPE);
				
				switch(varValue.m_dwType)
				{
				case DBVT_NULL:
					cout << "NULL";
					break;
				case DBVT_BOOL:
					cout << varValue.m_boolVal;
					break;
				case DBVT_UCHAR:
					cout << varValue.m_chVal;
					break;
				case DBVT_SHORT:
					cout << varValue.m_iVal;
					break;
				case DBVT_LONG:
					cout << varValue.m_lVal;
					break;
				case DBVT_SINGLE:
					cout << varValue.m_fltVal;
					break;
				case DBVT_DOUBLE:
					cout << varValue.m_dblVal;
					break;
				case DBVT_DATE :
					cout << varValue.m_pdate;
					break;
				case DBVT_STRING:
					cout << varValue.m_pstring->GetBuffer(1);
					break;
				case DBVT_BINARY:
					cout << varValue.m_pbinary;
					break;
				default:
					break;
				}

				if(i < n)
				{
					cout << " - ";
				}
			
				varValue.Clear();
			}
			cout << endl;
			rs.MoveNext();
		}
		rs.Close();
		cout << endl << "-----------" << endl << "Rows: " << count << endl;
		cout << "Columns: " << n << endl << "Weiter ";
	}
	db.Close();
	getch();
	fflush(stdin);
}

void write()
{
	system("cls");

	char username[255], vorname[255], nachname[255];
	CString Vorname;
	CString Nachname;
	CString Username;
	CString ODBC;

	cout << "Username: ";
	cin >> username;
	cout << "Vorname: ";
	cin >> vorname;
	cout << "Nachname: ";
	cin >> nachname;

	Username.Format("%s",username);
	Vorname.Format("%s",vorname);
	Nachname.Format("%s",nachname);

	ODBC = "DRIVER={MySQL ODBC 3.51 Driver};PORT=3306;SERVER=127.0.0.1;DATABASE=sample;USER=root;PWD=";

	CString InsertString = "INSERT INTO user (username, vorname, nachname) VALUES ('" + Username + "', '" + Vorname + "', '" + Nachname + "')";

 	CDatabase db;
	db.OpenEx(ODBC, CDatabase::noOdbcDialog); // Connection-Daten: DSN(MySQL), UID(root), PWD(test)

	db.ExecuteSQL( InsertString );

	db.Close();
}

void main()
{
	int eingabe;

	do
	{
		system("cls");
		cout << "[1] Daten lesen" << endl;
		cout << "[2] Datensatz schreiben" << endl;
		cout << "[0] Ende" << endl;
		cout << "Auswahl: ";
		cin >> eingabe;
		fflush(stdin);

		switch(eingabe)
		{
		case 1:
			read();
			break;
		case 2:
			write();
			break;
		default:
			system("cls");
		}
	}
	while(eingabe != 0);
}
Erlaubt ein Webhoster externen Datenbankzugriff (Hostloco.de z.B.) dann kann man mit dem Programm auch darauf zugreifen. Man muss nur den Connection String ändern.


Gruß Radhad
PS: Ich entwickel gerade ein MFC Programm welches Daten sowohl aus MS Access als auch aus MySQL lesen kann. Dafür verwende ich auch oben stehende Code-Teile.
 
Danke für den Code und den Link zu den ConnectionStrings.
Ich werde das jetzt einfach mal ausprobieren. Auf jeden Fall ein wohl sehr gut funktionierendes Beispiel, wenn du es weiterentwickelst. Werde mir das 'Wie' anschauen und vlt finde ich ja Schwachstellen bei mir.

Ich fände es trotzdem toll, wenn ich es ohne MFC machen könnte...wenn noch jmd eine Ahnung hat, was das Problem beim o.g. Code sein könnte - ich freue mich auch über Hinweise - es müssen nicht perfekte Lösungen sein. :)
 
Hallo,
muß es den mit den MFC sein ?
In Qt kann ich dir das recht einfach erklären.....
MFG,
SuperSonik
 
Zuletzt bearbeitet:
Naja,
ich beschreibe es mal vielleicht hilft es ja auch anderen ....

Also neben allen anderen includes braucht man zunächst das include des Treibers.
Die Treiber liefert Qt mit, für ODBC muß man natürlich den ODBC Connector von MySQL installiert haben und unter Systemsteuerung->Leistung und W..->Verwaltung->Datenquellen
richtig eingerichtet haben.

Code:
#include <C:\Qt\4.1.0\src\sql\drivers\odbc\qsql_odbc.h>

Im Folgenden gehe ich immer davon aus, dass man die entsprechenden includes immer macht. (#include <QtSql/QSqlDatabase>,#include <QtSql/QODBCDriver>,#include <QtSql/QSqlQuery>, usw ...)

Der restliche Code ist eigentlich recht einfach:

Code:
			QString ip,dbname,username,passwort;
			ip ="123.123.123.123"; 
			dbname = "testdb";
			username = "mueller";
			passwort = "geheim";
	        QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
	        db.setHostName(ip);
	        db.setDatabaseName(dbname);
	        db.setUserName(username);
	        db.setPassword(passwort);
	        db.open();
			QSqlQuery query;
        	query.prepare("INSERT INTO testable(s1, s2, s3, s4) "
                      "VALUES (:s1, :s2, :s3, :s4)");
            query.bindValue(":s1", wert1);
            query.bindValue(":s2", wert2);
            query.bindValue(":s3", wert3);
            query.bindValue(":s4", wert4);
        	query.exec();

INSERT usw. würde natürlich ähnlich funktionieren.
Neben QSqlQuery gibts noch QSqlTableModel und ein paar andere Klassen bei denen man die SQL-Befehle nicht selber schreiben muß.
Gruß,
SuperSonik
 
Hört sich echt gut an...kann man so mitlesen. :)
Problem: Qt gibts irgendwie nur für MingW-Compiler...ich würde aber gerne in Visual Studio verbleiben...
 
Hört sich echt gut an...kann man so mitlesen. :)
Problem: Qt gibts irgendwie nur für MingW-Compiler...ich würde aber gerne in Visual Studio verbleiben...

Du kannst im Visual Studio bleiben. Du mußt nur make durch nmake ersetzen.
Es gibt sogar ein Tool, dass dir direkt ein Visual Studio Projekt erzeugt. - Ich weiß im Moment aber nicht mehr wie's heißt. Da mußt Du mal in der Doku nachschauen.
Ach, ja es gibt zwei Versionen von Qt einmal mit MinGW einmal ohne. Du brauchst die ohne.
Gruß,
Sonik
 
Okidoki...dann Danke für die Infos. _Noch_ funktioniert es nicht, aaaaber das wird sich ändern ^^. Im Zweifelsfall gibts für den PC Schläge auf den Hinterkopf....;-)
 
Howdy! ^^
Habe ein wenig weitergesucht und -probiert und alle Fehler ausmerzen können, bis auf einen neu aufgetauchten Fehler:

Code:
LINK : fatal error LNK1104: Datei 'C:\Programme\MySQL\MySQL.obj' kann nicht geöffnet werden

Ich habe die libmysql.lib beim Linker eingefügt bei den 'Befehlszeilen' unter den Projekteigenschaften in Visual C++ 2003 .NET eingefügt.Desweiteren habe ich unter den Konfigurationseigenschaften des Projektes in 'C/C++' die Laufzeitbibliothek auf 'Multithreaded (/MT)' umgestellt, was den Fehler von
MySQL.obj konnte nicht gefunden werden auf obigen Fehler umgeändert hat (was ja in gewisser Weise schon ein Fortschritt ist - sie ist immerhin schon da ;) ).

[edit]Klappt ^^...er hat bei dem o.g. Fehler das Leerzeichen im "MySQL Server"-Ordner nicht verstehen und hat deswegen Mist gebaut....
 
Zuletzt bearbeitet:
Hallo,

ich stehe jetzt an genau dem selben Punkt wie du. Auch bei mir kann er den mysql.obj file nicht öffnen. Du sagtest das es an den Leerzeichen im Ordnernamen liegt. Wenn ich dort die Leerzeichen entferne und dann die MySql-Konsole starte legt er aber automatisch wieder einen Ordner mit Leerzeichen im Namen an und das Problem bleibt das gleiche. Wie genau hast du das Problem gelöst?

Gruß
 

Neue Beiträge

Zurück