C++ C++ Felder in SQLite-DB speichern und auslesen

T_55

Lieutenant
Registriert
Feb. 2013
Beiträge
638
Hallo,

ein zweidimensionales Feld soll in eine Datenbank gelegt werden und bei Bedarf wieder in das Programm gespielt werden. Das Grundgerüst zum Tabelle anlegen hat schon geklappt allerdings bin ich nicht sicher wie es am besten ist bei mehrdimensionalen Feldern gemacht wird. Ich denke eine verschachtelte Schleife könnte gut sein allerdings dazu meine Frage, die Reihenfolge der Aktionen sieht zur Zeit in etwa so aus,

DROP TABLE IF EXISTS
CREATE TABLE
INSERT INTO
VALUES
sqlite_exec

was müsste man in die Schleifen packen und was davor bzw danach?

Code:
int main()
{
    int feld[5][100] = {0}; // feld soll in db geschrieben werden

    sqlite3 *db;
    char *err_msg = 0;
    int rc = sqlite3_open("datenbank.db", &db);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return 1;
    }
    char *sql = "DROP TABLE IF EXISTS Tabelle_Nr;"
    "CREATE TABLE Tabelle_Nr(Id INTEGER PRIMARY KEY, Dim1 REAL, Dim2 REAL);"
    //test mit zwei zeilen soll dann aber durch zweidimensionale array ersetzt werden
    "INSERT INTO Tabelle_Nr(Id, Dim1, Dim2) VALUES (1, 2.34567, 8.88888), (2, 675.964, 0.00032);";
    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);

    if (rc != SQLITE_OK )
    {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);
        return 1;
    }
    sqlite3_close(db);
    return 0;
}

Grüße
 
Könnte es sein, dass du ein Verständnisproblem bei deinem 2D-Feld hast?
Es sind einfach nur 5 x 100 Werte. Für mich sieht dein SQL-Befehl so aus, als ob du davon ausgehst, dass es 5X-Werte und jeweils 100Y-Werte sind (wegen Dim1 und Dim2).

Du kannst also nicht die erste Dimension, ohne Angabe der zweiten abfragen.
Entferne einfach Dim2 aus deiner Tabelle und trage alle Werte nach und nach ein:
Code:
bool executeSQL(char *sql)
{
	char *err_msg = 0;
	if (sqlite3_exec(db, sql, 0, 0, &err_msg) != SQLITE_OK)
	{
		fprintf(stderr, "SQL error: %s\n", err_msg);
		sqlite3_free(err_msg);
		return false;
	}
	
	return true;
}

int main()
{
	int feld[5][100] = {0}; // feld soll in db geschrieben werden
	char *err_msg = 0;
	
	if (sqlite3_open("datenbank.db", &db) != SQLITE_OK)
	{
		fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
		sqlite3_close(db);
		sqlite3_free(err_msg);
		return 1;
	}
	
	if (!executeSQL("DROP TABLE IF EXISTS Tabelle_Nr;"))
	{
		// Fehler
	}

	if (!executeSQL("CREATE TABLE Tabelle_Nr(Id INTEGER PRIMARY KEY, Dim1 REAL);"))
	{
		// Fehler
	}
	
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 100; j++) {
			if (!executeSQL("INSERT INTO Tabelle_Nr(Id, Dim1) VALUES (i * 100 + j, feld[i][j]);"))
			{
				// Fehler
			}
		}
	}

	sqlite3_close(db);
	return 0;
}

In der Schleife müssen die Werte natürlich noch in int umgewandelt werden, habe das jetzt zwecks Übersichtlichkeit mal weg gelassen.
 
Zuletzt bearbeitet:
Besten Dank für den Code. Diese Variante mit nur einer Spalte ist natürlich platzsparend im Vergleich zu dem was ich erst vor hatte und execute in der Funktion kannte ich auch noch nicht. Super Sache ich werde das mal versuchen einzubauen. Bei Datenbanken ist bei mir der Knoten noch nicht ganz geplatzt aber es wird :) Wenn es alles klappt versuche ich den umgekehrten Weg, das Einspielen der Daten von DB zu Programm.

Mit den mehreren Spalten Dim1 Dim2 war nur die Überlegung, den ersten beiden Spalten die Dimension zu geben und einer dritten dann der entsprechenden Wert um sozusagen in einer Zeile Wert und Index zu speichern. Falls man mal aus irgendwelchen Gründen (zb wegen anderer Datenstruktur) nicht alle Felder speichern will würde beim zurückkopieren, von der DB zum Programm, der Index die Werte identifizierbar machen und so helfen die sie wieder richtig ins Programm zu bekommen. Natürlich hat man dann immer zu jedem Wert gleich zwei int-Werte dazu.

Gruß
 
Zurück
Oben