【问题标题】:cannot insert a record with a foreign key (android sqlite)无法插入带有外键的记录(android sqlite)
【发布时间】:2014-12-27 12:46:29
【问题描述】:

我有两张桌子。一个带有主键,另一个带有第一个表的外键。

我尝试将项目添加到第一个项目,然后将项目添加到第二个项目。

我的片段代码:

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

电话号码:

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;
    }

评论达尔:

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();
    }
}

但我收到此错误: 即使重新安装了我的应用程序

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)

【问题讨论】:

  • 您能告诉我们您的 cmets 表的确切名称吗?

标签: java android mysql database sqlite


【解决方案1】:

您有 2 个不同的类,它们都扩展了 SQLiteOpenHelper 并且恰好具有相同的数据库名称和版本。但安卓不知道这一点。第一次访问 PhoneDal 时,它会创建数据库。当您访问 CommentDal 时,Android 会注意到您已经有一个具有该名称和版本的数据库,因此它不会调用 Comment Dal 的 onCreate,并且永远不会创建 cmets 表。

你真的应该只有一个 Dal 和几种方法来添加电话和添加评论。

【讨论】:

    【解决方案2】:

    您有两个SQLiteOpenHelpers 使用相同的数据库名称。每个数据库文件只使用一个帮助类。

    数据库由一个助手设置,而另一个助手的生命周期回调将不会被调用,因为数据库已经存在。

    【讨论】:

      猜你喜欢
      • 2013-05-14
      • 1970-01-01
      • 2018-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-19
      相关资源
      最近更新 更多