Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe C++ Anwendungskurs Tag 4: Datenbanken Daniela Horn Institut für Neuroinformatik Real-time Computer Vision 23. März 2017 C++ Anwendungskurs 23. März 2017 | Daniela Horn 1 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Übersicht 1 Motivation 2 Relationale Datenbanken 3 SQL-Befehle 4 SQLite 5 Aufgabe C++ Anwendungskurs 23. März 2017 | Daniela Horn 2 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Übersicht 1 Motivation 2 Relationale Datenbanken 3 SQL-Befehle 4 SQLite 5 Aufgabe C++ Anwendungskurs 23. März 2017 | Daniela Horn 3 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Motivierendes Beispiel Programm A Datei A C++ Anwendungskurs 23. März 2017 | Daniela Horn 4 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Motivierendes Beispiel Programm A' Datei A' C++ Anwendungskurs 23. März 2017 | Daniela Horn 5 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Motivierendes Beispiel Programm A Programm B Datei A C++ Anwendungskurs 23. März 2017 | Daniela Horn 6 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Motivierendes Beispiel Programm A' Programm B Datei A' C++ Anwendungskurs 23. März 2017 | Daniela Horn 7 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Motivierendes Beispiel Programm A' Programm B Datei A' C++ Anwendungskurs 23. März 2017 | Daniela Horn 8 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Lösungsansätze Dateiversionsnummer verwalten (Minimum!) C++ Anwendungskurs 23. März 2017 | Daniela Horn 9 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Lösungsansätze Dateiversionsnummer verwalten (Minimum!) Semantik abspeichern C++ Anwendungskurs 23. März 2017 | Daniela Horn 9 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Lösungsansätze Dateiversionsnummer verwalten (Minimum!) Semantik abspeichern Datei enthält Informationen über ihren Inhalt C++ Anwendungskurs 23. März 2017 | Daniela Horn 9 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Lösungsansätze Dateiversionsnummer verwalten (Minimum!) Semantik abspeichern Datei enthält Informationen über ihren Inhalt XML / JSON C++ Anwendungskurs 23. März 2017 | Daniela Horn 9 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Lösungsansätze Dateiversionsnummer verwalten (Minimum!) Semantik abspeichern Datei enthält Informationen über ihren Inhalt XML / JSON XML in Qt C++ Anwendungskurs 23. März 2017 | Daniela Horn 9 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Lösungsansätze Dateiversionsnummer verwalten (Minimum!) Semantik abspeichern Datei enthält Informationen über ihren Inhalt XML / JSON XML in Qt Heute: Datenbanken C++ Anwendungskurs 23. März 2017 | Daniela Horn 9 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Übersicht 1 Motivation 2 Relationale Datenbanken 3 SQL-Befehle 4 SQLite 5 Aufgabe C++ Anwendungskurs 23. März 2017 | Daniela Horn 10 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe (Relationale) Datenbanken (Relationale) Datenbanken Speichern Semantik und Relationen zwischen Datenelementen Relation entspricht Tabelle Semantik entspricht Spaltenbenennung und Verknüpfung der Tabellen C++ Anwendungskurs 23. März 2017 | Daniela Horn 11 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe (Relationale) Datenbanken (Relationale) Datenbanken Speichern Semantik und Relationen zwischen Datenelementen Relation entspricht Tabelle Semantik entspricht Spaltenbenennung und Verknüpfung der Tabellen Transaktionskontrolle C++ Anwendungskurs 23. März 2017 | Daniela Horn 11 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe (Relationale) Datenbanken (Relationale) Datenbanken Speichern Semantik und Relationen zwischen Datenelementen Relation entspricht Tabelle Semantik entspricht Spaltenbenennung und Verknüpfung der Tabellen Transaktionskontrolle Benutzerverwaltung C++ Anwendungskurs 23. März 2017 | Daniela Horn 11 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe (Relationale) Datenbanken (Relationale) Datenbanken Speichern Semantik und Relationen zwischen Datenelementen Relation entspricht Tabelle Semantik entspricht Spaltenbenennung und Verknüpfung der Tabellen Transaktionskontrolle Benutzerverwaltung Konsistenzprüfung C++ Anwendungskurs 23. März 2017 | Daniela Horn 11 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe (Relationale) Datenbanken (Relationale) Datenbanken Speichern Semantik und Relationen zwischen Datenelementen Relation entspricht Tabelle Semantik entspricht Spaltenbenennung und Verknüpfung der Tabellen Transaktionskontrolle Benutzerverwaltung Konsistenzprüfung Sichtprüfung C++ Anwendungskurs 23. März 2017 | Daniela Horn 11 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe (Relationale) Datenbanken (Relationale) Datenbanken Speichern Semantik und Relationen zwischen Datenelementen Relation entspricht Tabelle Semantik entspricht Spaltenbenennung und Verknüpfung der Tabellen Transaktionskontrolle Benutzerverwaltung Konsistenzprüfung Sichtprüfung Zugriffskontrolle C++ Anwendungskurs 23. März 2017 | Daniela Horn 11 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe (Relationale) Datenbanken (Relationale) Datenbanken Speichern Semantik und Relationen zwischen Datenelementen Relation entspricht Tabelle Semantik entspricht Spaltenbenennung und Verknüpfung der Tabellen Transaktionskontrolle Benutzerverwaltung Konsistenzprüfung Sichtprüfung Zugriffskontrolle Optimierung von Zugriffen C++ Anwendungskurs 23. März 2017 | Daniela Horn 11 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe (Relationale) Datenbanken (Relationale) Datenbanken Speichern Semantik und Relationen zwischen Datenelementen Relation entspricht Tabelle Semantik entspricht Spaltenbenennung und Verknüpfung der Tabellen Transaktionskontrolle Benutzerverwaltung Konsistenzprüfung Sichtprüfung Zugriffskontrolle Optimierung von Zugriffen (Berechnung von Zwischenergebnissen) C++ Anwendungskurs 23. März 2017 | Daniela Horn 11 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Motivierendes Beispiel Programm A Programm B Datenbankmanagementsystem Tabelle A C++ Anwendungskurs Tabelle B 23. März 2017 | Daniela Horn 12 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Inhalt (Relationale) Datenbanken Crash-Course SQL C++ Anwendungskurs 23. März 2017 | Daniela Horn 13 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Inhalt (Relationale) Datenbanken Crash-Course SQL SELECT FROM, Joins C++ Anwendungskurs 23. März 2017 | Daniela Horn 13 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Inhalt (Relationale) Datenbanken Crash-Course SQL SELECT FROM, Joins CREATE TABLE, DROP TABLE C++ Anwendungskurs 23. März 2017 | Daniela Horn 13 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Inhalt (Relationale) Datenbanken Crash-Course SQL SELECT FROM, Joins CREATE TABLE, DROP TABLE UPDATE, INSERT, DELETE C++ Anwendungskurs 23. März 2017 | Daniela Horn 13 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Inhalt (Relationale) Datenbanken Crash-Course SQL SELECT FROM, Joins CREATE TABLE, DROP TABLE UPDATE, INSERT, DELETE SQLite C++ Anwendungskurs 23. März 2017 | Daniela Horn 13 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Inhalt (Relationale) Datenbanken Crash-Course SQL SELECT FROM, Joins CREATE TABLE, DROP TABLE UPDATE, INSERT, DELETE SQLite Was ist das? C++ Anwendungskurs 23. März 2017 | Daniela Horn 13 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Inhalt (Relationale) Datenbanken Crash-Course SQL SELECT FROM, Joins CREATE TABLE, DROP TABLE UPDATE, INSERT, DELETE SQLite Was ist das? Verwendung mit Qt C++ Anwendungskurs 23. März 2017 | Daniela Horn 13 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Übersicht 1 Motivation 2 Relationale Datenbanken 3 SQL-Befehle 4 SQLite 5 Aufgabe C++ Anwendungskurs 23. März 2017 | Daniela Horn 14 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe CREATE TABLE 1 CREATE TABLE countries ( 2 name 3 population 4 area 5 ); varchar(80), int, real -- Name des Landes -- Bevoelkerung -- Flaeche in Quadratkilometer Datentypen: varchar(len) int real name countries population area date point ... C++ Anwendungskurs 23. März 2017 | Daniela Horn 15 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe CREATE TABLE IF NOT EXISTS 1 CREATE TABLE IF NOT EXISTS countries ( 2 name varchar(80), 3 population int, 4 area real 5 ); -- tja, gibts aber schon Datentypen: varchar(len) int real name countries population area date point ... C++ Anwendungskurs 23. März 2017 | Daniela Horn 16 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe INSERT INTO 1 INSERT INTO countries (name, population, area) 2 VALUES (’Belize’, 327719, 22966.0); 3 INSERT INTO countries (name, population, area) 4 VALUES (’Palau’, 20750, 459.0); 5 INSERT INTO countries (name, population, area) 6 VALUES (’Osttimor’, 1120392, 14954.44); Datentypen: varchar(len): ’Hallo’ int: -123 real: -123.4e-5 date: ’2015-02-05’ point: ’(12.3, 45.6)’ name countries population area Belize Palau Osttimor 327.719 20.750 1.120.392 22.966,0 459,0 14.954,44 ... C++ Anwendungskurs 23. März 2017 | Daniela Horn 17 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SELECT FROM 1 SELECT name, population, area FROM countries WHERE population > 1000000; SELECT * um alle Spalten auszuwählen (schlechter Stil) C++ Anwendungskurs name countries population area Belize Palau Osttimor 327.719 20.750 1.120.392 22.966,0 459,0 14.954,44 23. März 2017 | Daniela Horn 18 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SELECT mit Operationen 1 SELECT name, population / area FROM countries 2 WHERE population / area > 40; SELECT * um alle Spalten auszuwählen (schlechter Stil als Code) name countries population area Belize Palau Osttimor 327.719 20.750 1.120.392 22.966,0 459,0 14.954,44 SELECT DISTINCT um doppelte Zeilen aus der Antwort zu löschen C++ Anwendungskurs name Antwort population / area_m2 Palau Osttimor 45,20697 74,92256 23. März 2017 | Daniela Horn 19 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SELECT mit ORDER BY 1 SELECT name FROM countries ORDER BY population; SELECT * um alle Spalten auszuwählen (schlechter Stil als Code) SELECT DISTINCT um doppelte Zeilen aus der Antwort zu löschen C++ Anwendungskurs Antwort name Palau Belize Osttimor 23. März 2017 | Daniela Horn 20 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SELECT mit Join 1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE TABLE capitals ( name varchar(80), country varchar(80), population int ); INSERT INTO capitals (name, country, population) VALUES (’Melekeok’, ’Palau’, 391),(’Dili’, ’Osttimor’, 234331), (’Naypyidaw’, ’Myanmar’, 925000); SELECT countries.name AS Land, capitals.population AS CapPop FROM countries, capitals WHERE countries.name = capitals.country AND capitals.population / countries.population >= 0.1; name capitals country population Melekeok Dili Naypyidaw Palau Osttimor Myanmar 391 234.331 925.000 C++ Anwendungskurs Antwort Land CapPop Osttimor 23. März 2017 | Daniela Horn 234.331 21 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SELECT mit anderen Joins 1 2 3 4 5 6 7 8 9 10 11 SELECT * FROM countries INNER JOIN capitals ON (countries.name = capitals.name) WHERE capitals.population / countries.population >= 0.1; SELECT * FROM countries LEFT OUTER JOIN capitals ON (countries.name = capitals.name) WHERE capitals.population / countries.population >= 0.1; SELECT * FROM countries RIGHT OUTER JOIN capitals ON (countries.name = capitals.name) WHERE capitals.population / countries.population >= 0.1; SELECT * FROM countries FULL OUTER JOIN capitals ON (countries.name = capitals.name) WHERE capitals.population / countries.population >= 0.1; C++ Anwendungskurs 23. März 2017 | Daniela Horn 22 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe UPDATE 1 UPDATE countries 2 SET population = population + 1 3 WHERE name = ’Belize’; name countries population area Belize Palau Osttimor 327.720 20.750 1.120.392 22.966,0 459,0 14.954,44 C++ Anwendungskurs 23. März 2017 | Daniela Horn 23 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe DELETE FROM 1 DELETE FROM countries WHERE population < 100000; name countries population area Belize Osttimor 327.720 1.120.392 22.966,0 14.954,44 C++ Anwendungskurs 23. März 2017 | Daniela Horn 24 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe DROP COLUMN / TABLE 1 DROP COLUMN area FROM countries; 2 3 DROP TABLE countries; countries name population Belize Osttimor C++ Anwendungskurs 327.720 1.120.392 23. März 2017 | Daniela Horn 25 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe VIEW 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CREATE TABLE countries ( name population area ); varchar(80), int, real -- country’s name -- its population -- its land area in square km INSERT INTO countries (name, bevoelkerung, area) VALUES (’Belize’, 327719, 22966.0), (’Palau’, 20750, 459.0), (’Osttimor’, 1120392, 14954.44); ALTER TABLE countries RENAME COLUMN ’population’ AS ’bevoelkerung’; CREATE VIEW myCountries AS SELECT name, bevoelkerung AS population, area FROM countries; name countries bevoelkerung area Belize Palau Osttimor 327.719 20.750 1.120.392 22.966,0 459,0 14.954,44 C++ Anwendungskurs 23. März 2017 | Daniela Horn 26 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Update VIEW 1 CREATE VIEW myCountries AS 2 SELECT name, bevoelkerung AS population, area 3 FROM countries; 4 5 SELECT * FROM myCountries; verhält sich wie eine Tabelle (für SELECT) kann ggf. Programmänderungen bei Datenbankänderungen vermeiden UPDATE und INSERT INTO sind unter Einschränkungen möglich aber in SQLite nicht implementiert C++ Anwendungskurs 23. März 2017 | Daniela Horn 27 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Constraints 1 CREATE TABLE countries ( 2 Id INTEGER PRIMARY KEY, -- Primaerschluessel, muss eindeutig und != null sein 3 -- Default wird gesetzt 4 Name VARCHAR(100) NOT NULL UNIQUE, -- eindeutig und nicht null 5 Population INTEGER DEFAULT 0, -- Defaultwert 6 PopCapital INTEGER DEFAULT 0, 7 CHECK (PopCapital <= Population) -- Konsistenzpruefung 8 ); kann (zum Teil) verhindern, dass die Daten in einen ungültigen Zustand geraten C++ Anwendungskurs 23. März 2017 | Daniela Horn 28 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Übersicht 1 Motivation 2 Relationale Datenbanken 3 SQL-Befehle 4 SQLite 5 Aufgabe C++ Anwendungskurs 23. März 2017 | Daniela Horn 29 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SQLite - Was ist das? „Datenbank für Arme“ Kommandozeilenprogramm, das Datenbank in eine Datei schreibt keine Transaktionskontrolle keine Benutzerverwaltung mittelmäßig performant C++ Anwendungskurs 23. März 2017 | Daniela Horn 30 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SQLite - Was ist das? „Datenbank für Arme“ Kommandozeilenprogramm, das Datenbank in eine Datei schreibt keine Transaktionskontrolle keine Benutzerverwaltung mittelmäßig performant Aber: ideal, um schnell was auszuprobieren von Vornherein in Qt 5.3 integriert C++ Anwendungskurs 23. März 2017 | Daniela Horn 30 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe CMake-Anbindung Folgende Variablen / Funktionen müssen gesetzt / ausgeführt werden: CMake FIND_PACKAGE(Qt5Sql) Sql zu QT5_USE_MODULES hinzufügen C++ Anwendungskurs 23. März 2017 | Daniela Horn 31 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SQLite in Qt - Header 1 2 3 4 5 #include <QtSql/QSqlDatabase> #include <QtSql/QSqlQuery> #include <QtSql/QSqlError> #include <QtSql/QSqlRecord> C++ Anwendungskurs // verwaltet die Verbindung zur Datenbank // stellt einen SQL-Befehl bzw. eine SQL-Abfrage dar // stellt einen SQL-Fehler dar //(Kommunikation mit Treiber) // stellt eine Zeile einer SQL-Abfrage dar 23. März 2017 | Daniela Horn 32 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SQLite in Qt - Verbindung mit der Datenbank 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <QtSql/QSqlDatabase> #include <QtSql/QSqlQuery> #include <QtSql/QSqlError> #include <QtSql/QSqlRecord> // verwaltet die Verbindung zur Datenbank // stellt einen SQL-Befehl bzw. eine SQL-Abfrage dar // stellt einen SQL-Fehler dar //(Kommunikation mit Treiber) // stellt eine Zeile einer SQL-Abfrage dar ... QSqlDatabase dataBase; dataBase = QSqlDatabase::addDatabase("QSQLITE"); dataBase.setHostName("localhost"); dataBase.setDatabaseName("d:/myDatabase.db"); bool ok = dataBase.open(); // hier kann mit der Datenbank gearbeitet werden dataBase.close(); Bei anderen Datenbankmanagementsystemen funktioniert es nahezu genauso. C++ Anwendungskurs 23. März 2017 | Daniela Horn 33 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SQLite in Qt - Absetzen einer Query 1 2 3 ... 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 QSqlDatabase database; QSqlQuery query("CREATE TABLE test(Id INTEGER PRIMARY KEY," "Name VARCHAR(100))", database); // wird sofort ausgefuehrt QSqlQuery delayedQuery(database); // wird spaeter ausgefuehrt delayedQuery.prepare("SELECT Name FROM test"); bool ok = delayedQuery.exec(); // ob Anfrage abgesetzt werden konnte if (!ok) { std::cout << delayedQuery.lastError().text().toStdString() << std::endl; } C++ Anwendungskurs 23. März 2017 | Daniela Horn 34 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SQLite in Qt - Iterieren eines SELECT-Resultats 1 2 3 ... 4 5 6 7 8 9 10 11 12 13 QSqlDatabase database; QSqlQuery query("SELECT Name FROM test", database); while (query.next()) { int colIdx = 0; std::cout << query.value(colIdx).toString() << std::endl; // oder auch std::cout << query.value(query.record().indexOf("Name")).toString() << std::endl; } C++ Anwendungskurs 23. März 2017 | Daniela Horn 35 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SQLite in Qt - bindValue() 1 2 3 ... 4 5 6 7 8 9 10 QSqlDatabase database; QString dataName; QSqlQuery insertQuery(database); // wird spaeter ausgefuehrt insertQuery.prepare("INSERT INTO table(Name) VALUES(:nameInsert)"); insertQuery.bindValue(":nameInsert", dataName); bool ok = insertQuery.exec(); // ob Anfrage abgesetzt werden konnte Zeichenketten nicht einfach in SQL-Statements einfügen! (SQL Injection) falls z.B. dataName = “Robert‘); DROP TABLE Students;“ ist, wird weiterer Code ausgeführt C++ Anwendungskurs 23. März 2017 | Daniela Horn 36 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe SQLite in Qt - bindValue() 1 2 3 4 ... 5 6 7 8 9 10 11 12 13 14 15 QSqlDatabase database; QString dataName; QString colName("Name"); QSqlQuery insertQuery(database); // wird spaeter ausgefuehrt insertQuery.prepare(QString( "INSERT INTO table(%1) VALUES(:nameInsert)").arg(colName) ); insertQuery.bindValue(":nameInsert", dataName); bool ok = insertQuery.exec(); // ob Anfrage abgesetzt werden konnte std::cout << insertQuery.executedQuery().toStdString() << std::endl; // zeigt ausgefuehrte Anweisung an SQL-Binding kann nur Werte ersetzen, andere Teile der SQL-Anweisung müssen über klassische Zeichenketten-Operationen eingefügt werden. C++ Anwendungskurs 23. März 2017 | Daniela Horn 37 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Übersicht 1 Motivation 2 Relationale Datenbanken 3 SQL-Befehle 4 SQLite 5 Aufgabe C++ Anwendungskurs 23. März 2017 | Daniela Horn 38 Motivation Relationale Datenbanken SQL-Befehle SQLite Aufgabe Aufgabe Ändern sie die Adressverwaltung aus der Aufgabe von Tag 3 und ersetzen Sie den Datenzugriff durch den Zugriff auf eine Datenbank. Implementieren Sie den Datenbankzugriff als einen Cache, bei dem initial die gesamten Daten eingelesen werden und der bei lesendem Zugriff die Daten aus dem Hauptspeicher bereitstellt. Bei schreibendem Zugriff sollen die Änderungen sowohl im Hauptspeicher als auch in der Datenbank vorgenommen werden. Sie können das Programm sqlite3.exe verwenden, um Queries in ihrer Datenbank abzusetzen. Sie können die benötigten Tabellen zunächst von Hand erstellen. Wenn der Rest funktioniert, lassen Sie die Tabellen vom Programm erstellen, wenn Sie noch nicht existieren. C++ Anwendungskurs 23. März 2017 | Daniela Horn 39