2013-02-23 162 views
0

我試圖做出與SQLite數據庫的Android應用程序,但是當我嘗試做一個查詢表「clientes」我展示一個RuntimeException。 我已經嘗試了很多東西,我發現有很多的解決方案,但沒有工作。android.database.sqlite.SQLiteException:沒有這樣的表:

主類:

public class AndroidBaseDatos extends Activity { 

private TextView texto; 
private String nombre; 
private DBHelper BD; 
/**Array donde guardamos los nuevos dispositivos encontrados**/ 
private ArrayAdapter<String> query; 
private ListView queryResult; 

UsuariosSQLiteHelper usdbh = 
     new UsuariosSQLiteHelper(this, "DBUsuarios", null, 1); 
    SQLiteDatabase db; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_android_base_datos); 

    texto = (TextView) findViewById(R.id.textView1); 
    queryResult = (ListView) findViewById(R.id.listView1); 
    BD=new DBHelper(this); 
    BD.open(); 
} 

public void onStart() { 
    super.onStart();   
    //Base de datos database 
      String[] campos = new String[] {"nombre", "apellidos", "edad"}; 
      String[] args = new String[] {"2"}; 
      db=usdbh.getReadableDatabase(); 
      Cursor c = db.query("clientes", campos, "_id=?", args, null, null, null); 
      //Cursor c = db.query("Usuarios", campos, null, null, null, null, null); 

    // Inicializa el array 
      query = new ArrayAdapter<String>(this, R.layout.nombre_dispositivo); 

// Establece el Listview para los dispositivos nuevos 


    //Nos aseguramos de que existe al menos un registro 
    if (c.moveToFirst()) { 
     //Recorremos el cursor hasta que no haya más registros 
     do { 
       nombre = c.getString(0); 
       String apellidos = c.getString(1); 
       int edad = Integer.parseInt(c.getString(2)); 
       Log.d("obteniendo datos", nombre); 
       query.add(nombre); 
       query.add(apellidos); 
       query.add(String.valueOf(edad)); 
       //String email = c.getString(1); 
     } while(c.moveToNext()); 
    } 
    texto.setText(nombre); 
    queryResult.setAdapter(query); 
    db.close(); 
} 

和擴展SQLiteOpenHelper

public class DBHelper extends SQLiteOpenHelper { 

// Ruta por defecto de las bases de datos en el sistema Android 
private static String DB_PATH = "/data/data/com.example.bbdd/databases/"; 

private static String DB_NAME = "database.db"; 

private SQLiteDatabase myDataBase; 

private final Context myContext; 

// Array de strings para su uso en los diferentes métodos 

/** 
* Constructor Toma referencia hacia el contexto de la aplicación que lo 
* invoca para poder acceder a los 'assets' y 'resources' de la aplicación. 
* Crea un objeto DBOpenHelper que nos permitirá controlar la apertura de la 
* base de datos. 
* 
* @param context 
*/ 
public DBHelper(Context context) { 

    super(context, DB_NAME, null, 1); 
    myContext = context; 
    myDataBase = this.getReadableDatabase(); 

} 

/** 
* Crea una base de datos vacía en el sistema y la reescribe con nuestro 
* fichero de base de datos. 
* */ 
public void createDataBase() throws IOException { 

    boolean dbExist = checkDataBase(); 
    SQLiteDatabase db_Read = null; 

    if (dbExist) { 
     // la base de datos existe y no hacemos nada. 
     Log.i("creando base de datos", "Ya existe"); 
     //copyDataBase(); 
    } else { 
     // Llamando a este método se crea la base de datos vacía en la ruta 
     // por defecto del sistema 
     // de nuestra aplicación por lo que podremos sobreescribirla con 
     // nuestra base de datos. 

     db_Read = this.getReadableDatabase(); 
     db_Read.close(); 
     Log.i("creando base de datos", "Creando la base de datos"); 

     try { 

      copyDataBase(); 

     } catch (IOException e) { 
      throw new Error("Error copiando Base de Datos"); 
     } 
    } 

} 

/** 
* Comprueba si la base de datos existe para evitar copiar siempre el 
* fichero cada vez que se abra la aplicación. 
* 
* @return true si existe, false si no existe 
*/ 
private boolean checkDataBase() { 

    SQLiteDatabase checkDB = null; 

    try { 

     String myPath = DB_PATH + DB_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, 
       SQLiteDatabase.OPEN_READONLY); 

    } catch (SQLiteException e) { 

     // si llegamos aqui es porque la base de datos no existe todavía. 

    } 
    if (checkDB != null) { 

     checkDB.close(); 

    } 
    return checkDB != null ? true : false; 
} 

