如何使用两个不同表SQLite中的元素进行更新/删除

如何使用两个不同表SQLite中的元素进行更新/删除,sqlite,android-studio,sql-update,android-sqlite,sql-delete,Sqlite,Android Studio,Sql Update,Android Sqlite,Sql Delete,我正在编写一个学生成绩提交程序,该程序接受以下输入:学生ID、学生名字、学生姓氏、班级ID、班级名称、成绩分数和字母成绩。为了防止数据冗余,我创建了三个不同的表。然而,当试图从不同的表中“修改”或“删除”具有两个值的条目时,我遇到了一个问题。(例如,删除其中student.id等于student_表中的student.id以及class.id等于class_表中的class.id的位置) 话虽如此,下面是我当前修改学生类的修改代码。我需要修改student.id和class.id的关联方式(它们

我正在编写一个学生成绩提交程序,该程序接受以下输入:学生ID、学生名字、学生姓氏、班级ID、班级名称、成绩分数和字母成绩。为了防止数据冗余,我创建了三个不同的表。然而,当试图从不同的表中“修改”或“删除”具有两个值的条目时,我遇到了一个问题。(例如,删除其中student.id等于student_表中的student.id以及class.id等于class_表中的class.id的位置)

话虽如此,下面是我当前修改学生类的修改代码。我需要修改student.id和class.id的关联方式(它们位于两个不同的表中)

编辑:

以下是我的表格供参考:

db=openOrCreateDatabase("STUDENTGRADES", Context.MODE_PRIVATE, null);
    db.execSQL("CREATE TABLE IF NOT EXISTS STUDENT_TABLE (studentid TEXT, fname TEXT, lname TEXT)");
    db.execSQL("CREATE TABLE IF NOT EXISTS CLASS_TABLE(classid TEXT PRIMARY KEY, classname TEXT UNIQUE)");
    db.execSQL("CREATE TABLE IF NOT EXISTS GRADE_TABLE (studentid TEXT, classid TEXT, pointgrade INTEGER, lettergrade TEXT)");

您不需要至少为一次更改一次更新多个表,例如学生姓名已更改(学生表将更改)或说成绩已更改(更改学生各自的成绩条目)

所以我认为最适合的方法是更新学生的详细信息(名字或姓氏或两者兼有)和改变成绩的方法(或者两者兼有)

至于删除,您可以按顺序从成绩表和学生表中删除,反之亦然

因此,我相信以下代码包括方法
deleteStudentInfo
changeStudentName
changeStudentFirstName
changeStudentLastName
changeStudentGrade
,还包括创建和填充表的示例用法(您可能希望考虑修订的模式):-

public类MainActivity扩展了AppCompatActivity{
公共静态最终字符串DBNAME=“study”;
公共静态最终字符串STUDENT\u TABLE\u NAME=“STUDENT\u TABLE”;
公共静态最终字符串COL\u STUDENT\u ID=“studentid”;
公共静态最终字符串COL\u STUDENT\u FIRSTNAME=“fname”;
公共静态最终字符串COL\u STUDENT\u LASTNAME=“lname”;
公共静态最终字符串CLASS\u TABLE\u NAME=“CLASS\u TABLE”;
公共静态最终字符串COL\u CLASS\u ID=“classid”;
公共静态最终字符串COL\u CLASS\u NAME=“classname”;
公共静态最终字符串GRADE\u TABLE\u NAME=“GRADE\u TABLE”;
公共静态最终字符串COL\u GRADE\u POINTGRADE=“POINTGRADE”;
公共静态最终字符串COL\u GRADE\u LETTERGRADE=“LETTERGRADE”;
公共静态最终字符串BY_STUDENTID=COL_STUDENT_ID+“=?”;
公共静态最终字符串由_CLASSID=COL_CLASS_ID+“=?”;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SQLiteDatabase db=openOrCreateDatabase(DBNAME,Context.MODE_PRIVATE,null);
db.execSQL(“如果不存在创建表”+学生表名称+”(“+
COL_STUDENT_ID+“文本主键,”+
COL_STUDENT_FIRSTNAME+“文本”+
COL_STUDENT_姓氏+“文本)”
);
db.execSQL(“如果不存在创建表”+类表名+”(“+
列类ID+“文本主键,”+
COL_CLASS_NAME+“文本唯一”+
")"
);
db.execSQL(“如果不存在创建表”+等级表名称+”(“+
COL_STUDENT_ID+“文本,”+
列类ID+“文本,”+
COL_GRADE_POINTGRADE+“整数”+
COL_GRADE_LETTERGRADE+“文本”+
")"
);
db.execSQL(“插入或忽略到”+学生表\u名称中+
“价值观”+
('00001','Fred','Smith'),“+
“('00010'、'Mary'、'Thomas'),”+
“('00910'、'Angela'、'Jones')”
);
db.execSQL(“插入或忽略到”+类\u表\u名称中+
“价值观”+
“('001','English'),”+
“(‘101’,‘数学’),”+
“('201','Chemistry')”
);
db.execSQL(“插入或忽略到”+GRADE\u TABLE\u NAME中+
“价值观”+
('00001','001',99,'A'),--弗雷德·史密斯的英语成绩为99分A\n+
('00001'、'101',25,'F'),--弗雷德·史密斯的数学成绩为F,得25分\n+
('00010','201',76,'B'),--Angela Jones 76化学学士\n+
('00910','101',50,'C'),\n+
('00910','201',63,'C'),\n+
('00910','001',89,'A')\n+
";"
);
变更学生姓名(db,“00001”、“Joe”、“Bloggs”);
changeStudentFirstName(db,“00001”,“Harry”);
变更学生姓氏(db,“00001”、“霍夫曼”);
//例如,不会因-1(跳过点等级)和null(跳过字母等级)而改变
changeStudentGrade(db,“00001”、“001”、-1,空);
//两者都改变
变更学生等级(db,“00001”、“001”、25、“D”);
changeStudentGrade(db,“00001”,“001”,27,空);
//Ooops无效的学生id
如果(删除学生信息(db,“001”)){
日志d(“删除”,“学生001删除”);
}否则{
Log.d(“删除”,“Ooops学生001未删除”);
}
//更正学生证
如果(删除学生信息(db,“00001”)){
日志d(“删除”,“学生001删除”);
}否则{
Log.d(“删除”,“Ooops学生001未删除”);
}
}
私有布尔deleteStudentInfo(SQLiteDatabase db,字符串studentid){
String tag=“STUDENT\u DELETE”;
字符串student\u table=“student\u table”;
字符串grade\u table=“grade\u table”;
long pre_delete_student_count=DatabaseUtils.queryNumEntries(db,student_表);
long pre_delete_grade_count=DatabaseUtils.queryNumEntries(db,grade_table);
字符串
db=openOrCreateDatabase("STUDENTGRADES", Context.MODE_PRIVATE, null);
    db.execSQL("CREATE TABLE IF NOT EXISTS STUDENT_TABLE (studentid TEXT, fname TEXT, lname TEXT)");
    db.execSQL("CREATE TABLE IF NOT EXISTS CLASS_TABLE(classid TEXT PRIMARY KEY, classname TEXT UNIQUE)");
    db.execSQL("CREATE TABLE IF NOT EXISTS GRADE_TABLE (studentid TEXT, classid TEXT, pointgrade INTEGER, lettergrade TEXT)");
public class MainActivity extends AppCompatActivity {

    public static final String DBNAME = "study";
    public static final String STUDENT_TABLE_NAME = "STUDENT_TABLE";
    public static final String COL_STUDENT_ID = "studentid";
    public static final String COL_STUDENT_FIRSTNAME = "fname";
    public static final String COL_STUDENT_LASTNAME = "lname";

    public static final String CLASS_TABLE_NAME = "CLASS_TABLE";
    public static final String COL_CLASS_ID = "classid";
    public static final String COL_CLASS_NAME = "classname";

    public static final String GRADE_TABLE_NAME = "GRADE_TABLE";
    public static final String COL_GRADE_POINTGRADE = "pointgrade";
    public static final String COL_GRADE_LETTERGRADE = "lettergrade";
    public static final String BY_STUDENTID = COL_STUDENT_ID + "=?";
    public static final String BY_CLASSID = COL_CLASS_ID + "=?";



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SQLiteDatabase db = openOrCreateDatabase(DBNAME,Context.MODE_PRIVATE,null);
        db.execSQL("CREATE TABLE IF NOT EXISTS " + STUDENT_TABLE_NAME + " (" +
                COL_STUDENT_ID + " TEXT PRIMARY KEY, " +
                COL_STUDENT_FIRSTNAME + " TEXT," +
                COL_STUDENT_LASTNAME + " TEXT)"
        );
        db.execSQL("CREATE TABLE IF NOT EXISTS " + CLASS_TABLE_NAME + "(" +
                 COL_CLASS_ID + " TEXT PRIMARY KEY," +
                 COL_CLASS_NAME + " TEXT UNIQUE " +
                ")"
        );
        db.execSQL("CREATE TABLE IF NOT EXISTS " + GRADE_TABLE_NAME + "(" +
                COL_STUDENT_ID + " TEXT, " +
                COL_CLASS_ID + " TEXT, " +
                COL_GRADE_POINTGRADE + " INTEGER, " +
                COL_GRADE_LETTERGRADE + " TEXT" +
                ")"
        );
        db.execSQL("INSERT OR IGNORE INTO " + STUDENT_TABLE_NAME +
                " VALUES" +
                "('00001','Fred','Smith')," +
                "('00010','Mary','Thomas')," +
                "('00910','Angela','Jones')"
        );
        db.execSQL("INSERT OR IGNORE INTO " + CLASS_TABLE_NAME +
                " VALUES" +
                "('001','English')," +
                "('101','Mathematics')," +
                "('201','Chemistry')"
        );
        db.execSQL("INSERT OR IGNORE INTO " + GRADE_TABLE_NAME +
                " VALUES" +
                "    ('00001','001',99,'A'), -- Fred Smith has 99 point grade as an A in English\n" +
                "    ('00001','101',25,'F'), -- Fred Smith has 25 point grade as an F on Mathematics\n" +
                "    ('00010','201',76,'B'), -- Angela Jones 76 a B in Chemistry\n" +
                "    ('00910','101',50,'C'), \n" +
                "    ('00910','201',63,'C'),\n" +
                "    ('00910','001',89,'A')\n" +
                ";"
        );

        changeStudentName(db,"00001","Joe","Bloggs");
        changeStudentFirstName(db,"00001","Harry");
        changeStudentLastName(db,"00001","Hoffmann");
        // e.g. won't change due to -1 (skip pointsgrade) and null (skip lettergrade)
        changeStudentGrade(db,"00001","001",-1,null);
        // Change both
        changeStudentGrade(db,"00001","001",25,"D");
        changeStudentGrade(db,"00001","001",27,null);

        // Ooops invalid student id
        if (deleteStudentInfo(db,"001")) {
            Log.d("DELETION","Student 001 deleted.");
        } else {
            Log.d("DELETION","Ooops Student 001 not deleted?????");
        }

        // Corrected Student ID
        if (deleteStudentInfo(db,"00001")) {
            Log.d("DELETION","Student 001 deleted.");
        } else {
            Log.d("DELETION","Ooops Student 001 not deleted?????");
        }
    }

    private boolean deleteStudentInfo(SQLiteDatabase db, String studentid) {

        String tag = "STUDENT_DELETE";
        String student_table = "STUDENT_TABLE";
        String grade_table = "GRADE_TABLE";

        long pre_delete_student_count = DatabaseUtils.queryNumEntries(db,student_table);
        long pre_delete_grade_count = DatabaseUtils.queryNumEntries(db,grade_table);

        String whereclause = "studentid =?";
        String[] whereargs = {studentid};

        db.delete(student_table,whereclause,whereargs);
        db.delete(grade_table,whereclause,whereargs);

        long post_delete_student_count = DatabaseUtils.queryNumEntries(db,student_table);
        long post_delete_grade_count = DatabaseUtils.queryNumEntries(db,grade_table);

        Log.d(
                tag,
                "Number of Students deleted from " +
                        student_table + " is " +
                        String.valueOf(
                                pre_delete_student_count - post_delete_student_count
                        ));
        Log.d(
                tag,
                "Number of Grades deleted from " + grade_table + " is " +
                        String.valueOf(
                                pre_delete_grade_count - post_delete_grade_count
                        )
        );
        if ((pre_delete_student_count + pre_delete_grade_count) != (post_delete_student_count + post_delete_grade_count)) {
            return true;
        }
        return false;
    }

    /**
     * Flexible Student Name Change
     *
     * @param db            The SQliteDatabase
     * @param studentid     The studentid (String)
     * @param newfirstname  The new firstname, null or blank to leave as is
     * @param newlastname   the new lastname, null or blank to leave as is
     */
    private void changeStudentName(SQLiteDatabase db, String studentid, String newfirstname, String newlastname ) {

        //Anything to do? if not do nothing
        if ((newfirstname == null || newfirstname.length() < 1) && (newlastname == null || newlastname.length() < 1)) {
            return;
        }
        ContentValues cv = new ContentValues();
        if (newfirstname != null && newfirstname.length() > 0) {
            cv.put(COL_STUDENT_FIRSTNAME,newfirstname);
        }
        if (newlastname != null && newlastname.length() > 0) {
            cv.put(COL_STUDENT_LASTNAME,newlastname);
        }
        // Overcautious check
        if (cv.size() < 1) {
            return;
        }
        db.update(STUDENT_TABLE_NAME,cv,BY_STUDENTID,new String[]{studentid});
    }

    /**
     * Change a Student's First Name (invokes changeStudentName method)
     * @param db            The SQLiteDatabase
     * @param studentid     The student's id (String)
     * @param newfirstname  The new first name to apply
     */
    private void changeStudentFirstName(SQLiteDatabase db, String studentid, String newfirstname) {
        changeStudentName(db,studentid,newfirstname,null);
    }

    /**
     * Change a Student's Last Name (invokes changeStudentName method)
     * @param db
     * @param studentid
     * @param newlastname
     */
    private void changeStudentLastName(SQLiteDatabase db, String studentid, String newlastname) {
        changeStudentName(db,studentid,null,newlastname);
    }

    /**
     * Change a students grade (allowing just one (points/letter))
     * @param db
     * @param studentid
     * @param classid
     * @param newpointsgrade
     * @param newlettergrade
     */
    private void changeStudentGrade(SQLiteDatabase db, String studentid, String classid, int newpointsgrade, String newlettergrade) {
        // Anything to do? if not do nothing
        if (newpointsgrade < 0 && (newlettergrade == null || newlettergrade.length() < 1)) {
            return;
        }
        ContentValues cv = new ContentValues();
        if (newpointsgrade >= 0) {
            cv.put(COL_GRADE_POINTGRADE,newpointsgrade);
        }
        if (newlettergrade != null && newlettergrade.length() > 0) {
            cv.put(COL_GRADE_LETTERGRADE,newlettergrade);
        }
        String whereclause = COL_STUDENT_ID + "=? AND " + COL_CLASS_ID + "=?";
        String[] whereargs = new String[]{studentid,classid};
        db.update(GRADE_TABLE_NAME,cv,whereclause,whereargs);
    }
}