android.database.sqlite.SQLiteException:没有这样的表:

时间:2013-02-23 03:11:53

标签: android database android-sqlite

我正在尝试使用SQlite数据库创建一个Android应用程序,但是当我尝试对表进行查询时,“clientes”会向我显示一个RuntimeException。 我尝试了很多东西,我找到了许多解决方案,但都没有。

主要班级:

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

它在db文件名数据库中的表,当我用shell打开它时,表会创建它,如果尝试再次创建它,则显示一个SQLException,表示表alredy存在,正如我之前检查的那样,但是我无法向任何数据库中的任何表显示任何查询。

谢谢。

3 个答案:

答案 0 :(得分:2)

  • 首先:删除创建数据库的代码。也就是说,坚持你的第一个想法(从资产文件夹复制数据库)。
  • 第二个:使用sqlite3在桌面上打开并测试数据库文件的有效性(即测试您的查询)。如果它有效且测试成功,请继续..
  • 第三:使用this implementation(这是我的博客)更简单,更直接
如果出现问题,请告诉我。

答案 1 :(得分:0)

您似乎永远不会致电crearTabla从代码中的任何位置创建表格。您至少应该在SQLiteOpenHelper上从onCreate调用它。

答案 2 :(得分: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>

尝试这样。,可能会有所帮助