2010-09-27 45 views
33

Tôi đã làm theo hướng dẫn chuẩn để xây dựng cơ sở dữ liệu với Android. Tôi đã tạo ra một lớp được gọi là DbHelper mở rộng SQLiteOpenHelper. Tôi đã ghi đè trình xử lý tạo để thực hiện chuỗi.Thực hiện nhiều câu lệnh với SQLiteDatabase.execSQL

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

DbDefinitions.DB_CREATE là chuỗi tĩnh tôi đã tạo.

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

Tôi muốn sử dụng 1 Chuỗi để thực thi nhiều câu lệnh SQL. Làm thế nào tôi có thể làm điều này như SQLiteDatabase.execSQL chỉ cho phép 1 tuyên bố?

Trả lời

36

Không thể thực hiện bằng các phương pháp chuẩn đi kèm với Android. Vì vậy, nếu bạn muốn thực hiện của nhiều câu lệnh SQL, bạn sẽ phải tạo tiện ích của riêng mình để làm như vậy. Ví dụ, bạn có thể có một cái gì đó như thế này:

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

Mặc dù, những gì tôi muốn làm là một cái gì đó như thế này:

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

Cảm ơn, chỉ là những gì tôi cần làm việc giống như một nét duyên dáng. –

+4

nếu như ';' nằm trong trường văn bản? –

+1

**; ** ở cuối câu lệnh SQL hoàn toàn vô dụng. –

0

Từ tài liệu về SQLiteDatabase và kinh nghiệm của tôi trong quá khứ tôi nghĩ rằng điều đó là không thể. Nhưng tại sao bạn không chia nó ra thành từng câu? Nó thực sự không phải là một vấn đề trong ví dụ của bạn. Hay bạn cần nó cho một trường hợp sử dụng khác nhau?

16

Vâng, trong trường hợp của tôi, tôi excuting truy vấn từ một tập tin mà tôi lưu lại dưới dạng một tài sản Đây là giải pháp tôi đã sử dụng + -

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

Trong trường hợp của tôi, Truy vấn là các truy vấn chèn đơn giản mà tôi có toàn quyền kiểm soát. Tuy nhiên, vấn đề đã được nêu lên liên quan đến các truy vấn với ";" Bên trong họ.

@TWiStErRob gợi ý sử dụng

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

hoặc

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

Tôi mới phát triển Java và Android nhưng giải pháp của bạn có thể thất bại trên dòng script.split() nếu câu lệnh được lưu trữ của bạn chứa dấu chấm phẩy như một phần của giá trị văn bản (ví dụ: giá trị mặc định của định nghĩa cột) – jon

+0

Bạn chắc chắn đúng về điều đó. Tôi không nghĩ rằng đó là một điều java hay android, mà là một vấn đề regex. Tôi không có guru regex vì vậy tôi không thể cung cấp cho bạn những điều chính xác, nhưng bằng cách sử dụng một regex mà kiểm tra nếu dấu chấm phẩy là ở phần cuối của tuyên bố sẽ làm việc. Điều này làm việc cho tôi như kịch bản của tôi chủ yếu là để tạo ra các bảng khác nhau. – frostymarvelous

+0

cảm ơn !, nó đã hoạt động! – OWADVL

0

chúng tôi có nhiều câu trả lời Greate đây. và đây là giải pháp của tôi cho nhiều câu lệnh chèn, tuy nhiên tôi đã sử dụng tệp trong nội dung không có trong hàng, mỗi dòng trong tệp này là một câu lệnh chèn.

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

Hãy thử một cái gì đó như thế này:

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"); 
Các vấn đề liên quan