在尝试了博客,论坛,网页的所有可能解决方案之后,我想出了这个问题。
最初我创建了一个带有“registrationTable”表的数据库,我能够完成所有CRUD操作。然后我尝试添加第二个表“purposeTable”,由于某种原因没有创建。
我尝试过以下事情:
更改了数据库版本
更改了第二个表的create语句
包括“PRAGMA foreign_keys = ON;”因为第二个表包含一个外键
将“cdate”字段的数据类型从文本交换到日期,反之亦然
但是表格仍未创建。
我的DBAdapter类的代码如下:
//Table 1
private static final String TAG = "DBAdapter";
private static final String DATABASE_TABLE = "registrationTable";
private static final String DATABASE_NAME = "project1database";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table registrationTable ( phone integer primary key not null, name text not null, " +
"age integer not null, area text not null, sex text not null);";
//Table 2
private static final String PURPOSE_TABLE = "purposeTable";
private static final String PURPOSE_CREATE = "create table purposeTable ( phone integer not null, foreign key (phone) references registrationTable(phone), " +
"cdate text not null, primary key (phone, date), text1 text not null, text2 text not null);";
private final Context context;
private SQLiteDatabase db;
private DatabaseHelper DBHelper;
public DBAdapter(Context ctx){
context = ctx;
}
//public DBAdapter read()throws SQLException
//public DBAdapter write()throws SQLException
//public void close()
//public long insertDetails(String name, int age, String area, int phone, String sex)
public long insertPurpose(String date, String text1, String text2){
ContentValues initialValues1 = new ContentValues();
initialValues1.put(CDATE, date);
initialValues1.put(TEXT1, text1);
initialValues1.put(TEXT2, text2);
return db.insert(PURPOSE_TABLE, null, initialValues1);
}
private static class DatabaseHelper extends SQLiteOpenHelper{
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
try{
db.execSQL(DATABASE_CREATE);
db.execSQL(PURPOSE_CREATE);
db.execSQL("PRAGMA foreign_keys = ON;");
}catch(SQLException e){
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading from version " + oldVersion + " to " + newVersion + ". All data will be deleted.");
db.execSQL("DROP TABLE IF EXISTS registrationTable");
db.execSQL("DROP TABLE IF EXISTS purposeTable");
onCreate(db);
}
}
我从另一个类调用方法insertPurpose(),代码如下:
dbAdapter2.write();
dbAdapter2.insertPurpose(cDate, text1, text2);
dbAdapter2.close();
logcat日志如下:
11-17 01:29:17.023: I/SqliteDatabaseCpp(15095): sqlite returned: error code = 1, msg = no such table: purposeTable, db=/data/data/com.android.project1/databases/project1database
11-17 01:29:17.143: E/SQLiteDatabase(15095): Error inserting text1=a text2=b cdate=17-11-2011
11-17 01:29:17.143: E/SQLiteDatabase(15095): android.database.sqlite.SQLiteException: no such table: purposeTable: , while compiling: INSERT INTO purposeTable(text1,text2,cdate) VALUES (?,?,?)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:260)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:112)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1745)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1618)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at com.android.project1.DBAdapter.insertPurpose(DBAdapter.java:113)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at com.android.project1.Purpose3Activity$1.onClick(Purpose3Activity.java:51)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.view.View.performClick(View.java:3460)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.view.View$PerformClick.run(View.java:13955)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.os.Handler.handleCallback(Handler.java:605)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.os.Handler.dispatchMessage(Handler.java:92)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.os.Looper.loop(Looper.java:137)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at android.app.ActivityThread.main(ActivityThread.java:4340)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at java.lang.reflect.Method.invokeNative(Native Method)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at java.lang.reflect.Method.invoke(Method.java:511)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-17 01:29:17.143: E/SQLiteDatabase(15095): at dalvik.system.NativeStart.main(Native Method)
先谢谢,如果有人能告诉我哪里出错了。
创建了第二个表,但未插入数据,新日志:
11-17 11:42:11.281: E/SQLiteDatabase(10172): Error inserting text1=e text2=d cdate=17-11-2011
11-17 11:42:11.281: E/SQLiteDatabase(10172): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.database.sqlite.SQLiteStatement.native_executeInsert(Native Method)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:113)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1745)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1618)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at com.android.project1.DBAdapter.insertPurpose(DBAdapter.java:113)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at com.android.project1.Purpose3Activity$1.onClick(Purpose3Activity.java:51)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.view.View.performClick(View.java:3460)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.view.View$PerformClick.run(View.java:13955)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.os.Handler.handleCallback(Handler.java:605)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.os.Handler.dispatchMessage(Handler.java:92)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.os.Looper.loop(Looper.java:137)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at android.app.ActivityThread.main(ActivityThread.java:4340)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at java.lang.reflect.Method.invokeNative(Native Method)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at java.lang.reflect.Method.invoke(Method.java:511)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-17 11:42:11.281: E/SQLiteDatabase(10172): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
您的表格约束必须after your column definitions:
请注意上面语法图中的“column-def”和“table-constraint”循环。
您的主键中也有拼写错误(date
应为cdate
)。
用于创建purposeTable
的SQL应如下所示:
create table purposeTable (
phone integer not null,
cdate text not null,
text1 text not null,
text2 text not null,
primary key (phone, cdate),
foreign key (phone) references registrationTable(phone)
);
就您的insertPurpose
方法而言,它不起作用,因为您phone
中的not null
标记为purposeTable
但insertPurpose
没有不为它提供价值。您还有phone
作为表主键的一部分,因此您无法删除not null
。我认为您应该在phone
中为insertPurpose
提供值。
答案 1 :(得分:1)
在第二个表的create table
中,您尝试在(电话,日期)上创建主键。那里没有date
列 - 仅cdate
。此外,约束(即主/外键)应该在字段声明之后。以下语法可以使用:
create table purposeTable (
phone integer not null,
cdate text not null,
text1 text not null,
text2 text not null,
primary key (phone, cdate),
foreign key (phone) references registrationTable(phone));
在从程序运行设备上的任何SQL之前,尝试在基于桌面的SQLite数据库上以交互方式运行它,看看它是如何工作的。以这种方式调试更容易。我建议使用一个不错的基于桌面的SQLite GUI,e。 G。 SQLiteStudio
编辑:插入失败:
您没有提供phone
。它是一个非空字段,必须在insert语句中提供,否则not null
约束将失败。这就是错误所说的。
答案 2 :(得分:0)
尝试将DATABASE_VERSION = 2
设置为触发onUpgrade
,然后创建表格。
答案 3 :(得分:0)
我的感觉是句子中有一些错误会产生目的表。尝试在shell中执行它以查看它是否有效。
如果您在一个数据库中有多个表,我的个人建议是针对不同的表使用不同的类并使用该句子:
CREATE TABLE IF NOT EXISTS tableName
而不是 CREATE TABLE tableName并覆盖DataBaseHelper的onOpen方法。
它将使您的代码更加清晰,易于调试。
http://www.jiahaoliuliu.com/2011/09/sqlite-create-multiple-tables-with.html