AIR: Lokale SQL-Datenbank verwenden

Im neunten Teil zu Adobe AIR 1.0 geht es um das Thema SQL. AIR bietet die Möglichkeit, mit lokalen SQL-Datenbanken zu arbeiten. Die AIR-Runtime hat eine SQL-Engine, die auf der Open Source Technologie SQLite basiert.

In der lokalen Datenbank können z.B. Programmdaten, Benutzereinstellungen, Dokumente oder andere Arten von Daten gespeichert werden. Die SQL-Datenbank ist nichts anderes als eine Datei auf der Festplatte, in der die Daten abgelegt werden. Sie kann über ActionScript erstellt, befüllt und ausgelesen werden. Als Syntax werden dazu gewöhnliche SQL-Statements verwendet.

Adobe AIR SQL

Das folgende AIR-Beispiel erstellt zuerst eine neue Datenbank (Der Einfachheit wegen wird diese auf dem Desktop gespeichert). Anschließend wird ein erster Eintrag in die Datenbank-Tabelle geschrieben. Über die Benutzeroberfläche kann man weitere Einträge hinzufügen und die vorhanden anzeigen lassen.

[as]
import flash.events.*;
import flash.filesystem.File;
import flash.data.*;

/*
* :::::::::::: Neue Datenbank erstellen bzw. öffnen, falls vorhanden :::::::::::::::::::::
*/

// neue SQL Verbindung
var conn:SQLConnection = new SQLConnection();

// event listeners
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);

// Wo wird SQL-Datenbank abgespeichert (->Desktop)
var dbFile:File = File.desktopDirectory.resolvePath(„DBSample.db“);

// DB/Datei öffnen; wenn nicht vorhanden, neue Datei
// (Default ist immer SQLMode.CREATE, könnte also auch weggelassen werden)
conn.openAsync(dbFile, SQLMode.CREATE);

function openHandler(event:SQLEvent):void {
trace(„Datenbank erfolgreich erstellt“);
}

function errorHandler(event:SQLErrorEvent):void {
trace(„Fehler:“, event.error.message);
trace(„Details:“, event.error.details);
}

/*
* :::::::::::: Tabelle anlegen, falls sie nicht existiert :::::::::::::::::::::
*/

// neues Statement
var createStatement:SQLStatement = new SQLStatement();

// Statement mit der Datenbank-Verbindung verknüpfen
createStatement.sqlConnection = conn;

// Inhalt des SQL-Statements
var sql:String =
„CREATE TABLE IF NOT EXISTS personen (“ +
“ id INTEGER PRIMARY KEY AUTOINCREMENT, “ +
“ vorname TEXT, “ +
“ nachname TEXT “ +
„)“;
createStatement.text = sql;

// event listeners
createStatement.addEventListener(SQLEvent.RESULT, createResult);
createStatement.addEventListener(SQLErrorEvent.ERROR, createError);

// Statement ausführen
createStatement.execute();

function createResult(event:SQLEvent):void {
trace(„Tabelle erstellt“);
}

function createError(event:SQLErrorEvent):void {
trace(„Fehler:“, event.error.message);
trace(„Details:“, event.error.details);
}

/*
* :::::::::::: Initialer Eintrag :::::::::::::::::::::
*/

// Ersten Eintrag in die DB schreiben
writeIntoDatabase(„Max Mustermann“);

/*
* :::::::::::: Daten nach Buttonklick einfüllen :::::::::::::::::::::
*/

function writeIntoDatabase(str:String):void {

// create the SQL statement
var insertStatement:SQLStatement = new SQLStatement();
insertStatement.sqlConnection = conn;

// define the SQL text
var insertSql:String =
„INSERT INTO personen (vorname) “ +
„VALUES (‚“ + str + „‚)“;
insertStatement.text = insertSql;

// event listener
insertStatement.addEventListener(SQLEvent.RESULT, insertResult);
insertStatement.addEventListener(SQLErrorEvent.ERROR, insertError);

// statement ausführen
insertStatement.execute();
}

function insertResult(event:SQLEvent):void {
trace(„INSERT statement succeeded“);
myTextArea.text = „Eintrag erfolgreich hinzugefügt.“;
}

function insertError(event:SQLErrorEvent):void
{
myTextArea.text = „Fehler: “ + event.error.message;
myTextArea.text += „\nDetails: “ + event.error.details;
}

mySubmitButton.addEventListener(MouseEvent.CLICK, mySubmitButton_CLICK);

function mySubmitButton_CLICK(e:MouseEvent):void {
writeIntoDatabase(myTextInput.text);
}

/* ::::::::::::::: Werte auslesen :::::::::::
*
*/

myReadButton.addEventListener(MouseEvent.CLICK, myReadButton_CLICK);

var selectStmt:SQLStatement

