如何使用context.getContentResolver()来使用CASE WHEN语句执行更新

时间:2016-05-28 21:18:17

标签: android sqlite sql-update

使用CASE的sql语句根据行id执行更新字段,而不需要传递值。

"UPDATE accounts SET field= CASE WHEN id=(select id from accounts where id=0) THEN 1 ELSE 0 END";

如何使用context.getContentResolver()来执行它?或者其他任何方式?

2 个答案:

答案 0 :(得分:1)

如果您的ContentProvider由SQLite数据库支持,ContentProvider本身可以使用UPDATE执行您需要的execSQL()语句。

要指定您希望完成此特定UPDATE,您可以:

  • call()上使用ContentResolver,在call()上触发ContentProvider。这基本上允许您为不符合正常模式的请求创建自己的协议。

  • 或者,您可以使用Uri上的专用路径以及update()。例如,如果您通常使用content://your.authority/stuff来访问提供商,请使用content://your.authority/stuff/special_updateupdate()一起向ContentProvider发出您想要此特殊UPDATE的信号完成。

答案 1 :(得分:1)

如果你使用ContentProvider和Path方法,我建议你使用一些帮助类:

public static class UriBuilder{
        public static final String FRAGMENT_RAW_UPDATE = "rawUpdate"; // here could be noNotify, conflict resolver pathes, etc.

        private Uri.Builder uri;

        public UriBuilder(Uri uri){
            this.uri = uri.buildUpon();
        }

        public UriBuilder(String uri){
            this.uri = Uri.parse(uri).buildUpon();
        }

        public UriBuilder append(String path){
            uri.appendPath(path);
            return this;
        }

        public UriBuilder append(long id){//points directly to item
            uri.appendPath(String.valueOf(id));
            return this;
        }

        public UriBuilder rawUpdate(){
            uri.fragment(FRAGMENT_RAW_UPDATE);
            return this;
        }

        public Uri build(){
            return uri.build();
        }

        public static boolean isRawUpdate(Uri uri) {
            return FRAGMENT_RAW_UPDATE.equals(uri.getFragment());
        }
}

在您的内容提供商中,您最好使用一些辅助方法来使用全新的UriBuilder创建URI,例如:

public static Uri contentUri(String path, long id){
        return new UriBuilder(BASE_URI)
                          .append(path)
                          .append(id)//optional
                          .build();
}

public static Uri contentUriRawUpdate(String path){
        return new UriBuilder(BASE_URI)
                          .append(path)
                          .rawUpdate()
                          .build();
}

在代码生活中完成所有这些后,我会更容易。要创建原始更新URI:

contentResolver.update(YourContentProvider.contentUriRawUpdate(DbContract.Table.CONTENT_URI), null, rawSql, null);

最后在ContentProvider的更新中:

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

        if(UriBuilder.isRawUpdate(uri)){
            dbHelper.getWritableDatabase().update(...);
            return;// early exit
        }
        ... // standard logic for matchers here
        ... // dbHelper.getWritableDatabase().update(...); 
        ... // notify observers here
}

<强>更新: 我建议您了解风险,而您的ContentProvider不会公开。使用这种方法,您可以执行任何SQL以及后门安全性方面:)