1

データベースが作成されている場所でアクティビティを開くと、SQLiteException:nosuchcolumnというエラーですぐにクラッシュします。SQLiteはまだ私には非常に謎なので、私は何をすべきか悩んでいます。

*新しいエラー。今回はワークアウトノートを作成できますが、クリックして編集すると、そのような列がもう1つ存在しません。今回は、squatLabelです。しかし、それは存在します.... *

編集:この時点で私が得ている唯一のエラーは、そのような列が存在しないことです:squatLabel

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class WorkoutList extends ListActivity {
    private static final int ACTIVITY_CREATE=0;
    private static final int ACTIVITY_EDIT=1;

    private static final int INSERT_ID = Menu.FIRST;
    private static final int DELETE_ID = Menu.FIRST + 1;

    private StrongDbAdapter mDbHelper;


    /** Called when the 5x5 button is pressed in first activity */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.workout_list);
        mDbHelper = new StrongDbAdapter(this);
        mDbHelper.open();
        fillData();
        registerForContextMenu(getListView());
    }

    private void fillData() {
        Cursor NotesCursor = mDbHelper.fetchAllNotes();

        // Get all of the rows from the database and create the item list
        NotesCursor = mDbHelper.fetchAllNotes();
        startManagingCursor(NotesCursor);

        // Create an array to specify the fields we want to display in the list (only TITLE)
        String[] from = new String[]{StrongDbAdapter.KEY_TITLE,};

        // and an array of the fields we want to bind those fields to (in this case just text1)
        int[] to = new int[]{R.id.workout_row };

        // Now create a simple cursor adapter and set it to display
        SimpleCursorAdapter notes = 
            new SimpleCursorAdapter(this, R.layout.workout_row, NotesCursor, from, to);
        setListAdapter(notes);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, INSERT_ID, 0, R.string.menu_insert);
        return true;
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch(item.getItemId()) {
            case INSERT_ID:
                createNote();
                return true;
        }

        return super.onMenuItemSelected(featureId, item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(0, DELETE_ID, 0, R.string.menu_delete);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch(item.getItemId()) {
            case DELETE_ID:
                AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
                mDbHelper.deleteNote(info.id);
                fillData();
                return true;
        }
        return super.onContextItemSelected(item);
    }

    private void createNote() {
        Intent i = new Intent(this, WorkoutEdit.class);
        startActivityForResult(i, ACTIVITY_CREATE);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        Intent i = new Intent(this, WorkoutEdit.class);
        i.putExtra(StrongDbAdapter.KEY_ROWID, id);

        startActivityForResult(i, ACTIVITY_EDIT);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        fillData();
    }
}

これが私のWorkoutEditクラスの一部で、問題が発生しているようです。

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.ViewFlipper;

public class WorkoutEdit extends Activity {

    public TextView mTitleText;
    //private EditText mBodyText;
    private Long mRowId;
    private StrongDbAdapter mDbHelper;
    private ViewFlipper viewFlipper;
    public TextView squats;
    public boolean workoutA;
    public String workoutState;
    //private double rowId = mRowId;
    public String squatLabel;
    public Button confirmButton;
    private Long prevId ;





    private void populateFields() {
        if (mRowId != null) {
            Cursor note = mDbHelper.fetchNote(mRowId);
            startManagingCursor(note);
            //mTitleText.setText(note.getString(
                    //note.getColumnIndexOrThrow(StrongDbAdapter.KEY_TITLE)));
            workoutState=(note.getString(
                    note.getColumnIndexOrThrow(StrongDbAdapter.KEY_TITLE)));
            squats.setText(note.getString(note.getColumnIndexOrThrow(StrongDbAdapter.SQUAT_LABEL)));
        }
    }



    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        saveState();
        outState.putSerializable(StrongDbAdapter.KEY_ROWID, mRowId);
    }

    @Override
    protected void onPause() {
        super.onPause();
        saveState();
    }

    @Override
    protected void onResume() {
        super.onResume();
        populateFields();
    }



    //Saves all the data to the database
    private void saveState() {
        String title = workoutState;
        String squatLabel = squats.getText().toString();


        if (mRowId == null) {
            long id = mDbHelper.createNote(title, squatLabel);
            if (id > 0) {
                mRowId = id;
            }
        } else {
            mDbHelper.updateNote(mRowId, title);
        }
    }       

    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mDbHelper != null) {
            mDbHelper.close();
        }

    }



}

