简体   繁体   中英

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:

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. 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. But Android doesn't know that. The first time you access PhoneDal, it creates the database. 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.

You really should just have one Dal with a couple methods to add a phone and add a comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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