WinFuture-Forum.de: C++ Und Sqlite3 - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

C++ Und Sqlite3


#1 Mitglied ist offline   lord_fritte 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.216
  • Beigetreten: 15. April 05
  • Reputation: 0

geschrieben 03. Oktober 2007 - 17:54

Hallo ich versuche mich gerade an sqlite3 mit C++, nur bin ich jetzt auf ein Problem gestoßen.
Ich würde gerne Datensätze aus einer Datenbank lesen und diese in der main Funktion weiter bearbeiten, also ich möchte nicht der callback funktion arbeiten.
Jetzt habe ich im Internet ein Beispiel gefunden:
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"

typedef struct sqlite_vm sqlite_vm;

int sqlite_compile(
	sqlite3 *db,			  /* The open database */
	const char *zSql,		/* SQL statement to be compiled */
	const char **pzTail,	 /* OUT: uncompiled tail of zSql */
	sqlite_vm **ppVm,		/* OUT: the virtual machine to execute zSql */
	char **pzErrmsg		  /* OUT: Error message. */
);

int sqlite_step(
	sqlite_vm *pVm,		  /* The virtual machine to execute */
	int *pN,				 /* OUT: Number of columns in result */
	const char ***pazValue,  /* OUT: Column data */
	const char ***pazColName /* OUT: Column names and datatypes */
);

int sqlite_finalize(
	sqlite_vm *pVm,		  /* The virtual machine to be finalized */
	char **pzErrMsg		  /* OUT: Error message */
);

int main(int argc, char **argv){
	sqlite3 *db;		   /*Datenbank-Objekt*/
	sqlite_vm *dbcursor;
	char *dberr = 0;	  /*Fehlermeldungen*/
	char *sql, *sqltail;  /*SQL-Kommandos*/

	/*
	* Datenbankdatei öffnen
	*/
	if(!sqlite3_open("test2.s3db", &db)){
		printf("Hoppla: %sn", dberr);
		free(dberr);
		return 1;
	}


	/*
	* Beispiel für Select-Statement
	*/
	sql = "SELECT * FROM Mitarbeiter";
	/* Lege Statement-Cursor an (Konstruktor) */
	if(SQLITE_OK != sqlite_compile(db, sql, &sqltail, &dbcursor, &dberr)) { //Zeile 48
		printf("Oha: %sn", dberr);
		free(dberr);
	}else{
		int ncols;		/*Anzahl zurückgegebener Spalten*/
		char **colnames;  /*Spaltennamen*/
		char **values;	/*Spalteninhalte*/

		/* arbeite Ergebnis mit Cursor ab */
		while (SQLITE_ROW == sqlite_step(dbcursor, &ncols, &values, &colnames)) { //Zeile 57
			printf("nr='%s', name='%s'n", values[0], values[1]);
		}
	}

	/*
	* Datenbank schließen
	*/
	sqlite3_close(db);

	return 0;
}

