简体   繁体   English

无法使用外键插入记录(Android sqlite)

[英]cannot insert a record with a foreign key (android sqlite)

I have two tables. 我有两张桌子。 One with primary key and another with foreign key to the first table. 一个具有主键,另一个具有外键的第一个表。

I try to add item to the first one and then an item to the second one. 我尝试将项目添加到第一个项目,然后将项目添加到第二个项目。

my fragment code: 我的片段代码:

            long phoneNewId = phoneDal.addItem(newPhone);
            if ( phoneNewId != 0) {
                String comment = ((EditText)rootView.findViewById(R.id.comment_text)).getText().toString();
                commentDal.addItem(phoneNewId, comment);
            }

PhoneDal: 电话号码:

public class PhoneDal extends SQLiteOpenHelper {

    // Database Version
    private static final int DATABASE_VERSION = 1;
    // Database Name
    private static final String DATABASE_NAME = Constants.DB_NAME;

    public static final String BLOCKED_PHONES_TABLE = "BLOCKED_PHONES_TABLE";

    public PhoneDal(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // SQL statement to create book table

        String CREATE_BLOCKED_PHONES_TABLE =
                "CREATE TABLE "+ BLOCKED_PHONES_TABLE +
                        " ( "+ KEY_ID+" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL  DEFAULT 1, "
                        + KEY_PHONE+" TEXT, "
                             + KEY_IS_BLOCKED+" BIT )";

        db.execSQL(CREATE_BLOCKED_PHONES_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion) {
            Log.w("MyAppTag", "Updating database from version " + oldVersion
                    + " to " + newVersion + " .Existing data will be lost.");
            // Drop older books table if existed
            db.execSQL("DROP TABLE IF EXISTS " + BLOCKED_PHONES_TABLE);

            // create fresh books table
            this.onCreate(db);
        }

    }



    private static final String KEY_ID = "id";
    private static final String KEY_PHONE = "KEY_PHONE";
    private static final String KEY_IS_BLOCKED = "KEY_IS_BLOCKED";

    public long addItem(Phone phone) {
        Log.d(Constants.LOGGER_TAG, "add saved-offer");
        // 1. get reference to writable DB
        SQLiteDatabase db = this.getWritableDatabase();

        // 2. create ContentValues to add key "column"/value
        ContentValues values = new ContentValues();
        //values.put(KEY_ID, phone.id);
        values.put(KEY_PHONE, phone.phone);
        values.put(KEY_IS_BLOCKED, phone.isBlocked);

        // 3. insert
        long newRowId =
                db.insertWithOnConflict(BLOCKED_PHONES_TABLE, KEY_ID,
                values, SQLiteDatabase.CONFLICT_REPLACE);

        // 4. close
        db.close();
        return newRowId;
    }

CommentDal: 评论Dal:

public class CommentDal extends SQLiteOpenHelper {

    // Database Version
    private static final int DATABASE_VERSION = 1;
    // Database Name
    private static final String DATABASE_NAME = Constants.DB_NAME;

    private static final String COMMENTS_TABLE = "COMMENTS_TABLE";

    public CommentDal(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // SQL statement to create book table

        String CREATE_COMMENTS_TABLE =
                "CREATE TABLE " + COMMENTS_TABLE +
                        " ( "+ KEY_ID+" INTEGER, "
                             + KEY_COMMENT_TEXT+" TEXT "
                             + "FOREIGN KEY("+KEY_ID+") REFERENCES "+PhoneDal.BLOCKED_PHONES_TABLE+"("+KEY_ID+"))";

        db.execSQL(CREATE_COMMENTS_TABLE);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion) {
            Log.w("MyAppTag", "Updating database from version " + oldVersion
                    + " to " + newVersion + " .Existing data will be lost.");
            // Drop older books table if existed
            db.execSQL("DROP TABLE IF EXISTS " + COMMENTS_TABLE);

            // create fresh books table
            this.onCreate(db);
        }
    }


    private static final String KEY_ID = "id";
    private static final String KEY_COMMENT_TEXT = "KEY_COMMENT_TEXT";

    public void addItem(long phoneID, String comment) {
        Log.d(Constants.LOGGER_TAG, "add saved-offer");
        // 1. get reference to writable DB
        SQLiteDatabase db = this.getWritableDatabase();

        // 2. create ContentValues to add key "column"/value
        ContentValues values = new ContentValues();
        values.put(KEY_ID, phoneID);
        values.put(KEY_COMMENT_TEXT, comment);

        // 3. insert
        long newRowId = db.insertWithOnConflict(COMMENTS_TABLE, KEY_ID, values,
                SQLiteDatabase.CONFLICT_REPLACE);

        // 4. close
        db.close();
    }
}

but i get this error: even after re-installing my app 但我收到此错误:即使重新安装我的应用程序之后

Process: com.example.stopcall.app, PID: 4720
android.database.sqlite.SQLiteException: no such table: COMMENTS_TABLE (code 1): , while compiling: INSERT OR REPLACE  INTO COMMENTS_TABLE(id,KEY_COMMENT_TEXT) VALUES (?,?)
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1113)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:690)
        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:1601)
        at com.example.stopcall.app.dal.CommentDal.addItem(CommentDal.java:69)
        at com.example.stopcall.app.ItemDetailFragment$2.onClick(ItemDetailFragment.java:111)

You have two SQLiteOpenHelper s using the same database name. 您有两个使用相同数据库名称的SQLiteOpenHelper Use only one helper class per database file. 每个数据库文件仅使用一个帮助程序类。

The databse gets set up by one helper and the other helper's lifecycle callbacks won't get invoked since the database is already there. 数据库由一个助手建立,而另一个助手的生命周期回调将不会被调用,因为数据库已经存在。

You have 2 different classes that both extend SQLiteOpenHelper and happen to have the same database name and version. 您有2个不同的类,它们都扩展了SQLiteOpenHelper,并且碰巧具有相同的数据库名称和版本。 But Android doesn't know that. 但是Android不知道这一点。 The first time you access PhoneDal, it creates the database. 首次访问PhoneDal时,它将创建数据库。 When you access CommentDal, Android notes that you already have a database with that name and version, therefore it doesn't call the Comment Dal's onCreate, and the comments table is never created. 当您访问CommentDal时,Android会指出您已经具有该名称和版本的数据库,因此它不会调用Comment Dal的onCreate,并且永远不会创建comment表。

You really should just have one Dal with a couple methods to add a phone and add a comment. 您确实应该只有一个Dal,并提供几种方法来添加电话和添加评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM