如何更新Sqlite数据库方法

时间:2017-12-12 21:55:11

标签: android sqlite android-sqlite

尝试更新恰好是外键的表中的列。

我知道它在我使用这些详细信息登录时进入数据库,但它在更新时似乎无效。

以下是我的更新方法,其中包含将ID转换为电子邮件的方法:

    private int getIdFromName(String email) {
        SQLiteDatabase db = this.getWritableDatabase();
        ArrayList<Integer> refs = new ArrayList<>();
        Cursor cursor;

        cursor = db.rawQuery("select " + REFEREE_EMAIL_COL + " from " +
                REF_TABLE + " where " + REFEREE_EMAIL_COL + "='" + email + "'", null);

        while (cursor.moveToNext()){
            refs.add(cursor.getInt(0));
        }

        return refs.get(0);
    }

     public boolean updateRef(String email)
   {
       SQLiteDatabase db = this.getWritableDatabase();
       ContentValues values = new ContentValues();

       int ref_id = getIdFromName(email);

       values.put(REFEREE_ID_COL, ref_id);

       db.update(MATCH_TABLE, values, "REFEREEID = ?", new String[]{email});
       return true;
   }


private Button btnSave,btnDelete;
private EditText homeTeamEdit, awayTeamEdit, typeOfMatchEdit, redCardsEdit, bookingsEdit, groundEdit, refEdit, dateEdit, timeEdit,
        awayScoreEdit, homeScoreEdit;
DBHandler mDatabaseHelper;

private String homeTeam, awayTeam, homeScore, awayScore;
private String typeOfMatch;
private String ref;
private String redCards, bookings;
private String date, time;
private String ground;
private int selectedID;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update_match);
        btnSave = (Button) findViewById(R.id.UpdateMatchButton);
        homeTeamEdit = (EditText) findViewById(R.id.HomeTeamUpdate);
        homeScoreEdit = (EditText) findViewById(R.id.updateHomeScore);
        awayTeamEdit = (EditText) findViewById(R.id.AwayTeamUpdate);
        awayScoreEdit = (EditText) findViewById(R.id.updateAwayScore);
        typeOfMatchEdit = (EditText) findViewById(R.id.updateTypeOfMatch);
        refEdit = (EditText) findViewById(R.id.updateRef);
        groundEdit = (EditText) findViewById(R.id.updateGround);
        refEdit = (EditText) findViewById(R.id.updateRef);

        final String referee = refEdit.getText().toString();

        mDatabaseHelper = new DBHandler(this);


        //get the intent extra from the ListDataActivity
        Intent receivedIntent = getIntent();

        //now get the itemID we passed as an extra
        selectedID = receivedIntent.getIntExtra("MatchId", -1); //NOTE: -1 is just the default value

        //now get the name we passed as an extra
        homeTeam = receivedIntent.getStringExtra("homeTeam");

        homeScore = receivedIntent.getStringExtra("homeScore");

        awayTeam = receivedIntent.getStringExtra("awayTeam");

        awayScore = receivedIntent.getStringExtra("awayScore");

        ground = receivedIntent.getStringExtra("ground");

        typeOfMatch = receivedIntent.getStringExtra("typeOfMatch");


        //set the text to show the current selected name
        homeTeamEdit.setText(homeTeam);
        awayTeamEdit.setText(awayTeam);
        typeOfMatchEdit.setText(typeOfMatch);
        groundEdit.setText(ground);
        homeScoreEdit.setText(homeScore);
        awayScoreEdit.setText(awayScore);

        btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String item = refEdit.getText().toString();
                if(mDatabaseHelper.checkIfRefExists(referee)) {
                    if (!item.equals("")) {
//                    mDatabaseHelper.updateName(referee, selectedID);
                        mDatabaseHelper.updateRef(referee);
                        toastMessage("Ref Updated");
                    } else {
                        toastMessage("You must enter a name");
                    }
                }
                else
                {
                    toastMessage("No ref with that email");
                }
            }
        });
    }

    /**
     * customizable toast
     * @param message
     */
    private void toastMessage(String message){
        Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
    }
}

当我尝试使用ref更新匹配时,它总是会点击该电子邮件中没有引用的toast消息。

我有没有对更新方法做错的事情,还是我完全没有?

UPDATE 以下是我创建的包含列名的表:

    private static final String TAG = "DBHandler";

public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "RefereeDB";
public static final String REF_TABLE = "referee_table";
public static final String MATCH_TABLE = "match_table";
public static final String ADMIN_TABLE = "admin_table";

//REF Tables
public static final String REFEREE_ID_COL = "REFEREEID";
public static final String REFEREE_NAME_COL = "NAME";
public static final String REFEREE_AGE_COL = "AGE";
public static final String REFEREE_PHONENUM_COL = "PHONENUMBER";
public static final String REFEREE_STATUS_COL = "REFEREESTATUS";
public static final String REFEREE_CLUB_COL = "REFCLUB";
public static final String REFEREE_EMAIL_COL = "REFEMAIL";
public static final String REFEREE_PASSWORD_COL = "REFEREEPASSWORD";

