如何引用现有的 SQLite 数据库创建新数据库并插入数据?

Posted

技术标签:

【中文标题】如何引用现有的 SQLite 数据库创建新数据库并插入数据?【英文标题】:How to reference existing SQLite db else create new DB and insert data? 【发布时间】:2014-01-15 15:45:50 【问题描述】:

我正在尝试使用数据库创建条形码扫描仪。如果数据库存在,则添加数据,否则创建一个名为“quantityCalculator.db”的新数据库,表名为“quantityCalculator”。

有一些现有的代码,但它会抛出许多错误以试图修复/

错误:

01-15 15:44:26.600: E/Trace(24862): error opening trace file: No such file or directory (2)
01-15 15:44:27.350: I/Adreno200-EGL(24862): <qeglDrvAPI_eglInitialize:299>: EGL 1.4 QUALCOMM build: AU_LINUX_android_JB_REL_RB1.04.01.01.06.043_msm7627a_JB_REL_RB1.2_Merge_release_AU (Merge)
01-15 15:44:27.350: I/Adreno200-EGL(24862): Build Date: 01/18/13 Fri
01-15 15:44:27.350: I/Adreno200-EGL(24862): Local Branch: 
01-15 15:44:27.350: I/Adreno200-EGL(24862): Remote Branch: m/jb_rel_rb1.2
01-15 15:44:27.350: I/Adreno200-EGL(24862): Local Patches: NONE
01-15 15:44:27.350: I/Adreno200-EGL(24862): Reconstruct Branch: NOTHING
01-15 15:44:31.910: E/SQLiteLog(24862): (14) cannot open file at line 30178 of [00bb9c9ce4]
01-15 15:44:31.910: E/SQLiteLog(24862): (14) os_unix.c:30178: (2) open(//foodcalculator.db) - 
01-15 15:44:31.920: E/SQLiteDatabase(24862): Failed to open database 'foodcalculator.db'.
01-15 15:44:31.920: E/SQLiteDatabase(24862): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:213)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:197)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:485)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at com.example.quantitycalculator.AddItem.checkDataBase(AddItem.java:50)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at com.example.quantitycalculator.AddItem.onClick(AddItem.java:82)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.view.View.performClick(View.java:4106)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.view.View$PerformClick.run(View.java:17150)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.os.Handler.handleCallback(Handler.java:615)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.os.Looper.loop(Looper.java:137)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at android.app.ActivityThread.main(ActivityThread.java:4792)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at java.lang.reflect.Method.invokeNative(Native Method)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at java.lang.reflect.Method.invoke(Method.java:511)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:808)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:575)
01-15 15:44:31.920: E/SQLiteDatabase(24862):    at dalvik.system.NativeStart.main(Native Method)
01-15 15:44:31.920: W/dalvikvm(24862): threadid=1: thread exiting with uncaught exception (group=0x40c83498)
01-15 15:44:31.920: E/test(24862): Exception
01-15 15:44:31.940: E/AndroidRuntime(24862): FATAL EXCEPTION: main
01-15 15:44:31.940: E/AndroidRuntime(24862): java.lang.NullPointerException
01-15 15:44:31.940: E/AndroidRuntime(24862):    at com.example.quantitycalculator.AddItem.checkDataBase(AddItem.java:55)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at com.example.quantitycalculator.AddItem.onClick(AddItem.java:82)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at android.view.View.performClick(View.java:4106)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at android.view.View$PerformClick.run(View.java:17150)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at android.os.Handler.handleCallback(Handler.java:615)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at android.os.Looper.loop(Looper.java:137)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at android.app.ActivityThread.main(ActivityThread.java:4792)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at java.lang.reflect.Method.invokeNative(Native Method)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at java.lang.reflect.Method.invoke(Method.java:511)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:808)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:575)
01-15 15:44:31.940: E/AndroidRuntime(24862):    at dalvik.system.NativeStart.main(Native Method)

主页:

package com.example.quantitycalculator;