そして、これが私のDbAdapterです

* Createステートメントを更新しました*

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;


public class StrongDbAdapter {

    public static final String KEY_TITLE = "title";
    public static final String KEY_BODY = "body";
    public static final String KEY_ROWID = "_id";


    public static final String WORKOUT_STATE = "workoutState";

    public static final String SQUAT_LABEL = "squatLabel";

    private static final String TAG = "StrongDbAdapter";
    private DatabaseHelper mDbHelper;
    private SQLiteDatabase mDb;


    private static final String DATABASE_NAME = "data";
    private static final String DATABASE_TABLE = "notes";
    private static final int DATABASE_VERSION = 2;



    /**
     * Database creation sql statement
     */
    private static final String DATABASE_CREATE =
        "create table notes (_id integer primary key autoincrement , "
        + "title text," +
        " squatLabel text, workoutState text );";


    private final Context mCtx;

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS notes");
            onCreate(db);
        }
    }

    /**
     * Constructor - takes the context to allow the database to be
     * opened/created
     * 
     * @param ctx the Context within which to work
     */
    public StrongDbAdapter(Context ctx) {
        this.mCtx = ctx;
    }

    /**
     * Open the notes database. If it cannot be opened, try to create a new
     * instance of the database. If it cannot be created, throw an exception to
     * signal the failure
     * 
     * @return this (self reference, allowing this to be chained in an
     *         initialization call)
     * @throws SQLException if the database could be neither opened or created
     */
    public StrongDbAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

    public void close() {
        mDbHelper.close();
    }



    public long createNote(String title, String squatLabel) {


        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_TITLE, title);
        //initialValues.put(WORKOUT_STATE, workoutState);
        initialValues.put(SQUAT_LABEL, squatLabel);

        return mDb.insert(DATABASE_TABLE, null, initialValues);
    }

    /**
     * Delete the note with the given rowId
     * 
     * @param rowId id of note to delete
     * @return true if deleted, false otherwise
     */
    public boolean deleteNote(long rowId) {

        return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
    }

    /**
     * Return a Cursor over the list of all notes in the database
     * 
     * @return Cursor over all notes
     */
    public Cursor fetchAllNotes() {

        return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE,
                WORKOUT_STATE}, null, null, null, null, null);
    }

    /**
     * Return a Cursor positioned at the note that matches the given rowId
     * 
     * @param rowId id of note to retrieve
     * @return Cursor positioned to matching note, if found
     * @throws SQLException if note could not be found/retrieved
     */
    public Cursor fetchNote(long rowId) throws SQLException {

        Cursor mCursor =

            mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
                    KEY_TITLE, WORKOUT_STATE}, KEY_ROWID + "='" + rowId+"'", null,
                    null, null, null, null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;

    }

    /**
     * Update the note using the details provided. The note to be updated is
     * specified using the rowId, and it is altered to use the title and body
     * values passed in
     * @return true if the note was successfully updated, false otherwise
     */
    public boolean updateNote(long rowId, String title) {
        ContentValues args = new ContentValues();
        args.put(KEY_TITLE, title);
        //args.put(WORKOUT_STATE, workoutState);

        return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
    }
}

そして最後に私のLogCat:

*新しいcreateステートメントでは、今回はそのような列squatLabelはありません。*

