it-swarm.com.de

Mehrere Anweisungen mit SQLiteDatabase.execSQL ausführen

Ich habe ein Standard-Tutorial zum Aufbau einer Datenbank mit Android verfolgt. Ich habe eine Klasse namens DbHelper erstellt, die SQLiteOpenHelper erweitert. Ich habe den Erstellungshandler überschrieben, um einen String auszuführen.

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(DbDefinitions.DB_CREATE);
}

DbDefinitions.DB_CREATE ist ein statischer String, den ich erstellt habe.

public static final String TABLE_MESSAGES = "messages";
public static final String TABLE_FRIENDS = "friends";

public static final String STATE_OK = "STATE_OK";

public static final String DB_CREATE = 
    "create table " + TABLE_MESSAGES + " (_id integer primary key, user_id integer not null, created_on integer, subject text not null, summary text not null, messagetext text null, read integer not null, status text not null default '" + STATE_OK + "'); " +
    "create table " + TABLE_FRIENDS + " (_id integer primary key, user_id integer not null, friend_id integer not null, created_on integer, status text not null default '" + STATE_OK + "');";

Ich möchte 1 String verwenden, um mehrere SQL-Anweisungen auszuführen. Wie kann ich dies tun, da SQLiteDatabase.execSQL nur eine Anweisung zulässt?

35
Andrew

Dies ist mit den Standardmethoden von Android nicht möglich. Wenn Sie also batch von mehreren SQL-Anweisungen ausführen möchten, müssen Sie dazu ein eigenes Dienstprogramm erstellen. Zum Beispiel können Sie so etwas haben:

public void executeBatchSql(String sql){
    // use something like StringTokenizer to separate sql statements
    for each sql statement{
        database.execSQL(oneStatement);
    }
}

Was ich tun würde, ist so etwas:

String sql1 = "create bla bla bla;";
String sql2 = "create foo bar;";
String[] statements = new String[]{sql1, sql2};

// then
for(String sql : statements){
    database.execSQL(sql);
}
40
Cristian

In meinem Fall entschuldige ich mich mit Abfragen aus einer Datei, die ich als Asset gespeichert habe. Dies ist die von mir verwendete Lösung + -

String script = readAsset(CREATE_SCRIPT);//readAsset is a method i use to get the file contents
try {
     String[] queries = script.split(";");
 for(String query : queries){
        db.execSQL(query);
     }
 } catch (Exception e) {
    .....

EDIT

In meinem Fall waren die Abfragen einfache Einfügeabfragen, über die ich volle Kontrolle hatte. Es wurde jedoch das Problem bezüglich Abfragen mit ";" In ihnen.

@TWiStErRob schlägt die Verwendung von vor 

script.split(";$");// $ meaning end of line. You will need to use RegexOption.MULTILINE for this to work

oder

script.split(";\n");// but you will need to ensure that each query is on a different line
19
frostymarvelous

Versuchen Sie etwas so:

    try {
        InputStream is = this.context.getAssets().open("script.sql");
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String line;
        while ((line = reader.readLine()) != null) {
            Log.i("SQL Script", line);
            if (!line.isEmpty() && !line.trim().startsWith("--"))
                db.execSQL(line);
        }
    } catch (IOException e) {
        Log.e("SQL Script", e.getMessage());
    }
    Log.i("SQL Script", "script executed");

wir haben hier viele großartige Antworten ... und hier ist meine Lösung für mehrere Einfügeanweisungen, jedoch habe ich eine Datei in Assets verwendet, die nicht in einer Zeile liegen. Jede Zeile in dieser Datei ist eine Einfügeanweisung.

    try {
        in = getAssets().open("InsertStatemets.SQL");
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        line = reader.readLine();

        while (line != null){
            db.execSQL(line);
            Log.e("Insert Statement",  line); 
        }

    } catch (Exception e) {

    }
0
Eng. Samer T

Aus der Dokumentation von SQLiteDatabase und meinen Erfahrungen in der Vergangenheit denke ich, dass dies nicht möglich ist. Aber warum teilen Sie es nicht einfach in einzelne Aussagen auf? In Ihrem Beispiel ist das wirklich kein Problem. Oder benötigen Sie es für einen anderen Anwendungsfall?

0
mreichelt