如何检查DB中是否没有相同的行?

时间:2018-06-11 08:10:30

标签: android sqlite android-sqlite

我的SQLite数据库中有两个方法,我检查表格中是否有某个列与String相同,之后我打印同一行上的所有其他列并且使用第二种方法,我检查第一种方法中的列是否等于存储在另一个表的列中的数据。

但是当我检查数据库中没有的数据时,我遇到了问题:

TABLE CODART_BARCODE

CODART_CODART     CODART_BARCODE    CODART_PXC
      123              1234             1

TABLE CODART_ART

 DESCR_ART           PVEN_ART            PACQ_ART     CODART_ART
   PIZZ                1.50                12              123

因此,如果在EditText中我插入123等于CODART_CODART并且另一个表中的CODART_ART中还有123,我将打印“PIZZ 1.50 12”,但如果我在EditText 12356中插入,则应用程序崩溃,因为没有相同的DB中的数据如何防止该应用程序崩溃?我的意思是,如果没有相同的数据我可以制作一个说“没有数据”或类似的东西,但不会让应用程序崩溃吗?

以下是DB中的两种方法:

        public String dbRawSearch(String id) {
            StringBuilder dbString = new StringBuilder();
            SQLiteDatabase db = this.getWritableDatabase();
            String query = "SELECT * FROM " + TABLE_CODART + " WHERE CODART_BARCODE = " + id;
            //Cursor points to a location in your results
            @SuppressLint("Recycle") Cursor c = db.rawQuery(query, null);
            //Move to the first row in your results
            c.moveToFirst();
            //Position after the last row means the end of the results
            while (!c.isAfterLast()) {
                if (c.getString(c.getColumnIndex("CODART_BARCODE")) != null) {
                    dbString.append(c.getString(c.getColumnIndex("CODART_CODART"))).append("\n");
                    dbString.append(c.getString(c.getColumnIndex("CODART_BARCODE"))).append("\n");
                    dbString.append(c.getString(c.getColumnIndex("CODART_PXC"))).append("\n");
                }
                c.moveToNext();
            }
            db.close();
            return dbString.toString();
        }


        // FETCH codArt from Articoli

public String dbRawArticoli(String id){
        StringBuilder dbString = new StringBuilder();
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_ART + " WHERE CODART_ART = " + id;
        Cursor c = db.rawQuery(query, null);
        c.moveToFirst();

    while (!c.isAfterLast()) {
        if (c.getString(c.getColumnIndex("CODART_ART")) != null) {
            dbString.append(c.getString(c.getColumnIndex("DESCR_ART"))).append("\n");
            dbString.append(c.getString(c.getColumnIndex("PVEN_ART"))).append("\n");
            dbString.append(c.getString(c.getColumnIndex("PACQ_ART"))).append("\n");
        }
        c.moveToNext();
    }
    db.close();
    return dbString.toString();

}

3 个答案:

答案 0 :(得分:1)

您的问题是您未正确封闭搜索参数,因此如果该值不是数字,则SQLite会认为您正在比较列,因此找不到列。

假设您使用: -

 String result1 = yourdbHelper.dbRawSearch("123");

然后生成的SQL将是: -

 SELECT * FROM CODART WHERE CODART_BARCODE = 123;

这很好,因为搜索正在寻找一个数字。

但是如果您使用: -

 String result1 = yourdbHelper.dbRawSearch("Fred");

然后生成的SQL将是: -

 SELECT * FROM CODART WHERE CODART_BARCODE = FRED

这会失败,因为FRED是非数字的,因此被解释为说 选择表CODART中的所有列,其中名为COADRT的列与名为FRED的列具有相同的值 ,没有名为FRED的列。

结果是你得到一个错误: -

06-11 11:34:12.653 1373-1373/soanswers.soanswers E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{soanswers.soanswers/soanswers.soanswers.MainActivity}: android.database.sqlite.SQLiteException: no such column: FRED (code 1): , while compiling: SELECT * FROM CODART WHERE CODART_BARCODE = FRED
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)

修复

解决方案很简单,就是用单引号括起要搜索的参数,这样SQL就是: -