import com.example.quantitycalculator.R;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Homepage extends Activity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.homepage);

        final Button addButton = (Button) findViewById(R.id.scanner);
        final Button editInventoryButton = (Button) findViewById(R.id.editItem);
        final Button currentInventoryButton = (Button) findViewById(R.id.currentItems);
        final Button settingsButton = (Button) findViewById(R.id.settings);

        addButton.setOnClickListener(new OnClickListener() 

            @Override
            public void onClick(View view) 
                Intent intent = new Intent(view.getContext(), AddItem.class);
                startActivity(intent);
            
        );

        currentInventoryButton.setOnClickListener(new View.OnClickListener() 

            @Override
            public void onClick(View view) 
                Intent intent = new Intent(view.getContext(), CurrentItems.class);
                startActivity(intent);
            
        );


        editInventoryButton.setOnClickListener(new View.OnClickListener() 

            @Override
            public void onClick(View view) 
                // TODO Auto-generated method stub
                Intent intent = new Intent(view.getContext(), EditItems.class);
                startActivity(intent);
            
        );

        settingsButton.setOnClickListener(new View.OnClickListener() 

            @Override
            public void onClick(View view) 
                // TODO Auto-generated method stub
                Intent intent = new Intent(view.getContext(), Settings.class);
                startActivity(intent);
            
        );
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);

    

    static final class ProductData 
        String barcode;
        String title;
        Double quantity;
    

添加项目:

package com.example.quantitycalculator;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import com.example.quantitycalculator.R;

import com.example.quantitycalculator.Homepage.ProductData;

public class AddItem extends Activity implements OnClickListener 
    private static final int REQUEST_BARCODE = 0;
    private static final ProductData mProductData = new ProductData();
    EditText mBarcodeEdit;
    EditText mTitleEdit;
    EditText mQuantityEdit;
    private Button mScanButton;
    private Button mAddButton;

    final String DATABASE_NAME = "quantitycalculator.db";
    final String DATABASE_PATH = "/data/data/com.quantitycalculator.db";
    private final String PRODUCT_TABLE = "foodItems";

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_product);

        mBarcodeEdit = (EditText) findViewById(R.id.barcodeEdit);
        mTitleEdit = (EditText) findViewById(R.id.titleEdit);
        mQuantityEdit = (EditText) findViewById(R.id.quantityEdit);
        mScanButton = (Button) findViewById(R.id.scanButton);
        mScanButton.setOnClickListener(this);
        mAddButton = (Button) findViewById(R.id.addButton);
        mAddButton.setOnClickListener(this);
    

    private boolean checkDataBase() 
        SQLiteDatabase checkDB = null;
        try 
            checkDB = SQLiteDatabase.openDatabase(DATABASE_NAME, null,
                    SQLiteDatabase.OPEN_READONLY);
            checkDB.close();
         catch (SQLiteException e) 
            // database doesn't exist yet.
            checkDB.execSQL("CREATE TABLE IF NOT EXISTS " + PRODUCT_TABLE
                    + " (barcode String, title String, quantity Double);");
        
        return checkDB != null ? true : false;
    

    public void onClick(View v) 
        // TODO Auto-generated method stub
        switch (v.getId()) 
        case R.id.scanButton:
            Intent intent = new Intent("com.google.zxing.client.android.SCAN");
            intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
            startActivityForResult(intent, REQUEST_BARCODE);
            break;

        case R.id.addButton:
            String barcode = mBarcodeEdit.getText().toString();
            String title = mTitleEdit.getText().toString();
            String quantity = mQuantityEdit.getText().toString();

            SQLiteDatabase checkDB = null;

            String errors = validateFields(barcode, title, quantity);
            if (errors.length() > 0) 
                showInfoDialog(this, "Please fix errors", errors);
            

            if (checkDataBase() == false) 
                checkDB = SQLiteDatabase.openDatabase(DATABASE_NAME, null,
                        SQLiteDatabase.OPEN_READWRITE);

                mProductData.barcode = barcode;
                mProductData.title = title;
                mProductData.quantity = Double.valueOf(quantity);

                checkDB.execSQL("INSERT INTO " + PRODUCT_TABLE + " Values "
                        + (mProductData));
                checkDB.close();

                showInfoDialog(this, "Success", "Product saved successfully");
                resetForm();

            

            else 
                checkDB = SQLiteDatabase.openDatabase(DATABASE_NAME, null,
                        SQLiteDatabase.OPEN_READWRITE);
                mProductData.barcode = barcode;
                mProductData.title = title;
                mProductData.quantity = Double.valueOf(quantity);

                checkDB.execSQL("INSERT INTO " + PRODUCT_TABLE + " Values "
                        + (mProductData));
                checkDB.close();

                showInfoDialog(this, "Success", "Product saved successfully");
                resetForm();
            
        
    

    private void showInfoDialog(Context context, String title,
            String information) 
        new AlertDialog.Builder(context).setMessage(information)
                .setTitle(title)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() 

                    public void onClick(DialogInterface dialog, int which) 
                        dialog.dismiss();

                    
                ).show();
    

    private void resetForm() 
        // TODO Auto-generated method stub
        mBarcodeEdit.getText().clear();
        mTitleEdit.getText().clear();
        mQuantityEdit.getText().clear();
    

    public void onActivityResult(int requestCode, int resultCode, Intent intent) 
        if (requestCode == REQUEST_BARCODE) 
            if (resultCode == RESULT_OK) 
                String barcode = intent.getStringExtra("SCAN_RESULT");
                mBarcodeEdit.setText(barcode);

             else if (resultCode == RESULT_CANCELED) 
                finish();
            
        
    

    private static String validateFields(String barcode, String title,
            String quantity) 
        StringBuilder errors = new StringBuilder();

        if (barcode.matches("^\\s*$")) 
            errors.append("Barcode required\n");
        

        if (title.matches("^\\s*$")) 
            errors.append("Title required\n");
        

        if (!quantity.matches("^-?\\d+(.\\d+)?$")) 
            errors.append("Need numeric quantity\n");
        

        return errors.toString();
    

