1

次のコードのSELECTステートメントに問題があります(これは私のデータベースヘルパークラスにあります)。

public Cursor selectMaxAreaNumber (long inspectionId) { 
String inspectionIdString = String.valueOf(inspectionId); 
String[] tableColumns = new String[] {  
        AREA_NUMBER,  
        "(SELECT max(" + AREA_NUMBER + ") FROM " + AREAS_TABLE + ") AS max"  
    };  
String whereClause = INSPECTION_LINK + " = ?"; 
String[] whereArgs = new String[] { 
        inspectionIdString           
    }; 
Cursor c = rmDb.query(AREAS_TABLE, tableColumns, whereClause, whereArgs,  
        null, null, null); 


if (c != null) { 
    c.moveToFirst(); 
} 
c.close(); 
return c; 

}

次に、これを私の活動で次のように呼びます。

Cursor c = rmDbHelper.selectMaxAreaNumber(inspectionId); 
    startManagingCursor(c); 
    c.moveToFirst(); 
    nextAreaNumber = c.getInt(c.getColumnIndex("max")) + 1;

テーブルから最大数を取得しているため、WHEREステートメントが失敗しているようです。しかし、何が問題なのかわかりません。

この質問の一部として、クエリで使用する前にIDを文字列に変換して正しいことを行っているかどうかを誰かが確認できますか?両方のビットにc.moveToFirst()を書き込む必要がありますか?

よろしくお願いします!

4

2 に答える 2

1

変更してみてください

"(SELECT max(" + AREA_NUMBER + ")FROM" + AREAS_TABLE + ")AS max"

"SELECT max(" + AREA_NUMBER + ")AS max FROM" + AREAS_TABLE

于 2012-09-19T19:44:19.553 に答える
1

代わりにこれを試してください:

public Cursor selectMaxAreaNumber (long inspectionId) { 
    String[] tableColumns = new String[] {  
        "Max(" + AREA_NUMBER + ") AS max"  
    };  
    String whereClause = INSPECTION_LINK + " = ?"; 
    String[] whereArgs = new String[] { 
        String.valueOf(inspectionId); 
    }; 
    return rmDb.query(AREAS_TABLE, tableColumns, whereClause, whereArgs,  
        null, null, null); 
} 

AREA_NUMBERこれにより、適切な。を持つ最大のカーソルが返されますinspectionId

いくつかのメモ:

  • 結果として1行しか得られないような関数を使用する場合、要求する必要はありMax()ません。AREA_NUMBERS Max(AREA_NUMBERS)
  • カーソルは空である可能性がありますが、そうではありませんnull
  • 使用する前にカーソルを閉じないでください

したがって、これは必要ありません。

if (c != null) { 
    c.moveToFirst(); 
} 
c.close(); 

cどういうわけかだった場合nullでも、NullPointerExceptionが発生することを理解してくださいc.close()


(オプション)を削除してwhereArgs、次を使用することができます。

String whereClause = INSPECTION_LINK + " = " + inspectionId;

(データ型であるという理由だけinspectionIdlong、インジェクション攻撃を実行するには文字列が必要です。)


最後に、ここで空のカーソルを確認する必要があります。

Cursor c = rmDbHelper.selectMaxAreaNumber(inspectionId); 
startManagingCursor(c); 
if(c.moveToFirst()) 
    nextAreaNumber = c.getInt(c.getColumnIndex("max")) + 1;
else //empty Cursor, return a default value
    nextAreaNumber = 0;
于 2012-09-19T19:53:24.910 に答える