//Match Tables
public static final String MATCH_ID_COL = "MATCHID";
public static final String MATCH_HOME_TEAM_COL = "HOMETEAM";
public static final String MATCH_AWAY_TEAM_COL = "AWAYTEAM";
public static final String MATCH_TIME_COL = "MATCHTIME";
public static final String MATCH_DATE_COL = "MATCHDATE";
public static final String MATCH_HOMESCORE_COL = "MATCHHOMESCORE";
public static final String MATCH_AWAYSCORE_COL = "MATCHAWAYSCORE";
public static final String MATCH_TYPEOFMATCH_COL = "TYPEOFMATCH";
public static final String MATCH_GROUND_NAME_COL = "GROUNDNAME";
public static final String MATCH_GROUND_LAT_COL = "GROUNDLAT";
public static final String MATCH_GROUND_LONGITUDE_COL = "GROUNDLONGITUDE";

//Admin Tables
public static final String ADMIN_ID_COL = "ADMINID";
public static final String ADMIN_EMAIL = "ADMINEMAIL";
public static final String ADMIN_PASSWORD = "ADMINPASSWORD";


//Create Tables
public static final String CREATE_TABLE_REF = "CREATE TABLE "
        + REF_TABLE + "(" + REFEREE_ID_COL + " INTEGER PRIMARY KEY AUTOINCREMENT," + REFEREE_NAME_COL + " TEXT," +
        REFEREE_AGE_COL + " INTEGER," + REFEREE_PHONENUM_COL + " TEXT," + REFEREE_STATUS_COL +
        " TEXT," + REFEREE_CLUB_COL + " TEXT," + REFEREE_EMAIL_COL + " TEXT," +
        REFEREE_PASSWORD_COL + " TEXT" + ")";


public static final String CREATE_TABLE_MATCH = "CREATE TABLE "
        + MATCH_TABLE + "(" + MATCH_ID_COL + " INTEGER PRIMARY KEY AUTOINCREMENT," + MATCH_HOME_TEAM_COL +
        " TEXT," + MATCH_AWAY_TEAM_COL + " TEXT," + MATCH_TIME_COL + " TEXT," + MATCH_DATE_COL +
        " DATETIME," + MATCH_HOMESCORE_COL + " TEXT," + MATCH_AWAYSCORE_COL + " TEXT," + MATCH_TYPEOFMATCH_COL +
        " TEXT," + MATCH_GROUND_NAME_COL + " TEXT," + MATCH_GROUND_LONGITUDE_COL + " TEXT," + MATCH_GROUND_LAT_COL + " TEXT, " + REFEREE_ID_COL + " INTEGER," + " FOREIGN KEY (REFEREEID) REFERENCES " + REF_TABLE + " (REFEREEID)" + ")";

public static final String CREATE_TABLE_ADMIN = "CREATE TABLE "
        + ADMIN_TABLE + "(" + ADMIN_ID_COL + " INTEGER PRIMARY KEY AUTOINCREMENT," + ADMIN_EMAIL +
        " TEXT," + ADMIN_PASSWORD + " TEXT" + ")";

2 个答案:

答案 0 :(得分:1)

我认为你刚刚写了一个错字。 您正在选择REFEREE_EMAIL_COL:

   cursor = db.rawQuery("select " + REFEREE_EMAIL_COL + " from " +
            REF_TABLE + " where " + REFEREE_EMAIL_COL + "='" + email + "'", null);

相反,你必须提供一些变量,比如REFEREE_ID_COL和列的名称ID,并使用它。

cursor = db.rawQuery("select " + REFEREE_ID_COL + " from " +
            REF_TABLE + " where " + REFEREE_EMAIL_COL + "='" + email + "'", null);

答案 1 :(得分:0)

getIdFromName方法似乎存在问题,因为它似乎是从传递给方法的字符串中提取整数。

也就是说,假设电子邮件是 fred@email.com 并且是REFEREE_EMAIL_COL中存储的有效电子邮件,则: -

该查询表示创建一个包含单个列的游标,REFEREE_EMAIL_COL所在的REFEREE_EMAIL_COL fred@email.com

因此,生成的Cursor将包含一行,其中一列的值为 fred@email.com

因此,行refs.add(cursor.getInt(0));将尝试根据游标列偏移0(唯一列)的内容获取一个整数,其中包含值 fred@email.com 。由于getInt方法友好/善良,这将返回0(请参阅the example - For String myTEXT = "The Lazy Quick Brown Fox Jumped Over the Fence or something like that."; here)。

因此,除非电子邮件传递给方法,实际上是id并且是一个转换为字符串的整数,也是想要的id,getIdFromName方法将返回0.否则你将获得id的id通过,这将是浪费时间。