Aber wenn ich den Code Compilieren möchte bekomme ich folgende Fehler:
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:: In function `int main(int, char**)':
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:48: error: invalid conversion from `char**' to `const char**'
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:48: error:   initializing argument 3 of `int sqlite_compile(sqlite3*, const char*, const char**, sqlite_vm**, char**)'
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:57: error: invalid conversion from `char***' to `const char***'
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:57: error:   initializing argument 3 of `int sqlite_step(sqlite_vm*, int*, const char***, const char***)'
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:57: error: invalid conversion from `char***' to `const char***'
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:57: error:   initializing argument 4 of `int sqlite_step(sqlite_vm*, int*, const char***, const char***)'
:: === Build finished: 6 errors, 0 warnings ===

Dieser Beitrag wurde von lord_fritte bearbeitet: 03. Oktober 2007 - 17:56

0

Anzeige



#2 Mitglied ist offline   Diewie 

  • Gruppe: aktive Mitglieder
  • Beiträge: 409
  • Beigetreten: 18. Juni 06
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Geisenhausen / München

geschrieben 03. Oktober 2007 - 22:01

Hi,

deine verwendete Methode stammt aus SQLite2 Zeiten und existiert leider mit der Version 3 nicht mehr. Z.B. wurde sqlite_compile zu sqlite3_prepare.
Die komplette SQLite3 Api findest du unter http://www.sqlite.org/capi3ref.html.

Ich habe deinen Quellcode etwas abgeändert. So dürfte er mit der aktuellen Version von SQLite funktionieren. Einziger Unterschied zu deinem Beispiel: Bei mir werden die Spalten 2 und 3 ausgegeben, weil meine Testtabelle anders aufgebaut war, aber dies kannst du ja leicht anpassen.

/*	SQLite3 Beispiel (http://www.winfuture-forum.de/index.php?showtopic=124876)
*
*	Autor: Stefan Diewald ([email protected])
*
*	SQLite3 C/C++ API: http://www.sqlite.org/capi3ref.html
*/

#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"

int main(int argc, char **argv){
	sqlite3 *db;			//Datenbank Zeiger
	sqlite3_stmt *stmt;		//Statement Zeiger
	char sql_str[1024];		//Anfrage String

	int dberr = 0;			//Fehler Integer

	//Datenbank öffnen oder neu erstellen
	if (SQLITE_OK != sqlite3_open_v2("test2.s3db", &db, 0, 0)) {
		printf("Fehler beim Öffnen der Datenbank: %s", sqlite3_errmsg(db));
		return 1;
	}

	//SQL Anfrage in sql_str kopieren
	_snprintf_s(sql_str, 1023, "SELECT * FROM Mitarbeiter");

	//Bytecode Programm aus der SQL Anfrage erstellen
	if (SQLITE_OK != sqlite3_prepare_v2(db, sql_str, -1, &stmt, 0)) {
		//Ausgabe von Fehler (z.B. bei Syntaxfehlern)
		printf("Fehler beim Vorbereiten der SQL Anfrage: %s", sqlite3_errmsg(db));
	} else {
		int ncols;		//Spaltenanzahl Integer

		ncols = sqlite3_column_count(stmt);		//Gibt die Anzahl der Spalten zurück

		//Solange Datensätze zurückgegeben werden
		while (SQLITE_ROW == sqlite3_step(stmt)) {

			//Werte aus Spalten 2 und 3 ausgeben (Index startet bei 0)
			printf("nr='%s', name='%s'\n", sqlite3_column_text(stmt, 1), sqlite3_column_text(stmt, 2));

			/* Bei weiterer Verarbeitung der Werte kann man mit
			*		int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
			*  die Größe des Rückgabewerts in Bytes bestimmen. */
		}
	}
	
	//Statement löschen
	sqlite3_finalize(stmt);

	//Datenbank schließen
	sqlite3_close(db);

	return 0;
}


Ich hoffe, das hilft weiter.

Gruß,
Stefan

Dieser Beitrag wurde von Diewie bearbeitet: 03. Oktober 2007 - 22:04

0

#3 Mitglied ist offline   lord_fritte 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.216
  • Beigetreten: 15. April 05
  • Reputation: 0

geschrieben 03. Oktober 2007 - 22:36

Danke!! :wink:

Dieser Beitrag wurde von lord_fritte bearbeitet: 03. Oktober 2007 - 22:37

0

#4 Mitglied ist offline   lord_fritte 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.216
  • Beigetreten: 15. April 05
  • Reputation: 0

geschrieben 04. Oktober 2007 - 16:16

Gibt es auch eine Funktion um auszugeben wie viel Datensätze gefunden wurden?
0

#5 Mitglied ist offline   Diewie 

  • Gruppe: aktive Mitglieder
  • Beiträge: 409
  • Beigetreten: 18. Juni 06
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Geisenhausen / München

geschrieben 04. Oktober 2007 - 23:18

Hi,

leider ist das nicht einfach so möglich, da durch den Aufruf von sqlite3_step erst der nächste Datensatz gesucht wird. D.h. man weiß erst wie viele Datensätze es gibt, nachdem sqlite3_step keine weiteren mehr zurückgibt/findet.

Einzige Methode um vorher zu bestimmen, wie viele Datensätze gleich zurückgegeben werden, ist die Verwendung einer SELECT-Abfrage mit COUNT().

"SELECT COUNT(*) FROM Mitarbeiter"
gibt einen Datensatz zurück, in dem in der ersten Spalte steht, wieviele Datensätze in der Tabelle Mitarbeiter sind. (http://www.sqlite.org/lang_expr.html)

Gruß,
Stefan
0

#6 Mitglied ist offline   lord_fritte 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.216
  • Beigetreten: 15. April 05
  • Reputation: 0

geschrieben 05. Oktober 2007 - 16:33

achso danke, naja unter PHP gibt es doch auch num_rows()
0

#7 Mitglied ist offline   Diewie 

  • Gruppe: aktive Mitglieder
  • Beiträge: 409
  • Beigetreten: 18. Juni 06
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Geisenhausen / München

geschrieben 05. Oktober 2007 - 17:23

Beitrag anzeigenZitat (lord_fritte: 05.10.2007, 17:33)

achso danke, naja unter PHP gibt es doch auch num_rows()


Hi,

ja die Buffern das Anfrageergebnis, also führen praktisch erst alle sqlite3_step() aus und zählen halt dabei mit. Danach bekommt man die Daten aus den Buffer. Wenn man sqlite in php ungebuffert nutzt, funktioniert das auch nicht (siehe sqlite_num_rows()).

Gruß,
Stefan
0

#8 Mitglied ist offline   lord_fritte 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.216
  • Beigetreten: 15. April 05
  • Reputation: 0

geschrieben 06. Oktober 2007 - 15:45

Ich habe jetzt ein Problem:
sqlite3_prepare_v2(db, "SELECT COUNT(*) FROM Mitarbeiter", -1, &stmt2, 0);
printf("Datensaetze: %d\n", sqlite3_column_text(stmt2, 0));


Ausgabe in der Console: Datensaetze: 0

Ausabe vom Compiler:
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:: In function `int main()':
E:\Daten\Dokumente\.Dokumente\Projekte\CodeBlocks\sqlite2\main.cpp:30: warning: int format, pointer arg (arg 2)
:: === Build finished: 0 errors, 1 warnings ===


