我知道有很多问题都存在相同的问题。接下来我将尝试做的事情:
我认为我的问题是我没有同时创建两个表,但是我看不到为什么它没有正确执行。
我正在尝试通过执行SELECT语句,使用“ tomasPendientes”表中的数据填充列表视图。
这是db helper类的代码:
public class AdminSQLiteOpenHelper extends SQLiteOpenHelper {
private ContentValues registro;
private static final String nombre ="dbAlarma";
private static final int versionDB = 1;
private static String table1 = "create table alarma( idal integer primary key autoincrement, nombreMed text, hora time, pastillasTotales integer, pastillasRestantes integer)";
private static String table2 = "create table tomasPendientes( idPend integer, FOREIGN KEY (idPend) REFERENCES alarma (idal))";
public AdminSQLiteOpenHelper(Context context, String nombre, SQLiteDatabase.CursorFactory factory, int version) {
super(context, nombre, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("DATABASE_CREATION", "Base de datos creandose...");
db.execSQL(table1);
db.execSQL(table2);
}
@Override
public void onUpgrade(SQLiteDatabase db, int versionAnte, int versionNue) {
Log.d("DATABASE_UPDATE", "Base de datos actualizandose...");
db.execSQL("drop table if exists alarma" );
db.execSQL("drop table if exists tomasPendientes");
db.execSQL(table1);
db.execSQL(table2);
}
public Cursor getTomasPendientes(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM tomasPendientes NATURAL JOIN alarma";
Cursor data = db.rawQuery(query, null);
return data;
}
public void insertarPendiente(String alarma){
SQLiteDatabase bd = this.getWritableDatabase();
registro = new ContentValues();
registro.put("idPendiente",alarma);
bd.insert("tomasPendientes", null, registro);//nombre de la tabla
bd.close();
}
}
这是正在调用使用数据库的方法的类,该函数用于显示带有db数据的列表视图:
public class VerTomasPendientes extends AppCompatActivity {
private ListView lv;
AdminSQLiteOpenHelper mDataBaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ver_tomas_pendientes);
lv = findViewById(R.id.lvAlarmas);
mDataBaseHelper = new AdminSQLiteOpenHelper(this, vars.bd, null, vars.version);
populateLV();
}
private void populateLV() {
Cursor data = mDataBaseHelper.getTomasPendientes();
ArrayList<String> listData = new ArrayList<>();
while(data.moveToNext()){
listData.add("Id alarma: " + data.getString(0) + "\n");
}
ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listData);
lv.setAdapter(adapter);
}
}
logcat中的错误是下一个:
Caused by: android.database.sqlite.SQLiteException: no such table: tomasPendientes (code 1): , while compiling: SELECT * FROM tomasPendientes NATURAL JOIN alarma at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:893) at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:504) at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:726) at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58) at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37) at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1426) at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1365) at farmacia.farmacia.AdminSQLiteOpenHelper.getTomasPendientes(AdminSQLiteOpenHelper.java:48) at farmacia.farmacia.VerTomasPendientes.populateLV(VerTomasPendientes.java:25) at farmacia.farmacia.VerTomasPendientes.onCreate(VerTomasPendientes.java:21)
我不明白为什么它创建不正确。
答案 0 :(得分:1)
我相信您的问题是您正在查看logcat的错误部分。那是您在查看先前的故障,而不是当前的故障。
运行确切的代码,不会导致表格未找到错误,但会按照以下说明发出列未找到错误:-
10-23 23:29:36.039 2189-2189/? E/SQLiteLog: (1) table tomasPendientes has no column named idPendiente
10-23 23:29:36.043 2189-2189/? E/SQLiteDatabase: Error inserting idPendiente=bert
android.database.sqlite.SQLiteException: table tomasPendientes has no column named idPendiente (code 1): , while compiling: INSERT INTO tomasPendientes(idPendiente) VALUES (?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:882)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1467)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
at axtest.axtest.AdminSQLiteOpenHelper.insertarPendiente(AdminSQLiteOpenHelper.java:48)
at axtest.axtest.MainActivity.onCreate(MainActivity.java:18)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
如果 tomasPendientes 表中没有这样的列,则您已使用registro.put("idPendiente",alarma);
。列为 idPend 。
但是,更改为列 idPend 会导致外键约束冲突(但是这些键未打开),因为似乎没有任何行插入到该表中 tomasPendientes 表所依赖。
以下代码是AdminSQLiteOpenhelper.java的修改版和一个调用活动。
AdminSQLiteOpenHelper.java
public class AdminSQLiteOpenHelper extends SQLiteOpenHelper {
private ContentValues registro;
private static final String nombre ="dbAlarma";
private static final int versionDB = 1;
//<<<<<<<<<< HIGHLY RECOMMEND A SINGLE DEFINITION OF TABLE and COLUMN NAMES
public static final String TABLE_ALARMA = "alarma";
public static final String TABLE_TOMASPENDIENTES = "tomasPendientes";
public static final String ALARMA_COL_IDA1 = "ida1";
public static final String ALARMA_COL_NOMBREMED = "nombreMed";
public static final String ALARMA_COl_HORA = "hora";
public static final String ALARMA_COL_PASTILLASTOTALES = "pastillasTotales";
public static final String ALARMA_COL_PASTILLASRENTANTES = "pastillasRestantes";
public static final String TOMASPENDIENTES_COL_IDPEND = "idPend";
private static String table1 = "create table alarma( idal integer primary key autoincrement, nombreMed text, hora time, pastillasTotales integer, pastillasRestantes integer)";
private static String crtt1 = "CREATE TABLE IF NOT EXISTS " + TABLE_ALARMA + "(" +
ALARMA_COL_IDA1 + " INTEGER PRIMARY KEY, " + //<<<<<<<<<< AUTOINCREMENT VERY LIKELY NOT REQUIRED SO OMITTED
ALARMA_COL_NOMBREMED + " TEXT, " +
ALARMA_COl_HORA + " TEXT," + //<<<<<<<<<< no column type called time as text (bit of a moot point as it probablu will not matter)
ALARMA_COL_PASTILLASTOTALES + " INTEGER, " +
ALARMA_COL_PASTILLASRENTANTES + " INTEGER " +
")";
private static String table2 = "create table tomasPendientes( idPend integer, FOREIGN KEY (idPend) REFERENCES alarma (idal))";
//<<<<<<<<<< THIS TABLES IS USELESSS AS IT IS >>>>>>>>>>
private static String crtt2 = "CREATE TABLE IF NOT EXISTS " + TABLE_TOMASPENDIENTES + "(" +
TOMASPENDIENTES_COL_IDPEND + " INTEGER REFERENCES " + TABLE_ALARMA + "(" + ALARMA_COL_IDA1 + ") " +
")";
public AdminSQLiteOpenHelper(Context context, String nombre, SQLiteDatabase.CursorFactory factory, int version) {
super(context, nombre, factory, version);
}
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.execSQL("PRAGMA foreign_keys = ON;");
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("DATABASE_CREATION", "Base de datos creandose...");
db.execSQL(crtt1);
db.execSQL(crtt2);
}
@Override
public void onUpgrade(SQLiteDatabase db, int versionAnte, int versionNue) {
Log.d("DATABASE_UPDATE", "Base de datos actualizandose...");
db.execSQL("drop table if exists alarma" );
db.execSQL("drop table if exists tomasPendientes");
onCreate(db); //<<<<<<<<<< just call onCreate
}
public Cursor getTomasPendientes(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM tomasPendientes NATURAL JOIN alarma";
Cursor data = db.rawQuery(query, null);
return data;
}
//<<<<<<<<<< NEW
public long insertAlarma(String nombreMed, String hora, int pastillastotales, int pastillarentantes) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(ALARMA_COL_NOMBREMED,nombreMed);
cv.put(ALARMA_COl_HORA,hora);
cv.put(ALARMA_COL_PASTILLASTOTALES,pastillastotales);
cv.put(ALARMA_COL_PASTILLASRENTANTES,pastillarentantes);
return db.insert(TABLE_ALARMA,null,cv);
}
//<<<<<<<<<< REPLACEMENT
public long insertTomaPendientes(long idpend) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(TOMASPENDIENTES_COL_IDPEND,idpend);
return db.insert(TABLE_TOMASPENDIENTES,null,cv);
}
/*<<<<<<<<<< OLD
public void insertarPendiente(String alarma){
SQLiteDatabase bd = this.getWritableDatabase();
registro = new ContentValues();
registro.put("idPendiente",alarma);
bd.insert("tomasPendientes", null, registro);//nombre de la tabla
bd.close();
}
*/
}
该活动中使用的代码为:-
public class MainActivity extends AppCompatActivity {
AdminSQLiteOpenHelper mASQLiteHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mASQLiteHlpr = new AdminSQLiteOpenHelper(this,"fred",null,1);
mASQLiteHlpr.insertAlarma("Alarm1","2018-01-11 23:59:59",1234,156);
mASQLiteHlpr.insertAlarma("Alarm2","2018-01-11 23:59:59",2234,256);
mASQLiteHlpr.insertAlarma("Alarm3","2018-01-11 23:59:59",3234,356);
Cursor c1 = mASQLiteHlpr.getTomasPendientes();
DatabaseUtils.dumpCursor(c1);
mASQLiteHlpr.insertTomaPendientes(1); // 1 will be OK as there a row in alama table will have 1 in column ida1
mASQLiteHlpr.insertTomaPendientes(100); // ooops nor row in alarma with 100 in column ida1
mASQLiteHlpr.insertTomaPendientes(2); // will work
Cursor c2 = mASQLiteHlpr.getTomasPendientes();
DatabaseUtils.dumpCursor(c2);
c1.close();
c2.close();
}
}
输出到日志:-
10-24 00:38:30.423 2694-2694/axtest.axtest D/DATABASE_CREATION: Base de datos creandose...
10-24 00:38:30.431 2694-2694/axtest.axtest I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@53450f08
10-24 00:38:30.431 2694-2694/axtest.axtest I/System.out: <<<<<
10-24 00:38:30.435 2694-2694/axtest.axtest E/SQLiteDatabase: Error inserting idPend=100
android.database.sqlite.SQLiteConstraintException: foreign key constraint failed (code 19)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:775)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
at axtest.axtest.AdminSQLiteOpenHelper.insertTomaPendientes(AdminSQLiteOpenHelper.java:92)
at axtest.axtest.MainActivity.onCreate(MainActivity.java:27)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@5346544c
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: 0 {
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: idPend=1
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: ida1=1
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: nombreMed=Alarm1
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: hora=2018-01-11 23:59:59
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: pastillasTotales=1234
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: pastillasRestantes=156
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: }
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: 1 {
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: idPend=1
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: ida1=2
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: nombreMed=Alarm2
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: hora=2018-01-11 23:59:59
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: pastillasTotales=2234
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: pastillasRestantes=256
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: }
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: 2 {
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: idPend=1
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: ida1=3
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: nombreMed=Alarm3
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: hora=2018-01-11 23:59:59
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: pastillasTotales=3234
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: pastillasRestantes=356
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: }
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: 3 {
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: idPend=2
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: ida1=1
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: nombreMed=Alarm1
10-24 00:38:30.439 2694-2694/axtest.axtest I/System.out: hora=2018-01-11 23:59:59
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: pastillasTotales=1234
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: pastillasRestantes=156
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: }
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: 4 {
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: idPend=2
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: ida1=2
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: nombreMed=Alarm2
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: hora=2018-01-11 23:59:59
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: pastillasTotales=2234
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: pastillasRestantes=256
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: }
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: 5 {
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: idPend=2
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: ida1=3
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: nombreMed=Alarm3
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: hora=2018-01-11 23:59:59
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: pastillasTotales=3234
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: pastillasRestantes=356
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: }
10-24 00:38:30.443 2694-2694/axtest.axtest I/System.out: <<<<<
注意(如果使用以上代码,则应在运行代码之前执行以下操作之一):-
tomasPendientes 表本身没有任何用处,因为它只有1列必须与的 ida1 列中的值重复> alarma 表。
答案 1 :(得分:0)
您已经在创建table1之后添加了table2吗?
与之类似,您以前是否使用table1进行编译?如果是这样,可能只是您的应用程序未运行onCreate,因为它仅运行一次。创建数据库后,onCreate将不再运行。
要解决此问题,您可能只需要在模拟器中卸载该应用,然后再次运行即可。
希望有帮助:)
编辑:我没有看到您已经尝试过此操作。