SELECT * FROM CODART WHERE CODART_BARCODE = 'FRED'
  • 请注意,这只是一个例子。但是,您需要对两个方法(dbRawSearch和dbRawArticoli)进行类似的更改,如下所示: -

为此,您可以更改: -

String query = "SELECT * FROM " + TABLE_CODART + " WHERE CODART_BARCODE = " + id;

来: -

String query = "SELECT * FROM " + TABLE_CODART + " WHERE CODART_BARCODE = '" + id + "'";

并且还要改变: -

String query = "SELECT * FROM " + TABLE_ART + " WHERE CODART_ART = " + id;

来: -

String query = "SELECT * FROM " + TABLE_ART + " WHERE CODART_ART = '" + id + "'";

其他

但是,有一些SQLiteDatabase便捷方法可以简化构建查询,这些查询也会相应地封装/转换数据。

其中一种是query方法(如下所示)。

而不是

  1. 移至第一行然后
  2. 检查您是否在最后一行然后
  3. 使用moveToNext然后返回2
  4. 在do while循环中,因为所有Cursor move???方法都返回

    • 如果可以移动,则为
    • 否则为假

    您可以使用以下方式简化问题: -

    while(yourcursor.moveToNext) {
       .... process the current row
    }
    

    因此可以考虑以下方法

    • 请注意方法名称末尾的 2 只是为了区别于原件

    : -

    public String dbRawSearch2(String id) {
        StringBuilder dbString = new StringBuilder();
        String whereclause = "CODART_BARCODE=?";
        String[] whereargs = new String[]{id};
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor c = db.query(TABLE_CODART,null,whereclause,whereargs,null,null,null);
        while (c.moveToNext()) {
            dbString.append(c.getString(c.getColumnIndex("CODART_CODART"))).append("\n");
            dbString.append(c.getString(c.getColumnIndex("CODART_BARCODE"))).append("\n");
            dbString.append(c.getString(c.getColumnIndex("CODART_PXC"))).append("\n");
        }
        c.close(); //<<<< Should always close cursors when finished with them
        db.close();
        return dbString.toString();
    }
    
    public String dbRawArticoli2(String id) {
        StringBuilder dbString = new StringBuilder();
        String whereclause = "CODART_ART=?";
        String[] whereargs = new String[]{id};
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor c= db.query(TABLE_ART,null,whereclause,whereargs,null,null,null);
        while (c.moveToNext()) {
            dbString.append(c.getString(c.getColumnIndex("DESCR_ART"))).append("\n");
            dbString.append(c.getString(c.getColumnIndex("PVEN_ART"))).append("\n");
            dbString.append(c.getString(c.getColumnIndex("PACQ_ART"))).append("\n");
        }
        c.close();
        db.close();
        return dbString.toString();
    }
    

答案 1 :(得分:0)

你应该使用光标是否为空及其大小

if (c != null) {
    if (c.getCount() > 0) {
       return "your string";         
    }
}
return "";// In case no record found

在空白案例中,向最终用户提供适当的消息。

答案 2 :(得分:0)

Change this part :
//Move to the first row in your results
            c.moveToFirst();
            //Position after the last row means the end of the results
            while (!c.isAfterLast()) {
                if (c.getString(c.getColumnIndex("CODART_BARCODE")) != null) {
                    dbString.append(c.getString(c.getColumnIndex("CODART_CODART"))).append("\n");
                    dbString.append(c.getString(c.getColumnIndex("CODART_BARCODE"))).append("\n");
                    dbString.append(c.getString(c.getColumnIndex("CODART_PXC"))).append("\n");
                }
                c.moveToNext();
            }

To :
//Move to the first row in your results
            if(c!= null && c.moveToFirst())
{
            //Position after the last row means the end of the results
            while (!c.isAfterLast()) {
                if (c.getString(c.getColumnIndex("CODART_BARCODE")) != null) {
                    dbString.append(c.getString(c.getColumnIndex("CODART_CODART"))).append("\n");
                    dbString.append(c.getString(c.getColumnIndex("CODART_BARCODE"))).append("\n");
                    dbString.append(c.getString(c.getColumnIndex("CODART_PXC"))).append("\n");
                }
                c.moveToNext();
            }
}

Explanation: In the case where there is no same data available you don't have the result set to get the string or column index from the result set.