Wenn ich das Format elemen im printf in %s änsere bekomme ich : Datensaetze: <null>

Dieser Beitrag wurde von lord_fritte bearbeitet: 06. Oktober 2007 - 16:22

0

#9 Mitglied ist offline   Diewie 

  • Gruppe: aktive Mitglieder
  • Beiträge: 409
  • Beigetreten: 18. Juni 06
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Geisenhausen / München

geschrieben 06. Oktober 2007 - 17:41

Hi,

auch wenn nur ein Datensatz zurückgegeben wird, so musst du auch zu dem springen, d.h. sqlite3_step einmal aufrufen. Neben sqlite3_column_text() gibt es auch sqlite3_column_int() (http://www.sqlite.or...te3_column_blob)

So müsste es in etwa aussehen, damit das richtige Ergebnis rauskommt.
sqlite3_stmt *stmt2;		//Statement Zeiger

if ((SQLITE_OK == sqlite3_prepare_v2(db, "SELECT COUNT(*) FROM Mitarbeiter", -1, &stmt2, 0)) && (SQLITE_ROW == sqlite3_step(stmt2))) {
	printf("Datensaetze: %d\n", sqlite3_column_int(stmt2, 0));
}

sqlite3_finalize(stmt2);


Gruß,
Stefan
0

#10 Mitglied ist offline   lord_fritte 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.216
  • Beigetreten: 15. April 05
  • Reputation: 0

geschrieben 06. Oktober 2007 - 19:30

Ja oke jetzt habs ich es verstanden, danke.
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0