function myReadButton_CLICK(e:MouseEvent):void {

// neues select statement
selectStmt = new SQLStatement();

// dem statement die verbindung zuweisen
selectStmt.sqlConnection = conn;

// statement festlegen
selectStmt.text = „SELECT vorname FROM personen“;

// event listeners
selectStmt.addEventListener(SQLEvent.RESULT, resultHandler);
selectStmt.addEventListener(SQLErrorEvent.ERROR, errorHandler);

// statement ausführen
selectStmt.execute();

}

function resultHandler(event:SQLEvent):void {

// ergebnis ablegen
var result:SQLResult = selectStmt.getResult();

// anzahl der einträge
var numResults:int = result.data.length;

// Textfeld leeren
myTextArea.text = „“;

// schleife
for (var i:int = 0; i < numResults; i++) { var n:Object = result.data[i]; myTextArea.text += n.vorname + "\n"; } } [/as]

Link: Working with local SQL databases
Quelldatei (.fla)

[ad]

15 Gedanken zu „AIR: Lokale SQL-Datenbank verwenden“

  1. Hi Flo,

    vielen Dank für den Hinweis auf meinen Artikel und für dein Feedback in meinem Blog. Ich verfolge deine Tutorials mit sehr viel Aufmerksamkeit und finde sie sehr übersichtlich und leicht nachzuvollziehen.

    Kommst du zur FlashForum Konferenz dieses Jahr?

    Grüße Christian

  2. Zu meiner Schande muss ich gestehen, dass ich nicht weiß, was ich mit dieser FLA-Datei tun muss. Ich entwickle AIR-Anwendungen bisher immer mit dem Flex Builder, deshalb stehe ich jetzt etwas wie der Ochs‘ vorm Tor.

    Ich versuche gerade, etwas über lokale Datenbankzugriffe mit AIR in Erfahrung zu bringen, daher wollte ich dieses Code-Beispiel mal ausführen. Ich lade die FLA-Datei dazu in die Adobe-Flash-CS3-Entwicklungsumgebung, veröffentliche das Ganze mit F12, und erhalte leider nur diese Fehlermeldung:

    Error: Error #3104: A SQLConnection must be open to perform this operation.
    at Error$/throwError()
    at flash.data::SQLStatement/checkAllowed()
    at flash.data::SQLStatement/checkReady()
    at flash.data::SQLStatement/execute()
    at air_fla::MainTimeline/frame1()

    Jemand eine Idee, an welcher Stelle da was anders gemacht werden muss?

    Vielen Dank für jedwede Hilfe.

  3. Hallo Christian,
    die .fla Datei ist nur für Flash. In Flex kannst du nix damit anfangen :)

    Du kannst gewöhnlicherweise (bis auf wenige Ausnahmen) aber den AS3-Code von Flash auch in Flex verwenden. Die Benutzeroberfläche müsstest du natürlich nachbauen und die Elemente mit den entsprechenden Instanznamen versehen.

    Zu deinem Flashproblem kann ich aktuell leider nichts sagen. Normalerweise sollte es funktionieren, wenn du die .fla öffnest und Ctrl+Enter drückst. (Voraussetzung ist, dass die AIR-Erweiterung für Flash CS3 installiert ist.)

    Vielleicht hat sich auch mit AIR 1.1 was geändert, glaube ich aber nicht. Dies kann ich gerade leider nicht nachprüfen, da ich unterwegs bin …

  4. Hallo.

    Vielen Dank für die Antwort.

    Die Flash-Entwicklungsumgebung, die mir zur Verfügung steht, hat die AIR-Erweiterungen – trotzdem geht’s nicht (bzw. nur mit o.g. Fehler).

    Ist aber nicht so schlimm; mittlerweile habe ich in Flex meinen eigenen asynchronen Zugriff auf die in AIR integrierte, lokale SQLite-Datenbank realisiert.

    Aber falls mal Zeit ist, dem Fehler auf den Grund zu gehen, würde ich mich natürlich für das Ergebnis interessieren (bzw. bei mehr Zeit auch selbst forschen).

  5. Hallo! Es scheint zu funktionieren, wenn man die DB schon erstellt hat. Jedoch funktioniert es bei mir nur unter XP und nicht unter Vista. Weiß jemand etwas darüber?

  6. habs rausgefunden…. ist eine Vista-Zugriffeinstellungssache (Benutzerkontensteuerung muss ausgeschaltet sein).

  7. Also ich habe die Benutzerkontensteuerung ausgeschaltet, aber ich bekomme den selben Fehler…

    Die Datei wird dann zwar angelegt, aber Sie bleibt leer

  8. Hier ein kurzer Hinweis, wie man mehrere Werte per INSERT eintragen kann:

    sqlStatement.text = "INSERT INTO setlists (setId,songId) VALUES ('"
    + setId + "','"
    + songId + "')";

  9. Beim Löschen findet man so heraus, ob etwas gelöscht wurde:

    var result:SQLResult = SQLStatement(event.currentTarget).getResult();

    if (result.rowsAffected > 0) { //… es wurde Zeilen gelöscht

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert