2010-09-27 26 views
33

He seguido un tutorial estándar para compilar una base de datos con Android. Creé una clase llamada DbHelper que amplía SQLiteOpenHelper. He redefinido el controlador de creación para ejecutar una cadena.Ejecutando varias declaraciones con SQLiteDatabase.execSQL

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

DbDefinitions.DB_CREATE es una cadena estática que he creado.

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

Me gustaría utilizar 1 cadena para ejecutar varias instrucciones SQL. ¿Cómo puedo hacer esto ya que SQLiteDatabase.execSQL solo permite 1 declaración?

Respuesta

36

Eso no es posible con los métodos estándar que vienen con Android. Por lo tanto, si desea ejecutar lote de varias sentencias de SQL, tendrá que crear su propia utilidad para hacerlo. Por ejemplo, puede tener algo como esto:

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

Sin embargo, lo que haría es algo como esto:

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

Gracias, justo lo que necesitaba funciona como un encanto. –

+4

que pasa si el ';' está dentro de un campo de texto? –

+1

El **; ** al final de las sentencias de SQL es completamente inútil. –

0

Según la documentación de SQLiteDatabase y mi experiencia en el pasado, creo que no es posible. Pero, ¿por qué no lo divide en declaraciones individuales? Realmente no es un problema en tu ejemplo. ¿O lo necesitas para un caso de uso diferente?

16

Bueno, en mi caso, estoy excuting consultas de un archivo me salvó como un activo Esta es la solución solía + -

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

EDITAR

En mi caso, las consultas eran simples consultas insertadas sobre las que tenía control total. Sin embargo, el problema se ha planteado con respecto a las consultas con ";" dentro de ellos.

@TWiStErRob sugiere el uso de

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

o

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

soy nuevo en el desarrollo de Java y Android pero su solución puede fallar en la línea script.split() si sus instrucciones almacenadas contienen un punto y coma como parte de un valor de texto (por ejemplo, en el valor predeterminado de una definición de columna) – jon

+0

Definitivamente a la derecha sobre eso. No creo que sea una cosa java o androide, sino más bien un problema de expresiones regulares. No soy un gurú regex, así que no puedo darte exactamente, pero usar una expresión regular que verifique si el punto y coma está al final del enunciado debería funcionar. Esto funciona para mí, ya que mi script es principalmente para crear varias tablas. – frostymarvelous

+0

¡gracias !, funcionó! – OWADVL

0

tenemos muchas respuestas greate aquí. y esta es mi solución para múltiples instrucciones de inserción, sin embargo, utilicé un archivo en activos no en fila, cada línea en este archivo es una declaración de inserció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

intentar algo como esto:

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