产品数据库:

package com.example.quantitycalculator;

import com.example.quantitycalculator.Homepage.ProductData;

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

public class ProductDatabase 
    private static final String PRODUCT_TABLE = "foodItems";
    private static final String DATABASE_NAME = "quantitycalculator.db";
    private static final int DATABASE_VERSION = 1;

    private SQLiteDatabase db;

    private static class ProductDatabaseHelper extends SQLiteOpenHelper 

        private static final String TAG = null;

        public ProductDatabaseHelper(Context context) 
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            // TODO Auto-generated constructor stub
        

        @Override
        public void onCreate(SQLiteDatabase db) 
            StringBuilder sql = new StringBuilder();

            sql.append("create table ").append(PRODUCT_TABLE).append("(  ")
                    .append("   _id integer primary key,")
                    .append("   barcode text,").append("   title text,")
                    .append("   quantity number").append(")  ");

            db.execSQL(sql.toString());

            Log.d(TAG, PRODUCT_TABLE + "table created");
        

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
            db.execSQL("drop table if exists " + PRODUCT_TABLE);
            onCreate(db);
        
    

    public ProductDatabase(Context context) 
        ProductDatabaseHelper helper = new ProductDatabaseHelper(context);
        db = helper.getWritableDatabase();
    

    public boolean insert(ProductData product) 
        ContentValues vals = new ContentValues();
        vals.put("barcode", product.barcode);
        vals.put("title", product.title);
        vals.put("quantity", product.quantity);

        return db.insert(PRODUCT_TABLE, null, vals) != -1;
    

所有帮助将不胜感激!

【问题讨论】:

【参考方案1】:

您的 DATABASE_PATH 中缺少数据库文件夹。您不应对数据库路径进行硬编码 将您的 DATABASE_PATH 更改为这一行:

DB_PATH="/data/data/" + context.getPackageName() + "/" + "databases/";

您的 logcat 显示 Failed to open database 'foodcalculator.db'.,但在代码中我可以看到您正在创建 quantitycalculator.db。请发布正确的 logcat。

【讨论】:

【参考方案2】:

将数据库功能与活动混合起来并不是一个好主意。您应该创建新类来与数据库通信。您应该阅读本教程,它将帮助您了解如何在应用程序中设计和创建 APP DB 接口:https://developer.android.com/training/basics/data-storage/databases.html

【讨论】:

以上是关于如何引用现有的 SQLite 数据库创建新数据库并插入数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 3 中使用现有的 SQLite? (FMDB)

iOS 下载 sqlite 数据库并替换现有的

将核心数据实现到现有应用程序中,创建或未编写的 sqlite

Iphone 编程 - 将现有的 sql 表导入到 sqlite 或核心数据

SpecialFolder.个人现有的sqlite数据库

如何在sqlite android中进行更改