我有一个表格,其中包含类型,制造商和型号以及设备ID等类别的设备列表。另一个名为system的表使用device id指向包含设备的表。我有一个编辑系统功能,我正在努力工作,我可以编辑系统表中的记录中的设备ID字段,以更改我指向的设备表中的哪个设备。我运行更新命令,它看起来应该工作,但行不会更新。有谁知道我做错了什么?
这是我的更新代码例程。
SQLiteDatabase db = dbHelper.getWritableDatabase();
String UpdateDeviceName = txtEditDeviceName.getText().toString();
String UpdateDeviceIP = txtEditDeviceIP.getText().toString();
//get the new device id based off of the three spinner values
String dbQuery = "SELECT * FROM " + dbHelper.Devices_Table + ";";
Cursor c = db.rawQuery(dbQuery, null);
if (c.getCount() > 0)
{
while (c.moveToNext())
{
int iColumnID = c.getColumnIndex(dbHelper.Attribute_Device_ID);
int iColumnDeviceType = c.getColumnIndex(dbHelper.Attribute_Device_Type);
int iColumnDeviceManufacturer = c.getColumnIndex(dbHelper.Attribute_Device_Manufacturer);
int iColumnDeviceModel = c.getColumnIndex(dbHelper.Attribute_Device_Model);
String CheckDeviceType = c.getString(iColumnDeviceType);
if (CheckDeviceType.equals(DeviceType))
{
String CheckDeviceManufacturer = c.getString(iColumnDeviceManufacturer);
if (CheckDeviceManufacturer.equals(DeviceManufacturer))
{
String CheckDeviceModel = c.getString(iColumnDeviceModel);
if (CheckDeviceModel.equals(DeviceModel))
{
DeviceID = c.getString(iColumnID);
}
}
}
}
}
db.close();
c.close();
db = dbHelper.getWritableDatabase();
//with the device ID update the system
dbQuery = "UPDATE " + dbHelper.System_Table + " SET " + dbHelper.Attribute_Device_ID + " = " + DeviceID + ", " +
dbHelper.Attribute_Device_Name + " = '" + UpdateDeviceName + "', " +
dbHelper.Attribute_Device_IP + " = '" +
UpdateDeviceIP + "' WHERE " + dbHelper.Attribute_Device_ID + " = " + OrginalDeviceID + ";";
c = db.rawQuery(dbQuery, null);
Log.d("Database Dump", "Edit Device Query: " + dbQuery);
c.close();
db.close();
答案 0 :(得分:1)
您在搜索后关闭了数据库:
db.close();
忽略这一行,因为数据库帮助程序代码更喜欢在不再使用DB之前保持数据库打开(完成后使用dbHelper.close()
关闭数据库)。
更新后同样适用。
答案 1 :(得分:1)
首先,任何rawQuery
语句都不能包含尾随分号!请参阅SQLiteDatabase
的文档。
此外,您必须在关闭数据库之前关闭游标。当你为每个查询获得一个新的时,你有来关闭数据库。否则系统稍后会抛出异常。虽然这些只会被记录并且不会导致强制关闭,但您仍应关注正确的资源管理。
最后,您应该使用updateWithOnConflict
方法,而不是使用CONFLICT_REPLACE
作为conflictAlgorithm。这只是忽略任何UNIQUE
约束并覆盖冲突的行。所以要小心。如果您不想覆盖现有行,则必须确保违反constarint不会导致您的问题。
答案 2 :(得分:1)
我找到了答案。首先,我要感谢Henry和Wolfram Rittmeyer。你们哪里非常有帮助。 :)
无论出于何种原因,android SQLite不喜欢在原始sql查询表单中使用update语句。在研究Wolfram Rittmeyer关于updateWithConflict的内容时,我发现了我的dbHelper扩展的SQLiteOpenHelper对象中的更新方法。当我切换到该方法时,我能够更新数据库。我的条件已经扩展到包括设备名称,如果系统有多个设备品牌和相同类型的模型,只有一个必须更改。
作为参考,更新数据库的工作代码如下。我只发布代码的更改部分。 if(c.getCount()> 0)块及以上的所有内容都保持不变。
c.close();
dbHelper.close();
db = dbHelper.getWritableDatabase();
//with the device ID update the system
ContentValues values = new ContentValues();
values.put(dbHelper.Attribute_Device_ID, DeviceID);
values.put(dbHelper.Attribute_Device_Name, UpdateDeviceName);
values.put(dbHelper.Attribute_Device_IP, UpdateDeviceIP);
String Where = dbHelper.Attribute_Device_ID + " = " + OrginalDeviceID + " AND " + dbHelper.Attribute_Device_Name + " = '" + OrginalDeviceName + "'";
db.update(dbHelper.System_Table, values, Where, null);
c.close();
dbHelper.close();
finish(); //this exits the activity and goes back to the calling activity