【问题标题】:Android Sqlite Transaction and Content ProviderAndroid Sqlite 事务和内容提供程序
【发布时间】:2013-08-19 22:01:05
【问题描述】:

我正在解析 JSON WebService 并创建一个数组,其中包含要在数据库中插入和删除条目的数据。

我找到了解决方案bulkInsert 使用内容提供程序中的数据库事务插入多行,但是,我正在尝试执行相同的过程来删除多行。

INSERT 解决方案:

@Override
public int bulkInsert(Uri uri, ContentValues[] allValues) {

    SQLiteDatabase sqlDB = mCustomerDB.getWritableDatabase();

    int numInserted = 0;
    String table = MyDatabase.TABLE;

    sqlDB.beginTransaction();

    try {
        for (ContentValues cv : allValues) {
            //long newID = sqlDB.insertOrThrow(table, null, cv);
            long newID = sqlDB.insertWithOnConflict(table, null, cv, SQLiteDatabase.CONFLICT_REPLACE);
            if (newID <= 0) {
                throw new SQLException("Error to add: " + uri);
            }
        }
        sqlDB.setTransactionSuccessful();
        getContext().getContentResolver().notifyChange(uri, null);
        numInserted = allValues.length;
    } finally {
        sqlDB.endTransaction();
    }

    return numInserted;
}

使用这个调用:

mContext.getContentResolver().bulkInsert(ProviderMyDatabase.CONTENT_URI, valuesToInsertArray);

有没有办法使用内容提供者删除数据库的多行(具有此数组 ID)。

更新:

我找到了这个解决方案,使用 `IN 子句:

List<String> list = new ArrayList<String>();

for (ContentValues cv : valuesToDelete) {
    Object value = cv.get(DatabaseMyDatabase.KEY_ROW_ID);
    list.add(value.toString());
}

String[] args = list.toArray(new String[list.size()]);
String selection = DatabaseMyDatabase.KEY_ROW_ID + " IN(" + new String(new char[args.length-1]).replace("\0", "?,") + "?)";

int total = mContext.getContentResolver().delete(ProviderMyDatabase.CONTENT_URI, selection, args);
LOGD(TAG, "Total = " + total);

问题是,如果 JSON 返回超过 1000 行要插入,则会发生错误,因为 SQLITE_MAX_VARIABLE_NUMBER 设置为 999。它可以更改,但只能在编译时更改。

ERROR: SQLiteException: too many SQL variables

提前致谢

【问题讨论】:

    标签: android database sqlite android-contentprovider android-sqlite


    【解决方案1】:

    我用这段代码解决了这个问题:

    if (!valuesToDelete.isEmpty()) {
    
            StringBuilder sb = new StringBuilder();
            String value = null;
    
            for (ContentValues cv : valuesToDelete) {
    
                value = cv.getAsString(kei_id);
    
                if (sb.length() > 0) {
                    sb.append(", ");
                }
                sb.append(value);
            }
    
            String args = sb.toString();
    
            String selection = kei_id + " IN(" + args + ")";
    
            int total = mContext.getContentResolver().delete(uri, selection, null);
            LOGD(TAG, "Total = " + total);
    
    
        } else {
            LOGD(TAG, "No data to Delete");
        }
    

    谢谢

    【讨论】:

    【解决方案2】:

    用户 ContentResolver 对象删除多行。

    // get the ContentResolver from a context
    // if not from any activity, then you can use application's context to get the ContentResolver
    //    'where' is the condition e.g., "field1 = ?" 
    //    whereArgs is the values in string e.g., new String[] { field1Value } 
    ContentResolver cr = getContentResolver();
    cr.delete(ProviderMyDatabase.CONTENT_URI, where, whereArgs);
    

    因此,任何带有 (field1 = field1Value) 的行都将被删除。

    如果要删除所有行,那么

    cr.delete(ProviderMyDatabase.CONTENT_URI, "1 = 1", null);
    

    【讨论】:

      猜你喜欢
      • 2011-10-18
      • 2016-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多