SQLiteのqueryで躓いたって話


はじめに

これは私が初めてのAndroidアプリケーション開発で躓き、その後、解決した方法を備忘録として綴っています。

データベースに追加したい物が既存であるか確認したかった

javaでSQLiteを利用したアプリケーションを作成中に、EditTextに入力されたitemが、既にデータベースに登録していた場合はアラートを表示させ追加しない処理をさせようとしていたがなかなか上手くできなかった。

初めに行ったこと

example.java
String item = editText.getText().toString();
Cursor c = db.query("table", new String[]{"item", "yen"}, "item = " + item, null, null, null, null);

これは調べた先の様々なサイトの内のいくつかに書かれていた方法でした。実際に試してみたところ...

android.database.sqlite.SQLiteException: no such column: リンゴ

といったエラーが表示されてしまいます。

ちなみにカラムって...

それぞれの項目にあたる「列」のこと。

https://26gram.com/database-terms

try-catch文で挑戦

ってことでカラムを知らないし調べようともしなかった私は、try-catch文を利用して、tryで既存なのかを確認。catchでデータベースに追加すれば良くね?って思ったので実際にコードでしてみた。

example.java
String item = editText.getText().toString();
try{
    Cursor c = db.query("table", new String[]{"item", "num"}, "item = " + item, null, null, null, null);
    /*既存の時の処理*/
}catch(Exception e){
    /*データベースに追加する処理*/
}

この結果を実行してみてみると...

item yen
リンゴ 100
リンゴ 100

同じの追加されてるし!!あれれ~おかしぃぞ~...
色々と調べた結果、どうやら"item = " + itemの書き方がいけないようです。(←ここでカラムの意味に気付き無事赤面)

本来の検索方法

example.java
Cursor c = db.query("table", new String[]{"item", "yen"}, "item = ?", new String[]{item}, null, null, null);

と書くことが正解のようです。最初に書いてたコードの方が直感的にわかり...ってことは置いといて書き方もわかったことだし次に進もう!

...としたところで、ここでもう一度躓きました。そのコードがこちら。

example.java
Cursor c = db.query("table", new String[]{"item", "yen"}, "item = ?", new String[]{item}, null, null, null);
if(c.moveToFirst()){
    /*既存の時の処理*/
}else{
    /*データベースに追加する処理*/
}

カーソルを最初の位置に移動できる ⇒ 既に存在する って発想に至ったわけですね。
実際のところ追加されてていようがなかろうが、そんなことに関係なく「正」になるため毎回、既存の処理が実行されてしまいました。

既存かどうか判定する方法

では、既存かどうかを判断するプログラムは、最終的にどのようにして解決させたかというと、

example.java
String item = editText.getText().toString();
Cursor c = db.query("table", new String[]{"item", "yen",}, "item = ?", new String[]{item}, null, null, null);
if(c.getCount() != 0) {
    /*既存の時の処理*/
}else{
    /*データベースに追加する処理*/
}

レコード(行)を数えてくれる機能を持ったメソッドがあったためそれを利用し、
・行数が0でなかった場合は既存の処理
・0行だった場合はデータベースに追加する処理
とすることで、希望通りのプログラムを実装することができました。

余談

"item like ?", new String[]{"%" + item + "%"}とすれば、SQLのlile句を利用し、その言葉が含まれるフィールド(要素)を探すことが出来ます。

最後に

今回の記事はここまでになります。
Androidアプリケーションは今回が初めての挑戦だったため、躓くことも多かったですが、無事作成することができ、普段使用している携帯にインストールさせることが出来ました。
わからないことがあったら調べること。メソッドをよく確認し活用すること。
この2つを自分の座右の銘に追加し、これからもAndroidのアプリケーション開発に挑んでいけたらと思います。
アドバイス、質問等ありましたらコメント欄にてお願い致します。
最後までお付き合い頂きありがとうございました。