更新SQLite数据库会导致错误

时间:2016-08-15 12:13:08

标签: java android sqlite

我是Android新手并且正在使用应用程序,应该从相机检索数据并将其存储到SQlite数据库中。不幸的是,数据库更新不起作用,因此任何提示或评论都将受到赞赏。

以下是代码:

package de.die_web_agenten.www.runinstant;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;

import de.die_web_agenten.www.runinstant.db.TaskContract;
import de.die_web_agenten.www.runinstant.db.TaskDBHelper;


public class AndroidBarcodeQrExample extends Activity {
    /** Called when the activity is first created. */

    static final String ACTION_SCAN = "com.google.zxing.client.android.SCAN";
    private ListAdapter listAdapter;
    private TaskDBHelper helper;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_barcode);
    }

    public void scanBar(View v) {
        try {
            Intent intent = new Intent(ACTION_SCAN);
            intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
            startActivityForResult(intent, 0);
        } catch (ActivityNotFoundException anfe) {
            showDialog(AndroidBarcodeQrExample.this, "No Scanner Found", "Download a scanner code activity?", "Yes", "No").show();
        }
    }

    public void scanQR(View v) {
        try {
            Intent intent = new Intent(ACTION_SCAN);
            intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
            startActivityForResult(intent, 0);
        } catch (ActivityNotFoundException anfe) {
            showDialog(AndroidBarcodeQrExample.this, "No Scanner Found", "Download a scanner code activity?", "Yes", "No").show();
        }
    }

    private static AlertDialog showDialog(final Activity act, CharSequence title, CharSequence message, CharSequence buttonYes, CharSequence buttonNo) {
        AlertDialog.Builder downloadDialog = new AlertDialog.Builder(act);
        downloadDialog.setTitle(title);
        downloadDialog.setMessage(message);
        downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
                Uri uri = Uri.parse("market://search?q=pname:" + "com.google.zxing.client.android");
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                try {
                    act.startActivity(intent);
                } catch (ActivityNotFoundException anfe) {

                }
            }
        });
        downloadDialog.setNegativeButton(buttonNo, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
            }
        });
        return downloadDialog.show();
    }

    private void updateUI() {
        helper = new TaskDBHelper(AndroidBarcodeQrExample.this);
        SQLiteDatabase sqlDB = helper.getReadableDatabase();
        Cursor cursor = sqlDB.query(TaskContract.TABLE,
                new String[]{ TaskContract.Columns.SCAN_RESULT, TaskContract.Columns.SCAN_RESULT_FORMAT,TaskContract.Columns._id,
                         TaskContract.Columns.DATE},
                null, null, null, null, null
        );


        listAdapter = new SimpleCursorAdapter(
                this,
                R.layout.task_view,
                cursor,
                new String[]{TaskContract.Columns.SCAN_RESULT_FORMAT, TaskContract.Columns.SCAN_RESULT, TaskContract.Columns._id},
                new int[]{R.id.taskTextView},
                0
        );

        this.setListAdapter(listAdapter);

    }

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == 0) {
            if (resultCode == RESULT_OK) {
                String contents = intent.getStringExtra("SCAN_RESULT");
                String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
                helper = new TaskDBHelper(AndroidBarcodeQrExample.this);
                SQLiteDatabase db = helper.getWritableDatabase();
                ContentValues values = new ContentValues();
                //values.clear();
                values.put(TaskContract.Columns.SCAN_RESULT, contents);
                values.put(TaskContract.Columns.SCAN_RESULT_FORMAT, format);
                db.insertWithOnConflict(TaskContract.TABLE, null, values, SQLiteDatabase.CONFLICT_IGNORE);
                //Toast toast = Toast.makeText(this, "Content:" + contents + " Format:" + format, Toast.LENGTH_LONG);
                //toast.show();
                /*Intent SecondIntent = new Intent(AndroidBarcodeQrExample.this, SecondListActivity.class);
                SecondIntent.putExtra("SCAN_RESULT", contents);
                startActivity(SecondIntent);*/
                //Intent SecondIntent = new Intent(getBaseContext(), SecondListActivity.class);
                //intent.putExtra("SCAN_RESULT", contents);
                //intent.putExtra("SCAN_RESULT_FORMAT", format);
                //Intent i = new Intent(this,  SecondListActivity.class);
                //startActivityForResult(i, 1);
                //startActivity(SecondIntent);
                Log.d("ADebugTag", "Value: " + (contents));
                Log.d("BDebugTag", "Value: " + (format));
                //updateUI();

            //Context context = getApplicationContext();
            //CharSequence text = "Informationen erfolgreich gespeichert!";
            //int duration = Toast.LENGTH_SHORT;
            //Toast toast = Toast.makeText(context, text, duration);
            }

        }

    }

    public void setListAdapter(ListAdapter listAdapter) {
        this.listAdapter = listAdapter;
    }

}

