异常处理系列: android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed

本文介绍了一种常见的Android数据库异常,并提供了具体的解决方案。通过一个实际的例子,详细解释了如何避免因重复主键或空非空字段导致的数据插入失败。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

出现这个异常的时候,可以先肯定是你对android数据库操作的时候出问题了。

情况1:你定义的字段为 not null而插入时对应的字段却没值。

情况2:你定义的字段设定PRIMARY,而插入的值已经在表中存在。


先说说我遇到的情况吧,类似如下:

两张表:部门表(Depart)和员工表(Employee)

Depart:departId,departName
Employee:employeeId,employeeName,foreignDepartId

public void add(Employee em,Depart dp){
	SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
	//把部门插入到表中
	db.execSQL("insert into Depart(departId,departName) values(?,?)",  
		                new Object[]{dp.getDepartId(),dp.getDepartName()}); 
	//把员工插入到这个部门中
	db.execSQL("insert into Employee(employeeId,employeeName,foreignDepartId) values(?,?,?)",  
		                new Object[]{em.getEmployeeId(),em.getEmployeeName,dp.getDepartId()});						
}

上边这个是写在业务层的,是一个增加的方法

然后我们在测试程序里边调用的时候:
private Service service = new Service();
public void testAdd(){
	Depart dp = new Depart(1,"外交部");
	Employee em = new Employee(1,"张三",dp.getDepartId());
	
	service.add(em,dp);
}
按照上边的来说,第一条数据是可以插入的。


但是,如果我们把testAdd()函数里边的Employee em = new Employee(1,"张三",dp.getDepartId());这条语句中的1换成2之后,再插入就会出错:

因为在插入Employee对象的时候Depart对象也要再插入一遍,但是数据库中是有这个对象对应的Id了。

所以,这里我们要在add()中加入一个查询,查询Dept对象对应的id在数据库中是否存在。

03-05 17:45:49.133 05864 05796 W NetworkScheduler: Error inserting flex_time=3536000 job_id=-1 period=7073000 source=16 requires_charging=0 preferred_network_type=1 target_class=com.google.android.gms.measurement.PackageMeasurementTaskService user_id=0 target_package=com.google.android.gms tag=Measurement.PackageMeasurementTaskService.UPLOAD_TASK_TAG task_type=0 required_idleness_state=0 service_kind=0 source_version=250832000 persistence_level=1 preferred_charging_state=1 required_network_type=0 runtime=1741176949126 retry_strategy={"maximum_backoff_seconds":{"3600":0},"initial_backoff_seconds":{"30":0},"retry_policy":{"0":0}} last_runtime=0 [CONTEXT service_id=218 ] android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: pending_ops.tag, pending_ops.target_class, pending_ops.target_package, pending_ops.user_id (code 2067 SQLITE_CONSTRAINT_UNIQUE) at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method) at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:988) at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:814) at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:89) at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1981) at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1875) at dreu.d(:com.google.android.gms@250832035@25.08.32 (260400-731361394):727) at drcl.n(:com.google.android.gms@250832035@25.08.32 (260400-731361394):29) at drcl.u(:com.google.android.gms@250832035@25.08.32 (260400-731361394):364) at drcl.h(:com.google.android.gms@250832035@25.08.32 (260400-731361394):51) at dqxa.run(:com.google.android.gms@250832035@25.08.32 (260400-731361394):72) at atim.c(:com.google.android.gms@250832035@25.08.32 (260400-731361394):50) at atim.run(:com.google.android.gms@250832035@25.08.32 (260400-731361394):76) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) at atnz.run(:com.google.android.gms@250832035@25.08.32 (260400-731361394):8) at java.lang.Thread.run(Thread.java:1012)什么意思
最新发布
03-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值