无法在sqlite中创建第二个表

时间:2011-11-16 20:12:34

标签: android sqlite

在尝试了博客,论坛,网页的所有可能解决方案之后,我想出了这个问题。

最初我创建了一个带有“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)

4 个答案:

答案 0 :(得分:1)

您的表格约束必须after your column definitions

create table syntax diagram

请注意上面语法图中的“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标记为purposeTableinsertPurpose没有不为它提供价值。您还有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