这是TaskDBHelper类:

package de.die_web_agenten.www.runinstant.db;

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


public class TaskDBHelper extends SQLiteOpenHelper {

    public TaskDBHelper(Context context) {
        super(context, TaskContract.DB_NAME, null, TaskContract.DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqlDB) {
        String sqlQuery =
                String.format("CREATE TABLE %s (" +
                        "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "%s TEXT, %s TEXT)",
                                    TaskContract.TABLE,
                                    TaskContract.Columns.SCAN_RESULT,
                                    TaskContract.Columns.SCAN_RESULT_FORMAT
                                    );
        Log.d("TaskDBHelper", "Query to form table: " + sqlQuery);
        sqlDB.execSQL(sqlQuery);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqlDB, int i, int i2) {
        sqlDB.execSQL("DROP TABLE IF EXISTS "+TaskContract.TABLE);
        onCreate(sqlDB);
    }
}

这是TaskContract类:

    package de.die_web_agenten.www.runinstant.db;

    public class TaskContract {
        public static final String DB_NAME = "de.die_web_agenten.www.runinstant";
        public static final int DB_VERSION = 1;
        public static final String TABLE = "VALUES";


        public static class Columns {
            public static final String SCAN_RESULT = "SCAN_RESULT";
            public static final String SCAN_RESULT_FORMAT = "SCAN_RESULT_FORMAT";
            //public static final String DATE = "date";
            public static final String _id = "_id";
        }
    }

Here´s the TaskDBHelper class: 

package de.die_web_agenten.www.runinstant.db;

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


public class TaskDBHelper extends SQLiteOpenHelper {

    public TaskDBHelper(Context context) {
        super(context, TaskContract.DB_NAME, null, TaskContract.DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqlDB) {
        String sqlQuery =
                String.format("CREATE TABLE %s (" +
                        "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "%s TEXT, %s TEXT)",
                                    TaskContract.TABLE,
                                    TaskContract.Columns.SCAN_RESULT,
                                    TaskContract.Columns.SCAN_RESULT_FORMAT
                                    );
        Log.d("TaskDBHelper", "Query to form table: " + sqlQuery);
        sqlDB.execSQL(sqlQuery);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqlDB, int i, int i2) {
        sqlDB.execSQL("DROP TABLE IF EXISTS "+TaskContract.TABLE);
        onCreate(sqlDB);
    }
}

这是logcat:

