質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

2回答

16205閲覧

SQLiteException: no such table (code1)の解決方法がわからない。

Velonica

総合スコア35

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2016/07/26 13:11

###前提・実現したいこと
Androidで資材管理をするアプリを開発しています。
アプリ内ですでに作成したSQLiteのDatabaseを利用して、資材の一覧をExpandableListViewで実装しようと考えています。
###発生している問題・エラーメッセージ
ExpandableListViewChildData.classの11行目のqueryメソッドにおいて、すでに作成したDatabaseを読み込んで、SELECT文を実行しようとするとSQLiteException: no such table: Name(code1)というエラーが発生。

###該当のソースコード

Java

1 2public class DBOpenHelper extends SQLiteOpenHelper { 3 private static final String DB_FILE_NAME = "HAVI.db"; 4 private static final String DB_NAME = "HAVI"; 5 private static final int DB_VERSION = 1; 6 7 private Context context; 8 private File dbPath; 9 private boolean createDatabase = false; 10 11 public DBOpenHelper(Context context) { 12 super(context, DB_NAME, null, DB_VERSION); 13 this.context = context; 14 this.dbPath = context.getDatabasePath(DB_NAME); 15 } 16 17 @Override 18 public synchronized SQLiteDatabase getReadableDatabase() { 19 SQLiteDatabase database = super.getReadableDatabase(); 20 if(createDatabase) { 21 try { 22 database = copyDatabase(database); 23 } catch (IOException e) { 24 25 } 26 } 27 return database; 28 } 29 30 @Override 31 public synchronized SQLiteDatabase getWritableDatabase() { 32 SQLiteDatabase database = super.getWritableDatabase(); 33 if(createDatabase) { 34 try { 35 database = copyDatabase(database); 36 } catch (IOException e) { 37 38 } 39 } 40 return database; 41 } 42 43 private SQLiteDatabase copyDatabase(SQLiteDatabase database) throws IOException { 44 database.close(); 45 46 InputStream input = context.getAssets().open(DB_FILE_NAME); 47 OutputStream output = new FileOutputStream(this.dbPath); 48 copy(input, output); 49 50 51 createDatabase = false; 52 53 return super.getWritableDatabase(); 54 } 55 56 @Override 57 public void onCreate(SQLiteDatabase db) { 58 super.onOpen(db); 59 this.createDatabase = true; 60 } 61 62 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 63 onUpgrade(db, oldVersion, newVersion); 64 } 65 66 private static int copy(InputStream input, OutputStream output) throws IOException { 67 byte[] buffer = new byte[1024 * 4]; 68 int count = 0; 69 int n = 0; 70 while(-1 != (n = input.read(buffer))) { 71 output.write(buffer, 0, n); 72 count += n; 73 } 74 75 output.flush(); 76 input.close(); 77 output.close(); 78 79 return count; 80 } 81}

java

1public class ExpandableListViewChildData { 2 public static List<List<Map<String, String>>> allChildList = new ArrayList<List<Map<String, String>>>(); 3 private static List<Map<String, String>> ChildList = new ArrayList<Map<String, String>>(); 4 private static Map<String, String> ChildData = new HashMap<String, String>(); 5 public static String[] key = {"TITLE"}; 6 7 public static List<List<Map<String, String>>> getData(String place, SQLiteDatabase db) { 8 String[] column = {"name", "expendable"}; 9 String where = "place1=? OR place2=?"; 10 String[] whereArgs = {place, place}; 11 Cursor cursor = db.query("Name", column, where, whereArgs, null, null, null, null); 12 String[] expendable = {"A", "B"}; 13 14 try { 15 for(String ex : expendable) { 16 if (cursor.moveToFirst()) { 17 do { 18 String name = cursor.getString(cursor.getColumnIndex("name")); 19 String expendableDatabase = cursor.getString(cursor.getColumnIndex("expendable")); 20 if (ex.equals(expendableDatabase)) { 21 ChildData.put(key[0], name); 22 } 23 } while(cursor.moveToNext()); 24 } 25 ChildList.add(ChildData); 26 27 28 } 29 allChildList.add(ChildList); 30 } finally { 31 db.close(); 32 } 33 34 return allChildList; 35 } 36} 37

###試したこと
デバッグして、Databaseがコピーされていることを確認。SQLite Browserでデータベースを作成して、それをターミナルでtableが存在してることを確認。

###補足情報(言語/FW/ツール等のバージョンなど)
API 21

いろいろ調べてみましたが、よくわかりませんでした。ぜひご教授ください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

データベースのクローズは、SQLiteDatabase#closeではなく、SQLiteOpenHelper#closeを使ってはいかがですか?

SQLiteOpenHelperのソースコードを見る限り、一度データベースをオープンするとそのデータベースをメンバに保持し、それを使いまわしているようです。
それが原因かどうかまでは確認できませんでしたが、動作しないのであれば疑うべきだと思います。
ご自身でもソースコードを見てご確認してみてください。

