web-dev-qa-db-fra.com

Exécution de plusieurs instructions avec SQLiteDatabase.execSQL

J'ai suivi un tutoriel standard pour créer une base de données avec Android. J'ai créé une classe appelée DbHelper qui étend SQLiteOpenHelper. J'ai remplacé le gestionnaire de création pour exécuter une chaîne.

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

DbDefinitions.DB_CREATE est une chaîne statique que j'ai créée.

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 + "');";

J'aimerais utiliser 1 String pour exécuter plusieurs instructions SQL. Comment puis-je faire cela car SQLiteDatabase.execSQL n'autorise qu'une seule instruction?

35
Andrew

Ce n'est pas possible d'utiliser les méthodes standard fournies avec Android. Donc, si vous voulez exécuter batch de plusieurs instructions SQL, vous devrez créer votre propre utilitaire pour le faire. Par exemple, vous pouvez avoir quelque chose comme ça:

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

Bien que, ce que je ferais est quelque chose comme ceci:

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

Eh bien, dans mon cas, je suis en train d'exécuter des requêtes à partir d'un fichier que j'ai sauvegardé en tant qu'actif C'est la solution que j'ai utilisée + -

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) {
    .....

MODIFIER

Dans mon cas, les requêtes étaient de simples requêtes d'insertion sur lesquelles j'avais un contrôle total. Cependant, le problème a été soulevé concernant les requêtes avec ";" à l'intérieur d'eux.

@TWiStErRob suggère d'utiliser 

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

ou

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

Essayez quelque chose comme ça:

    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");

nous avons beaucoup de réponses géniales ici . et voici ma solution pour plusieurs instructions d’insertion, mais j’ai utilisé un fichier dans des éléments non alignés, chaque ligne de ce fichier est une instruction d’insertion.

    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

D'après la documentation de SQLiteDatabase et mon expérience dans le passé, je pense que ce n'est pas possible. Mais pourquoi ne le divisez-vous pas en une seule déclaration? Ce n'est vraiment pas un problème dans votre exemple. Ou en avez-vous besoin pour un cas d'utilisation différent?

0
mreichelt