08-05 18:57:05.336: E/AndroidRuntime(1131): FATAL EXCEPTION: main
08-05 18:57:05.336: E/AndroidRuntime(1131): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.anapoleon.android.stronglifts/com.anapoleon.android.stronglifts.WorkoutEdit}: java.lang.IllegalArgumentException: column 'squatLabel' does not exist
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.app.ActivityThread.access$600(ActivityThread.java:122)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.os.Looper.loop(Looper.java:137)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.app.ActivityThread.main(ActivityThread.java:4340)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at java.lang.reflect.Method.invokeNative(Native Method)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at java.lang.reflect.Method.invoke(Method.java:511)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at dalvik.system.NativeStart.main(Native Method)
08-05 18:57:05.336: E/AndroidRuntime(1131): Caused by: java.lang.IllegalArgumentException: column 'squatLabel' does not exist
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:301)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at com.anapoleon.android.stronglifts.WorkoutEdit.populateFields(WorkoutEdit.java:199)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at com.anapoleon.android.stronglifts.WorkoutEdit.onCreate(WorkoutEdit.java:82)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.app.Activity.performCreate(Activity.java:4465)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
08-05 18:57:05.336: E/AndroidRuntime(1131):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
08-05 18:57:05.336: E/AndroidRuntime(1131):     ... 11 more

前もって感謝します!:)

4

4 に答える 4

1

他の人が言っているように、あなたはあなたのDBでその列を定義していません。

彼らがあなたに言うのを怠ったのは、アプリのデータベーススキーマに列を追加した後、2つのことのうちの1つをしなければならないということです。

1)アプリを削除して再インストールし、DBの作成時にDBの新しいスキーマが使用されるようにします

また

2)onUpgradeメソッドが呼び出され、DBが新しいスキーマに更新されるように、データベースのバージョンをインクリメントします

于 2012-08-05T17:37:28.977 に答える
0

create ステートメントを見てください。

private static final String DATABASE_CREATE =
        "create table notes (_id integer primary key autoincrement , "
        + "title text," +
        " squatLabel text );";

含まれていませんworkoutState。create ステートメントに列を追加するだけです。

于 2012-08-05T16:09:33.370 に答える
0

誰かがまだ同じエラーに直面している場合、文字列をクエリしている場合は、必ず引用符を追加してください。

たとえば、次のように書いたときにエラーが発生しました。

        Cursor cursor = this.database.query(
            SQLiteHelper.TABLE_NAME,
            new String[]{ID, FNAME},
            "fname"+" = "+name,   ......

私はそれを解決しました:

        Cursor cursor = this.database.query(
            SQLiteHelper.TABLE_NAME,
            new String[]{ID, FNAME},
            "fname"+" = "+"'"+name+"'", .....
于 2021-12-11T15:08:45.623 に答える
0

更新された Create DB ステートメントが正しいと思われます。

次のエラーに関しては、データベースとカーソルを決して閉じないということです。私は通常、DB を操作するときに次のテンプレートを使用します。

openReadableDatabase(); // or openWritableDatabase();

// do some work with DB

closeDatabase();

前述の方法は次のようになります。

private void closeDatabase() {
    if (_db != null && _db.isOpen()) {
        _db.close();
    }
}

private void openReadableDatabase() {
    _db = getReadableDatabase();
}

private void openWritableDatabase() {
    _db = getWritableDatabase();
}

同じことをカーソルオブジェクトに適用できます:

Cursor cursor = _db.query(TABLE_NAME, FROM, null, null, null, null, null);

// do some work with cursor

cursor.close();

FROM は列名の配列です。注意: 最後の列名の後のコンマはタイプミスではありません。

private static final String[] FROM = { COLUMN1_NAME, COLUMN2_NAME, };

更新:
db.query() メソッドのデータ取得パラメーターに SquatLabel 列を追加する必要があります (fetchNote メソッドについても同様です)。

public Cursor fetchAllNotes() {
    return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE,
        SQUAT_LABEL, WORKOUT_STATE}, null, null, null, null, null);
}
于 2012-08-05T17:19:45.770 に答える