注意! fred@email.com只是假设使用。

调试代码以检查上述情况是否正确。

以下代码可用于确定上述情况是否属实: -

private int getIdFromName(String email) {
    SQLiteDatabase db = this.getWritableDatabase();
    ArrayList<Integer> refs = new ArrayList<>();
    Cursor cursor;

    cursor = db.rawQuery("select " + REFEREE_EMAIL_COL + " from " +
            REF_TABLE + " where " + REFEREE_EMAIL_COL + "='" + email + "'", null);

    Log.d("CURSOR COUNT","The number of rows in the Cursor is " + Integer.toString(ccursor.getCount()));
    while (cursor.moveToNext()){
        Log.d("ID EXTRACTED","The extracted ID is " + Integer.toString(cursor.getInt(0))); // <<<<<<<< added 
        refs.add(cursor.getInt(0));
    }
    return refs.get(0);
}

日志包含,   - a)具有符合选择标准的行数的行。

  • b)如果一行包含字符串,根据变量email,在REFEREE_EMAIL_COL列中,包含提取的ID的行(如果有多行,则为行)。如果 0 ,则可能是上述原因。

潜在的修复: -

假设该表未使用WITHOUT ROWID创建,则以下内容可能有效: -

cursor = db.rawQuery("select " + rowid + " from " +
                REF_TABLE + " where " + REFEREE_EMAIL_COL + "='" + email + "'", null);

A little about rowid here

在这种情况下, rowid 将是游标中的唯一一列,它将被转换为一个整数(真的应该使用getLong,因为它很长,然后很长时间返回随后使用)。

请注意!您的问题中没有可用的信息,例如实际的列名,限制了可以给出的答案。

关于您的评论

  

这对我的朋友不起作用。它必须与我的相关   更新方法!

更新方法取决于getIdFromName方法返回的值。 0 ,假设您使用的是标准ID列,例如?? INTEGER PRIMARY KEY?? INTEGER PRIMARY KEY AUTOINCREMENT,哪里?是列名(rowid的别名),不是一行。 Id从1开始(除非你强迫它)。如果您确实有一个rowid的别名列,那么您可以在上面的修复中使用该列名而不是 rowid

在表格结构后编辑

之前的答案适用,它只能部分解决问题,因此getIdFromName可能是: -

private long getIdFromName(String email) {
    long rv = -1; //default return value -1 indicates no referee
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery("select " + REFEREE_ID_COL + " from " +
            REF_TABLE + " where " + REFEREE_EMAIL_COL + "='" + email + "'", null);
    if (cursor.moveToFirst()) {
        rv = cursor.getLong(csr.getColumnIndex(REFEREE_ID_COL));
    }
    cursor.close();
    return rv;
}

**`getIdFromName`** will now return a **long** rather than an **int**, there is no need for the Integer Array as you only return a long (was int). If the email passed does not result in a referee being found then the value returned will be -1. The Cursor is also closed to reduce the potential for problems if there are too many open Cursors. You will note that the hard coded offset of 0, has been replaced with csr.getColumnIndex(column_name), this gets the offset based upon the column name it is more felxible and less prone to errors.

updateRef 方法也存在问题。这看起来好像它的目的是用裁判的id更新当前的比赛。

然而,它正在做的是尝试更新比赛的裁判ID,裁判ID与裁判ID相同。最终结果是没有任何东西得到更新。

  

e.g。假设您的匹配ID为10,则当前已通过电子邮件发送参考号   fred@email.com,id为200。

     

getIdFromName正确返回200。

     

您的代码说: -

     

更新匹配表以将裁判ID更改为200所在的位置   裁判员身份证是200.应该说的是更新比赛表   将裁判ID更改为200,匹配ID为10。

     

你们对所有有裁判的比赛都没有任何效果   200。

需要的是当前匹配,以便可以使用裁判更新该特定匹配,因此需要将两个参数传递给 updateRef 方法,例如: -

    public boolean updateRef(String email, long matchid) {
       long ref_id = -1;
       int updates_done = 0;
       SQLiteDatabase db = this.getWritableDatabase();
       ContentValues values = new ContentValues();

       // Get the referee's id
       ref_id = getIdFromName(email);
       // if the referee exists then try to update the match
       if (ref_id > 0) {
           values.put(REFEREE_ID_COL,ref_id);
           updates_done = db.update(
               MATCH_TABLE, 
               values, 
               MATCH_ID_COL + "=?",
               new String[]{Long.toString(matchid)}
           );
           return updates_done > 0;
       }
       return false;
   }

然后需要稍微更改才能传递匹配ID,例如: -

        mDatabaseHelper.updateRef(referee);

应更改为: -

        mDatabaseHelper.updateRef(referee, (long) selectedID);

理想情况下,你应该总是使用long作为id,因为id最高可达9223372036854775807.

请注意!再次,代码尚未检查,因此可能有一些错误。