08-15 16:55:12.356 15118-15118/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: de.die_web_agenten.www.runinstant, PID: 15118
                                                   java.lang.RuntimeException: Unable to resume activity {de.die_web_agenten.www.runinstant/de.die_web_agenten.www.runinstant.AndroidBarcodeQrExample}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { act=com.google.zxing.client.android.SCAN flg=0x80000 (has extras) }} to activity {de.die_web_agenten.www.runinstant/de.die_web_agenten.www.runinstant.AndroidBarcodeQrExample}: android.database.sqlite.SQLiteException: near "VALUES": syntax error (code 1): , while compiling: CREATE TABLE VALUES (_id INTEGER PRIMARY KEY AUTOINCREMENT, SCAN_RESULT TEXT, SCAN_RESULT_FORMAT TEXT)
                                                   #################################################################
                                                   Error Code : 1 (SQLITE_ERROR)
                                                   Caused By : SQL(query) error or missing database.
                                                    (near "VALUES": syntax error (code 1): , while compiling: CREATE TABLE VALUES (_id INTEGER PRIMARY KEY AUTOINCREMENT, SCAN_RESULT TEXT, SCAN_RESULT_FORMAT TEXT))
                                                   #################################################################
                                                       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3409)
                                                       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2774)
                                                       at android.app.ActivityThread.access$900(ActivityThread.java:177)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:135)
                                                       at android.app.ActivityThread.main(ActivityThread.java:5910)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
                                                    Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { act=com.google.zxing.client.android.SCAN flg=0x80000 (has extras) }} to activity {de.die_web_agenten.www.runinstant/de.die_web_agenten.www.runinstant.AndroidBarcodeQrExample}: android.database.sqlite.SQLiteException: near "VALUES": syntax error (code 1): , while compiling: CREATE TABLE VALUES (_id INTEGER PRIMARY KEY AUTOINCREMENT, SCAN_RESULT TEXT, SCAN_RESULT_FORMAT TEXT)
                                                   #################################################################
                                                   Error Code : 1 (SQLITE_ERROR)
                                                   Caused By : SQL(query) error or missing database.
                                                    (near "VALUES": syntax error (code 1): , while compiling: CREATE TABLE VALUES (_id INTEGER PRIMARY KEY AUTOINCREMENT, SCAN_RESULT TEXT, SCAN_RESULT_FORMAT TEXT))
                                                   #################################################################
                                                       at android.app.ActivityThread.deliverResults(ActivityThread.java:4005)
                                                       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3395)
                                                        ... 11 more
                                                    Caused by: android.database.sqlite.SQLiteException: near "VALUES": syntax error (code 1): , while compiling: CREATE TABLE VALUES (_id INTEGER PRIMARY KEY AUTOINCREMENT, SCAN_RESULT TEXT, SCAN_RESULT_FORMAT TEXT)
                                                   #################################################################
                                                   Error Code : 1 (SQLITE_ERROR)
                                                   Caused By : SQL(query) error or missing database.
                                                    (near "VALUES": syntax error (code 1): , while compiling: CREATE TABLE VALUES (_id INTEGER PRIMARY KEY AUTOINCREMENT, SCAN_RESULT TEXT, SCAN_RESULT_FORMAT TEXT))
                                                   #################################################################
                                                       at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                       at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1093)
                                                       at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:670)
                                                       at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                       at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
                                                       at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
                                                    at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.

感谢任何帮助,谢谢

2 个答案:

答案 0 :(得分:1)

这是有问题的部分:还需要2个参数。你有5个占位符,其中3个填充...

   String sqlQuery =
            String.format("CREATE TABLE %s (" +
              "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
              "%s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT)",
              TaskContract.TABLE,
              TaskContract.Columns.SCAN_RESULT,
              TaskContract.Columns.SCAN_RESULT_FORMAT
                // 2 more to go!!
              );

另请注意:使用字符串操作通常不是创建SQL查询的推荐方法,即使在此代码中,所有输入似乎都来自应用程序内部。

答案 1 :(得分:1)

错误发生,因为预期占位符String的数量与给定格式String的数量不匹配:

应格式化以下String(预计6 String s填写占位符):

"CREATE TABLE %s (_id INTEGER PRIMARY KEY AUTOINCREMENT, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT)"

你给了它3 String s:

TaskContract.TABLE, TaskContract.Columns.SCAN_RESULT, TaskContract.Columns.SCAN_RESULT_FORMAT

您只需要传递String.format()方法所需的列名,您就应该好了。