Пользовательская функция таблицы Sqlite - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь сделать заявку с логином пользователя.Я создал две таблицы user_reg и user_info.Первый пустой со столбцами идентификатора студента, адреса электронной почты и пароля.Вторая таблица имеет три столбца: имя пользователя, идентификатор студента, курс, в каждом из которых уже есть 10 значений, которые я уже добавил.Я пытаюсь написать функцию, чтобы значения вставлялись в первую таблицу только тогда, когда введенный идентификатор студента совпадает с любым из идентификаторов учащихся из второй таблицы.Я использовал необработанный запрос в курсоре для выбора идентификатора студента из второй таблицы.И второй курсор для получения пользователем вставленного студенческого идентификатора.И затем, если цикл, чтобы увидеть, если результат соответствует.Я думаю, что это неправильно.Как правильно это сделать?

Это мой код для создания таблицы и вставки значений.Я знаю, что это неправильно, я, вероятно, должен использовать цикл для запроса таблицы информации пользователя.Буду признателен за любую помощь в том, как сделать это правильно.

public static final String SQL_TABLE_USERS = " CREATE TABLE " + TABLE_USERS
            + " ( "
            + KEY_ID + " INTEGER PRIMARY KEY, "
            + KEY_EMAIL + " TEXT, "
            + KEY_SID + " INTEGER, "
            + KEY_PASSWORD + " TEXT"
            + " ) ";

    //SQL for creating user info table
    public static final String SQL_TABLE_USERINFO = " CREATE TABLE " + TABLE_USERINFO
            + " ( "
            + KEY_ID + "INTEGER PRIMARY KEY, "
            + KEY_SID + " INTEGER, "
            + KEY_NAME + "TEXT, "
            + KEY_COURSE + " TEXT "
            + " ) ";


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

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        //Create Table when oncreate gets called
        sqLiteDatabase.execSQL(SQL_TABLE_USERS);
        sqLiteDatabase.execSQL(SQL_TABLE_USERINFO);
        sqLiteDatabase.execSQL("INSERT INTO TABLE_USERINFO VALUES('01','45207160010','Mary James','TYBSCIT')");
        sqLiteDatabase.execSQL("INSERT INTO TABLE_USERINFO VALUES('02','45207160020','Amelia John','FYBCOM')"); ```


And this is my function for matching student id:-
public boolean isSIDmatches(String sid) {
        SQLiteDatabase db = this.getReadableDatabase();
        String sidmatch = "SELECT KEY_SID FROM TABLE_USERINFO";
        Cursor cursor = db.rawQuery(sidmatch, new String[]{""});
        Cursor cursor1 = db.query(TABLE_USERS,// Selecting Table
                new String[]{KEY_ID, KEY_EMAIL, KEY_SID, KEY_PASSWORD},//Selecting columns want to query
                KEY_SID + "=?",
                new String[]{sid},//Where clause
                null, null, null);
        if (cursor != null && cursor.moveToFirst()&& cursor.getCount()>0 && cursor==cursor1) {
            return true;
        }
        else {
            return false;
        }
    }




1 Ответ

0 голосов
/ 03 февраля 2019

Одним из способов может быть включение внешнего ключа (не то, что вам нужно будет включать обработку внешнего ключа, так как он выключен по умолчанию).

В основном внешний ключ вводитограничение, которое говорит, что дочерний элемент может быть добавлен, только если значение, применяемое к дочернему элементу, существует в родительском элементе.

Дочерний и родительский элемент представляют собой комбинацию таблицы / столбца (или столбцов).

Поскольку вы говорите, что значение в таблице user_info должно существовать в таблице user_reg, то user_reg будет родительским, а user_info - дочерним в столбце, имя которого равно studentid.

Таким образом, вы можете определить внешний ключиспользуя: -

CREATE TABLE IF NOT EXISTS user_info (studentid INTEGER PRIMARY KEY REFERENCES user_reg(studentid), email TEXT, password TEXT);
  • Обратите внимание, предполагается, что у студента будет только один студент

Однако, поскольку внешний ключ должен указывать на уникальную строкув родителе это ограничит таблицу user_reg наличием только 1 записи на каждого учащегося, что, вероятно, нежелательно.

Это подчеркивает основную проблему, вы в основномЕсли вы смотрите на схему / структуру не так, чтобы вы могли сосредоточиться на рассмотрении структуры с точки зрения курса.

Предполагается, что отдельные аспекты пользователя, его имя,их идентификатор, адрес электронной почты и т. д. принадлежат таблице user_info, в которой имеется по одной строке на каждого учащегося, и что таблица user_reg (регистрация в курсе) должна рассматриваться как курс или курсы, в которых зарегистрирован учащийся, и как таковой, что один студентможет быть зарегистрировано много раз (в отдельных курсах), и, таким образом, это должен быть ребенок, а user_info должен быть родителем.

Возможно, вам следует использовать: -

CREATE TABLE IF NOT EXISTS user_info (studentid INTEGER PRIMARY KEY, email TEXT, password TEXT, username TEXT);
CREATE TABLE IF NOT EXISTS user_reg (studentid INTEGER REFERENCES user_info, course TEXT);

Затем вы сначала добавите студента в таблицу user_info, а затем добавите студента в курс / курсы, например: -

INSERT INTO user_info VALUES
    (1,'Fred@email.mail','fredismypassword','UserFred'),
    (2,'Mary@email.mail','maryismypassword','UserMary'),
    (3,'Sue@email.mail','sureismypassword','UserSue')
;

INSERT INTO user_reg VALUES
    (1,'English'),(1,'Woodwork'),(1,'Chemistry'),
    (2,'Geography'),
    (3,'Chemistry')
;
  • Таким образом, Фред зарегистрирован на 3 курса, Мэри и Сьюпо одному на каждый

Например, запрос может быть: -

SELECT * FROM user_reg JOIN user_info ON user_reg.studentid = user_info.studentid ORDER BY course;

Это приведет к: -

enter image description here

Попытка добавить несуществующего студента, например, с помощью: -

INSERT INTO user_reg VALUES (10,'English') -- Oooops no such student ID

Результатом будет

INSERT INTO user_reg VALUES (10,'English') -- Oooops no such student ID
> FOREIGN KEY constraint failed

ПримерИспользуя Android

Собрав все вместе (повторяя вышеупомянутое на Android), вы получите код:

StudentDBHelper.java (Помощник по базам данных)

public class StudentDBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "studentdb";
    public static final int DBVERSION = 1;
    public static final String TBl_USERINFO = "user_info";
    public static final String TBL_USERREG = "user_reg";

    public static final String COL_USERINFO_STUDENTID = "student_id";
    public static final String COL_USERINFO_USERNAME = "username";
    public static final String COL_USERINFO_EMAIL = "email";
    public static final String COL_USERINFO_PASSWORD = "password";

    public static final String COL_USERREG_STUDENT_ID = "student_id";
    public static final String COL_USERREG_COURSE = "course";

    private final String crtUserInfo = "CREATE TABLE IF NOT EXISTS " + TBl_USERINFO + "(" +
            COL_USERINFO_STUDENTID + " INTEGER PRIMARY KEY, " +
            COL_USERINFO_USERNAME + " TEXT, " +
            COL_USERINFO_EMAIL + " TEXT," +
            COL_USERINFO_PASSWORD + " TEXT" +
            ")";

    private final String drpUerInfo = "DROP TABLE IF EXISTS " + TBl_USERINFO;

    private final String crtUserReg = "CREATE TABLE IF NOT EXISTS " + TBL_USERREG + "(" +
            COL_USERREG_STUDENT_ID + " INTEGER REFERENCES " + TBl_USERINFO + "(" + COL_USERINFO_STUDENTID + ")," +
            COL_USERREG_COURSE + " TEXT " +
            ")";

    private final String drpUserReg = " DROP TABLE If EXISTS " + TBL_USERREG;

    SQLiteDatabase mDB;



    public StudentDBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase(); //<<<<<<<<<< will force create when constructing if DB doesn't exist
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(crtUserInfo);
        db.execSQL(crtUserReg);
    }

    @Override
    public void onConfigure(SQLiteDatabase db) {
        super.onConfigure(db);
        db.setForeignKeyConstraintsEnabled(true); //<<<<<<<<<< TURN ON FOREIGN KEY HANDLING
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(drpUserReg); //<<<<<<<<<< must be done before UserInfo
        db.execSQL(drpUerInfo);
    }

    public long addUserInfo(String userName, String email, String password) {
        ContentValues cv = new ContentValues();
        cv.put(COL_USERINFO_USERNAME,userName);
        cv.put(COL_USERINFO_EMAIL,email);
        cv.put(COL_USERINFO_PASSWORD,password);
        return mDB.insert(TBl_USERINFO,null,cv);
    }

    public long addUserReg(long studentId, String course) {
        ContentValues cv = new ContentValues();
        cv.put(COL_USERREG_STUDENT_ID,studentId);
        cv.put(COL_USERREG_COURSE,course);
        return mDB.insert(TBL_USERREG,null,cv);
    }

    public void logStudentsInCourses() {
        String tbl = TBL_USERREG +
                " JOIN " + TBl_USERINFO + " ON " +
                TBl_USERINFO + "." + COL_USERINFO_STUDENTID +
                " = " +
                TBL_USERREG + "." + COL_USERREG_STUDENT_ID;
        Cursor csr = mDB.query(tbl,null,null,null,null,null,COL_USERREG_COURSE);
        while (csr.moveToNext()) {
            Log.d(
                    "DBINFO",
                    "Row " + String.valueOf(csr.getPosition() + 1) +
                            "\n\t Student UserName = " + csr.getString(csr.getColumnIndex(COL_USERINFO_USERNAME)) +
                            "\n\tStudent Email = " + csr.getString(csr.getColumnIndex(COL_USERINFO_EMAIL)) +
                            "\n\tStudent password = " + csr.getString(csr.getColumnIndex(COL_USERINFO_PASSWORD)) +
                            "\n\tEnrolled in Course " + csr.getString(csr.getColumnIndex(COL_USERREG_COURSE))
            );
        }
    }
}

##MainActivity.java (вызывающее действие)

public class MainActivity extends AppCompatActivity {

    StudentDBHelper mDBHlpr;
    Context mContext;

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

        mDBHlpr = new StudentDBHelper(this);

        mDBHlpr.addUserInfo("Fred","fred@email.com","fredpassword"); //<<<<<<<<<< will return 1 as this will be the generated value (first run only)
        mDBHlpr.addUserInfo("Mary","mary@email.com","marypassword");
        mDBHlpr.addUserInfo("Sue","sue@email.com","suepassword");

        mDBHlpr.addUserReg(1,"English"); 
        mDBHlpr.addUserReg(1,"Wooodwork");
        mDBHlpr.addUserReg(1,"Chemistry");
        mDBHlpr.addUserReg(2,"Geography");
        mDBHlpr.addUserReg(3,"Chemistry");
        mDBHlpr.addUserReg(10,"Chemistry"); //<<<<<<<<< Ooops won't insert return will be -1
        mDBHlpr.logStudentsInCourses();
    }
}
  • Обратите внимание, что приведенное выше предназначено для запуска только один раз

Результат

Выше, когдапри первом запуске выдает следующее в журнал: -

2019-02-03 13:57:09.829 15640-15640/so.cdfa E/SQLiteDatabase: Error inserting student_id=10 course=Chemistry
    android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1564)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1433)
        at so.cdfa.StudentDBHelper.addUserReg(StudentDBHelper.java:80)
        at so.cdfa.MainActivity.onCreate(MainActivity.java:37)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2019-02-03 13:57:09.831 15640-15640/so.cdfa D/DBINFO: Row 1
         Student UserName = Fred
        Student Email = fred@email.com
        Student password = fredpassword
        Enrolled in Course Chemistry
2019-02-03 13:57:09.831 15640-15640/so.cdfa D/DBINFO: Row 2
         Student UserName = Sue
        Student Email = sue@email.com
        Student password = suepassword
        Enrolled in Course Chemistry
2019-02-03 13:57:09.831 15640-15640/so.cdfa D/DBINFO: Row 3
         Student UserName = Fred
        Student Email = fred@email.com
        Student password = fredpassword
        Enrolled in Course English
2019-02-03 13:57:09.831 15640-15640/so.cdfa D/DBINFO: Row 4
         Student UserName = Mary
        Student Email = mary@email.com
        Student password = marypassword
        Enrolled in Course Geography
2019-02-03 13:57:09.831 15640-15640/so.cdfa D/DBINFO: Row 5
         Student UserName = Fred
        Student Email = fred@email.com
        Student password = fredpassword
        Enrolled in Course Wooodwork
  • Обратите внимание, что исключение не является временем выполнения / фатальным исключением и не останавливает обработку, оно просто сообщает об ошибке вставкииз-за конфликта внешнего ключа.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...