というか、SQLiteOpenHelperを使う意味もなくないですか?
SQLiteOpenHelperのメリットは、データベースの新規作成やアップグレードが楽な点だと思うのですが、データベースを開くたびにデータベースを作りなおしているようですし、メリットは薄いと思うのですが。
(getReadableDatabaseを呼んで、getWritableDatabaseのデータベースを返すのも、気持ち悪いですし)

投稿2016/07/27 14:24

katsuko

総合スコア3471

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

クエリのテーブル名が間違っている可能性があります。正しい名前ですか?
正しい場合はそもそもデータベースの作成は出来ていない、またパスが間違っている可能性があります。

・データベースのオリジナルはassetsに配置すべきだとおもいます。
・DBOpenHelper#onCreateでファイルのコピーをした方がわかりやすい。


今回の原因をまとめると
・assetsからDBのコピーをしようとしたが権限がないため書き込みができていなかった。
・SQLiteOpenHelperの機能でDBファイルがなかったため自動で作成した。
・DBファイルは空になっているため質問の例外が発生した。

やはり確認方法が甘かったように思います。
たぶん、ログに書き込み失敗のエラーログが出ていたと思います。

投稿2016/07/26 13:31

編集2016/07/29 03:16
yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Velonica

2016/07/27 09:11

テーブル名の間違い、データベースの作成の有無は確認済みです。データベースのパスはDBOpenHelperのコンストラクタでcontext.getDatabasePath(DB_NAME);を使っているのですが、ここに間違いがあるのでしょうか? データベースのオリジナルはassetsに入れてます。 DBOpenHelperのonCreateでファイルをコピーしてみましたが、同じエラーが発生しました。
yona

2016/07/27 12:01

DB_NAMEに.dbを追加してみてください。
Velonica

2016/07/27 12:49

回答ありがとうございます。 .dbをつけて実行してみました。しかし、以下のエラーが出てしまいました。java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.example.macuser.havi2/databases/HAVI.db ちなみに一応、DB_NAME以外にはDB_FILE_NAMEというフィールドに.dbとついたオリジナルのDatabaseファイル名を指定しています。これはcopyDatabaseメソッドにおいて利用しており、オリジナルのデータベースをコピーしています。
yona

2016/07/27 14:07

SQLiteOpenHelper#onCreateは指定したパス上にDBファイルが存在しない場合は新規で空のDBファイルを作成します。 そのため、パスが間違っている、またはDBファイルのコピー処理の実行位置が悪いため空のDBファイルが作られたため、テーブルがないと言われていると考えています。 正直に言うと私はあなたが行ったファイルがあるかの確認した結果を信用していません。 ・データベースがコピーされていること確認した方法がわからない。 ・データベースにテーブルがあるのを確認したファイルはどのファイルなのか? そのため下記の方法で確認してください。 ・assetsのDBファイルにテーブルが存在すること。 ・assetsのDBファイルとコピーしたDBファイルのサイズが一致すること。 ・コピーしたDBファイルをさらにDownloaフォルダにコピーし、そのDBファイルにテーブルが含まれていること。
Velonica

2016/07/28 03:48

回答ありがとうございます。 assetsのDBファイルにテーブルが存在しているか、assetsのDBファイルとコピーしたDBファイルのサイズが一致するかどうか、コピーしたDBファイルをさらにDownloadフォルダにコピーし、そのDBファイルにテーブルが含まれるかどうか、確認しました。しかし、3つとも正しかったです。 しかし、この3つを確認するにあたって、今まで実機で実行していたのですが、エミュレーターでアプリを実行してみたところ、SQLiteException: no such table (code1)のエラーは出ずに、adapterに対するNullPointerExceptionが発生しました。これは、もしかして、実機において何かしらの問題があるのでしょうか? ちなみに、実機はSamsung SC-01F/Android 5.0/API 21です
yona

2016/07/28 04:06 編集

ありえますね。 パーミッションは付いていますか? また、アプリを一度アンインストールしてから再度実行してみてください。
Velonica

2016/07/28 11:45

パーミッションについて自分なりに調べてみたところ、パーミッション一覧というのは見つけられたのですが、どれをつければ良いのかわかりませんでした。 ぜひご教授ください。
yona

2016/07/28 16:18

ファイル書き込みのパーミッションWRITE_EXTERNAL_STORAGEを追加してください。
Velonica

2016/07/29 03:06

無事解決しました。 長々とおつきあいありがとうございました。
yona

2016/07/29 03:19

おめでとうございます。 やはり、getReadableDatabaseやgetWritableDatabaseにファイルコピーの処理を書くべきではないと思います。
Velonica

2016/07/29 03:55

そうなんですね。勉強になりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問