/** 
* Copia nuestra base de datos desde la carpeta assets a la recién creada 
* base de datos en la carpeta de sistema, desde dónde podremos acceder a 
* ella. Esto se hace con bytestream. 
* */ 
private void copyDataBase() throws IOException { 
    Log.i("copiando base de datos", "Copiando..."); 
    // Abrimos el fichero de base de datos como entrada 
    InputStream myInput = myContext.getAssets().open(DB_NAME); 

    Log.i("copiando base de datos", myContext.getAssets().open(DB_NAME).toString()); 
    // Ruta a la base de datos vacía recién creada 
    String outFileName = DB_PATH + DB_NAME; 
    Log.i("copiando base de datos", DB_PATH + DB_NAME); 

    // Abrimos la base de datos vacía como salida 
    OutputStream myOutput = new FileOutputStream(outFileName); 

    // Transferimos los bytes desde el fichero de entrada al de salida 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = myInput.read(buffer)) > 0) { 
     myOutput.write(buffer, 0, length); 
    } 

    // Liberamos los streams 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 

} 

public void open() throws SQLException { 

    // Abre la base de datos 
    try { 
     createDataBase(); 
    } catch (IOException e) { 
     throw new Error("Ha sido imposible crear la Base de Datos"); 
    } 

    String myPath = DB_PATH + DB_NAME; 
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, 
      SQLiteDatabase.OPEN_READONLY); 

} 

@Override 
public synchronized void close() { 
    if (myDataBase != null) 
     myDataBase.close(); 
    super.close(); 
} 

@Override 
public void onCreate(SQLiteDatabase db) { 

} 

public void crearTabla(){ 
    String sqlCreate = "CREATE TABLE clientes (_id INTEGER, nombre TEXT, apellidos TEXT, edad INTEGER)"; 
    myDataBase.execSQL(sqlCreate); 
    myDataBase.execSQL("INSERT INTO clientes (_id, nombre, apellidos, edad) " + 
      "VALUES (2, 'Alberto', 'Redondo', 27)"); 
} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

} 

類這是調試信息。

> 02-23 02:18:25.072: E/Trace(4081): error opening trace file: No such file or directory (2) 
02-23 02:18:26.370: I/creando base de datos(4081): Ya existe 
02-23 02:18:26.410: E/SQLiteLog(4081): (1) no such table: clientes 
02-23 02:18:26.410: D/AndroidRuntime(4081): Shutting down VM 
02-23 02:18:26.421: W/dalvikvm(4081): threadid=1: thread exiting with uncaught exception (group=0x40a13300) 
02-23 02:18:26.450: E/AndroidRuntime(4081): FATAL EXCEPTION: main 
02-23 02:18:26.450: E/AndroidRuntime(4081): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.bbdd/com.example.bbdd.AndroidBaseDatos}: android.database.sqlite.SQLiteException: no such table: clientes (code 1): , while compiling: SELECT nombre, apellidos, edad FROM clientes WHERE _id=? 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.app.ActivityThread.access$600(ActivityThread.java:130) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.os.Handler.dispatchMessage(Handler.java:99) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.os.Looper.loop(Looper.java:137) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.app.ActivityThread.main(ActivityThread.java:4745) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at java.lang.reflect.Method.invoke(Method.java:511) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at dalvik.system.NativeStart.main(Native Method) 
02-23 02:18:26.450: E/AndroidRuntime(4081): Caused by: android.database.sqlite.SQLiteException: no such table: clientes (code 1): , while compiling: SELECT nombre, apellidos, edad FROM clientes WHERE _id=? 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:882) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at com.example.bbdd.AndroidBaseDatos.onStart(AndroidBaseDatos.java:90) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1163) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.app.Activity.performStart(Activity.java:5018) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2032) 
02-23 02:18:26.450: E/AndroidRuntime(4081):  ... 11 more 
02-23 02:23:26.573: I/Process(4081): Sending signal. PID: 4081 SIG: 9 

這是一個數據庫文件名稱數據庫,當我與外殼打開它創建的表clientes,如果嘗試創建它再次說明,指出該表alredy存在一個SQLException,作爲表我檢查之前,但我不能顯示任何查詢任何數據庫中的任何表。

