【问题标题】:SQLite Insert failsSQLite 插入失败
【发布时间】:2011-07-08 13:48:29
【问题描述】:

好吧,我昨天和今天一直在与这个作斗争,我得到了一个简单的 SQLite 插入,它不断返回 -1 作为返回值,我在某处读到将主键名称更改为 _id,但没有做任何更改。

所以这里是代码的快照。 我的字段常量:

//BALLS TABLE
public  static final String BALLS_TABLE  = "balls";
public  static final String BALL_ID = "id";
public  static final String BALL_USERID = "userId";
public  static final String BALL_MODEL = "model";
public  static final String BALL_BRAND = "brand";
public  static final String BALL_SERIAL = "serial";
public  static final String BALL_NOTES = "notes";
public  static final String BALL_IMAGE = "image";

然后在我的 createTables(SQLiteDatabase db) 上我得到了

//球桌

db.execSQL(
"create table " + BALLS_TABLE +" (" +
BALL_ID + " integer primary key autoincrement not null," +
BALL_USERID + "integer not null," +
BALL_MODEL + " text not null," +
BALL_BRAND + " text not null," +
BALL_SERIAL + " text not null," +
BALL_NOTES + " text not null," +
BALL_IMAGE + " blob" +
");");

表格的创建正在工作,因为我得到了其他已填充的表格。

最后是整个ball Helper类

package com.kegel.android.bowlermanager.data;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class BallHelper {

    private SQLiteDatabase database;
    private ArrayList<Ball> currentBalls;
    private Context context;

    public BallHelper(Context context,SQLiteDatabase database)
    {
        this.context = context;
        this.database = database;
        loadBalls();
    }

    public ArrayList<Ball> getCurrentBalls() {
        return currentBalls;
    }

    public Boolean BallExists(long id)
    {
        for (Ball ball : currentBalls)
        {
            if (ball.getId() == id)
                return true;
        }   
        return false;
    }

    public Boolean BallExists(Ball u)
    {
        for (Ball ball : currentBalls)
        {
            if (ball.getId() == u.getId())
                return true;
        }   
        return false;
    }

    public void updateBall(Ball b) {
        assert(null != b);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] by = null;
        if (b.getImage() != null )
        {
            Bitmap bmp = b.getImage();
            bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);   
            by = baos.toByteArray();  

        }
        ContentValues values = new ContentValues();
        values.put(SQLiteOpenDataHelper.BALL_USERID, 1);
        values.put(SQLiteOpenDataHelper.BALL_MODEL, b.getModel());
        values.put(SQLiteOpenDataHelper.BALL_BRAND , b.getBrand());
        values.put(SQLiteOpenDataHelper.BALL_SERIAL , b.getSerial());
        values.put(SQLiteOpenDataHelper.BALL_NOTES, b.getNotes());
        values.put(SQLiteOpenDataHelper.BALL_IMAGE , by);
        if (b.isValid())
        {
            if (b.getId() == 0)
            {
                b.setId(database.insert(SQLiteOpenDataHelper.BALLS_TABLE, null, values));
            }
            else
            {
                long id = b.getId();
                String where = String.format("%s = %d", SQLiteOpenDataHelper.BALL_ID, id);
                database.update(SQLiteOpenDataHelper.BALLS_TABLE, values, where, null);
            }
            loadBalls();    
        }
    }
    public void deleteBalls(Long id) {
        String where = String.format("%s in (%s)", SQLiteOpenDataHelper.BALL_ID, id);
        database.delete(SQLiteOpenDataHelper.BALLS_TABLE, where, null);
        loadBalls();
    }
    public void deleteBalls(Ball u) {
        String where = String.format("%s in (%s)", SQLiteOpenDataHelper.BALL_ID, u.getId());
        database.delete(SQLiteOpenDataHelper.BALLS_TABLE, where, null);
        loadBalls();
    }
        private void loadBalls() {
        byte[] img = null;
        currentBalls = new ArrayList<Ball>();
        //try
        //{
        Cursor ballsCursor = database.query(SQLiteOpenDataHelper.BALLS_TABLE, new String[] {SQLiteOpenDataHelper.BALL_ID,SQLiteOpenDataHelper.USER_ID, SQLiteOpenDataHelper.BALL_MODEL, SQLiteOpenDataHelper.BALL_BRAND, SQLiteOpenDataHelper.BALL_SERIAL, SQLiteOpenDataHelper.BALL_NOTES, SQLiteOpenDataHelper.BALL_IMAGE}, null, null, null, null, null);
        ballsCursor.moveToFirst();
        Ball b;
        if (! ballsCursor.isAfterLast()) {
            do {
                long id = ballsCursor.getInt(0);
                long bowlerId  = ballsCursor.getLong(1);
                String model = ballsCursor.getString(2);
                String brand = ballsCursor.getString(3);
                String serial = ballsCursor.getString(4);
                String notes = ballsCursor.getString(5);
                img = ballsCursor.getBlob(6);
                Bitmap bmp=BitmapFactory.decodeByteArray(img,0,img.length);
                b = new Ball(context,bowlerId,model,brand,serial,notes);
                b.setId(id);
                b.setImage(bmp);
                currentBalls.add(b);
            } while (ballsCursor.moveToNext());
        }
        ballsCursor.close();
    }
}

这里的第二双眼睛会派上用场!所以如果有人能在这里发现任何东西,或者让我知道我是否遗漏了一些东西,我将非常感激。我已经检查了 b 上的值(甚至通过了我的内部验证)但是像这样的插入会失败:

Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.fake_pofile);
Ball ball = new Ball(this,1, "Test", "Test", "", "");
ball.setImage(bm);
mHelper.updateBall(ball);

【问题讨论】:

  • 日志中有任何异常或附加信息吗?
  • 插入失败是怎么回事? Logcat 有消息吗?
  • 首先,球 id 是自动增量(在您的创建表查询中定义),不确定在自动增量时插入具有定义 id 的球是否是个好主意...其次,我看到你正在使用布尔值而不是布尔值,因此您也可能使用 Integer 而不是 int 并且 Integer 是对象。当您检查 ball.getId() == 0 时,球的 id 无法初始化,可能导致 NullPointer 异常。请发布异常,以便查看问题所在;)
  • 也不例外, database.Insert 返回一个 -1 ,而应该返回的是一个有效的生成的自动增量 ID。我对其他类使用相同的逻辑,它们完美地返回了 Id。我也处于测试阶段,所以我确信没有其他人在搞乱 setId o getId。谢谢大家的帮助。

标签: java android database sqlite insert


【解决方案1】:

嗯......因为我没有,没有其他人注意到创建表的代码,在字段 BALL_USERID 之间我没有留下空格,所以它是一个完整的单词,db.exec 应该是有趣的事情抛出异常,但在这种情况下没有并接受一个奇怪的名称作为没有类型的字段,并创建了没有字段“userId”但没有类型的“useridinteger”的表(如果你没有设置,是否有默认类型一个??)

有时只是那些小事会让你发疯。

【讨论】:

    【解决方案2】:

    我知道这是一个旧示例,但对于任何寻找 Objective C 示例的人来说,这很好。但是,请务必将 sqlite3_reset(statement) 行放在 return 语句之前。否则,该代码仅适用于第一次保存或查找。

    【讨论】:

      猜你喜欢
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多