首页 > 解决方案 > 从选择插入房间

问题描述

我想将表 program_day_exercise 中的值插入到表 training_exercise 中。所以我写了这个查询:

@Query("""
    INSERT INTO training_exercise
    SELECT 0, :trainingId, exercise_id, num, measure_weight, measure_reps, measure_time, measure_distance
    FROM program_day_exercise
    WHERE program_day_id = :programDayId
""")
fun fillTrainingWithProgramExercises(trainingId: Long, programDayId: Long)

它可以编译,但有一个关于 UNIQUE 约束的运行时错误:

02-23 13:31:12.618 11881-12003/com.dmitrysimakov.kilogram E/SQLiteLog: (1555) abort at 34 in [INSERT INTO training_exercise
        SELECT 0, ?, exercise_id, num, measure_weight, measure_reps, measure_time, measure_distance
        FROM program_day_exercise
        WHERE program_day_id 
02-23 13:31:12.618 11881-12003/com.dmitrysimakov.kilogram E/AndroidRuntime: 
FATAL EXCEPTION: pool-4-thread-1
Process: com.dmitrysimakov.kilogram, PID: 11881
android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: training_exercise._id

然后我以其他方式编写了此查询:

@Query("""
    INSERT INTO training_exercise (training_id, exercise_id, num, measure_weight, measure_reps, measure_time, measure_distance)
    SELECT :trainingId, exercise_id, num, measure_weight, measure_reps, measure_time, measure_distance
    FROM program_day_exercise
    WHERE program_day_id = :programDayId
""")
fun fillTrainingWithProgramExercises(trainingId: Long, programDayId: Long)

它工作正常。但是 SQLite 插件无法解析括号中的参数。

问题

我在方法之前添加了@Suppress("AndroidUnresolvedRoomSqlReference"),但我想知道为什么插件认为这是一个错误。


我的实体

@Entity(tableName = "training_exercise",
    foreignKeys = [
        ForeignKey(
                entity = Training::class,
                parentColumns = ["_id"],
                childColumns = ["training_id"],
                onDelete = ForeignKey.CASCADE),
        ForeignKey(
                entity = Exercise::class,
                parentColumns = ["_id"],
                childColumns = ["exercise_id"],
                onDelete = ForeignKey.CASCADE)
])
data class TrainingExercise(
    @PrimaryKey(autoGenerate = true) override val _id: Long = 0,
    val training_id: Long,
    val exercise_id: Long,
    val num: Byte,
    @Embedded(prefix = "measure_") val measures: ExerciseMeasures = ExerciseMeasures()
)

@Entity(tableName = "program_day_exercise",
    foreignKeys = [
ForeignKey(
        entity = ProgramDay::class,
        parentColumns = ["_id"],
        childColumns = ["program_day_id"],
        onDelete = ForeignKey.CASCADE),
ForeignKey(
        entity = Exercise::class,
        parentColumns = ["_id"],
        childColumns = ["exercise_id"],
        onDelete = ForeignKey.CASCADE)
])
data class ProgramDayExercise(
    @PrimaryKey(autoGenerate = true) override val _id: Long = 0,
    val program_day_id: Long,
    val exercise_id: Long,
    val num: Byte,
    val strategy: String? = null,
    @Embedded(prefix = "measure_") val measures: ExerciseMeasures = ExerciseMeasures()
)

标签: androidsqliteandroid-room

解决方案


在您的第一个查询中,您选择第一行并将其插入回数据库中。如果该id字段是唯一的或主键,这将失败,因为显然您不能插入重复的记录。

查看我们看到的错误消息training_exercise._id。您确定该属性 istraining_id和 not idor_id吗?


推荐阅读