謝謝。

+0

在我可以幫助你之前,我想知道你是否打算從資產文件夾複製一個已經創建的數據庫文件,或者你正在使用sql create語句創建一個新的數據庫文件? ..因爲我可以看到你在你的代碼中做了兩件事,這是沒有道理的! – kdehairy 2013-02-25 09:33:19

+0

我的第一個想法是從數據庫文件中複製所有信息,但是當出現錯誤時,我試圖創建一個新的查詢來查看查詢是否有錯誤,這就是爲什麼兩個代碼混合在一起 – 2013-02-25 19:33:52

回答

2
  • 第一次:刪除創建數據庫的代碼。也就是說,堅持你的第一個想法(從資產文件夾複製數據庫)。
  • 秒:使用sqlite3打開並測試您的桌面上的數據庫文件(即測試您的查詢)的有效性。如果它是有效的,並測試成功,請繼續..
  • 第三:更容易,更直接的使用this implementation(這是我的博客)

請讓我知道,如果出事了。

+0

非常感謝,它非常完美。 – 2013-02-26 19:38:21

+0

鏈接已損壞:( – Ricardo 2013-12-02 19:27:11

+1

@Ricardo遺憾的是,我更新的鏈接。現在應該工作。請告知如果你發現任何問題,我知道。 – kdehairy 2013-12-02 22:57:39

0

看來你從來沒有打電話crearTabla從代碼中的任何地方創建表。您至少應該從SQLiteOpenHelper上的onCreate調用它。

+0

我不稱呼crear Tabla因爲當我這樣做時,會出現一個SQLException表示表客戶已經存在。 – 2013-02-25 08:18:47

0

創建簡單的插入和更新用代碼嘗試這樣可能會有所幫助......

public class MainActivity extends Activity implements OnClickListener { 

SQLiteDatabase database; 
private static final String DBNAME="Example"; 
Button btn1,btn2; 
EditText et1,et2; 
int id=0; 
String name=null; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    et1=(EditText) findViewById(R.id.editText1); 
    et2=(EditText) findViewById(R.id.editText2); 


    database=openOrCreateDatabase(DBNAME, MODE_PRIVATE, null); 
    btn1=(Button) findViewById(R.id.button1); 
    btn2=(Button) findViewById(R.id.button2); 
    btn2.setOnClickListener(this); 
    btn1.setOnClickListener(this); 


} 

@Override 
public void onClick(View v) { 

    switch(v.getId()){ 
    case R.id.button1: 
     id =Integer.parseInt(et1.getText().toString()); 
     name=et2.getText().toString(); 
     try{ 
      database.execSQL("CREATE TABLE IF NOT EXISTS tabl(_id INTEGER PRIMARY KEY,id NUMERIC,name TEXT)"); 
      Log.v("hi", "table created"); 
      database.beginTransaction(); 
      database.execSQL("INSERT INTO tabl(id,name) VALUES ("+id+",'"+name+"');"); 
      database.setTransactionSuccessful(); 
      database.endTransaction(); 
     } 
     catch(Exception e){ 
      Log.v("hi", e.toString()); 
     } 
     break; 
    case R.id.button2: 
     id =Integer.parseInt(et1.getText().toString()); 
     name=et2.getText().toString(); 
     try{ 
      database.beginTransaction(); 
      database.execSQL("UPDATE tabl SET name='"+name+"' WHERE id="+id+";"); 
      database.setTransactionSuccessful(); 
      database.endTransaction(); 
     } 
     catch(Exception e){ 
      Log.v("hi", e.toString()); 
     } 
    } 
} 
} 

和資源

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> 
    <EditText android:id="@+id/editText1" android:layout_width="wrap_content"  android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="91dp" android:layout_marginTop="64dp" android:ems="10"> 
    <requestFocus /> 
    </EditText> 
    <EditText android:id="@+id/editText2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/editText1" android:layout_below="@+id/editText1" android:layout_marginLeft="50dp" android:layout_marginTop="36dp" android:ems="10" /> 
    <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/editText2" android:layout_centerVertical="true" android:text="Button" /> 
    <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button1" android:layout_alignBottom="@+id/button1" android:layout_alignRight="@+id/editText2" android:text="Button" /> 
    </RelativeLayout> 

嘗試這樣,可能會有所幫助

相關問題