我试图与用户登录的应用程序。我创建了两个表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;
}
}
一种方法可以纳入一个外键(不,你将需要把外键的处理上,因为它默认是关闭的)。
基本上是一个外键引入了一个约束说,如果这个值被应用到子存在于父孩子只能添加。
子和父是一个表/列(或列)的组合。
正如你说的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项,这可能是不可取的。
这凸显了一个潜在的问题,你基本上看在你可能会专注于从视场的角度观看结构的错误的方式架构/结构。
有人建议,用户的单一方面,他们的名字,他们的ID,他们的电子邮件等所属的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,'[email protected]','fredismypassword','UserFred'),
(2,'[email protected]','maryismypassword','UserMary'),
(3,'[email protected]','sureismypassword','UserSue')
;
INSERT INTO user_reg VALUES
(1,'English'),(1,'Woodwork'),(1,'Chemistry'),
(2,'Geography'),
(3,'Chemistry')
;
作为一个例子的查询可以是: -
SELECT * FROM user_reg JOIN user_info ON user_reg.studentid = user_info.studentid ORDER BY course;
这将导致: -
试图添加不存在的学生如使用: -
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电子复制),则该码可以是
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","[email protected]","fredpassword"); //<<<<<<<<<< will return 1 as this will be the generated value (first run only)
mDBHlpr.addUserInfo("Mary","[email protected]","marypassword");
mDBHlpr.addUserInfo("Sue","[email protected]","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 = [email protected]
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 = [email protected]
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 = [email protected]
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 = [email protected]
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 = [email protected]
Student password = fredpassword
Enrolled in Course Wooodwork