Подтвердить что ты не робот

Выполнение нескольких операторов с помощью SQLiteDatabase.execSQL

Я выполнил стандартный учебник по созданию базы данных с Android. Я создал класс под названием DbHelper, который расширяет SQLiteOpenHelper. Я переустановил обработчик create для выполнения строки.

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

DbDefinitions.DB_CREATE - статическая строка, которую я создал.

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

Я бы хотел использовать 1 String для выполнения нескольких операторов SQL. Как я могу это сделать, поскольку SQLiteDatabase.execSQL разрешает только 1 оператор?

4b9b3361

Ответ 1

Это невозможно сделать, используя стандартные методы, которые поставляются с Android. Итак, если вы хотите выполнить партию нескольких операторов SQL, вам придется создать свою собственную утилиту для этого. Например, вы можете иметь что-то вроде этого:

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

Хотя, я бы сделал что-то вроде этого:

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

Ответ 2

Ну, в моем случае, я вызываю запросы из файла, который я сохранил в качестве актива Это решение, которое я использовал + -

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

ИЗМЕНИТЬ

В моем случае запросы были простыми вставными запросами, над которыми я полностью контролировал. Тем не менее, вопрос был поднят по вопросам с ";" внутри них.

@TWiStErRob предлагает использовать

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

или

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

Ответ 3

Из документации SQLiteDatabase и моего опыта в прошлом я считаю, что это невозможно. Но почему бы вам просто не разделить его на отдельные заявления? Это действительно не проблема в вашем примере. Или вам это нужно для другого варианта использования?

Ответ 4

у нас есть много полезных ответов здесь. и вот мое решение для нескольких операторов вставки, однако я использовал файл в активах не в строке, каждая строка в этом файле является оператором insert.

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

    }

Ответ 5

Попробуйте что-то вроде этого:

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