2010-09-27 2 views
33

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

@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 строку для выполнения нескольких операторов SQL. Как я могу это сделать, поскольку SQLiteDatabase.execSQL разрешает только 1 оператор?

ответ

36

Это невозможно сделать, используя стандартные методы, которые поставляются с 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); 
} 
+0

Спасибо, как раз то, что мне нужно работает как шарм. –

+4

Что делать, если ';' находится в текстовом поле? –

+1

** ** в конце SQL-запросов совершенно бесполезно. –

0

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

16

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

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

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

@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 
+6

Я новичок в разработке Java и Android, но ваше решение может потерпеть неудачу в строке script.split(), если ваши хранимые операторы содержат точку с запятой как часть текстового значения (например, по значению по умолчанию для определения столбца). – jon

+0

Вы определенно прямо об этом. Я не думаю, что это Java или Android, но проблема с регулярным выражением. Я не являюсь гуру регулярных выражений, поэтому я не могу дать вам точную вещь, но с использованием регулярного выражения, которое проверяет, должно ли работать запятая в конце инструкции. Это работает для меня, так как мой сценарий состоит в основном для создания различных таблиц. – frostymarvelous

+0

спасибо !, он сработал! – OWADVL

0

мы имеем много Greate ответов здесь. и вот мое решение для нескольких операторов вставки, однако я использовал файл в активах не в строке, каждая строка в этом файле является оператором 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) { 

    } 
0

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

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