2016-05-28 16 views
1

値を渡す必要なく、行IDに基づいて更新フィールドを実行するCASEを持つsqlステートメントがあります。context.getContentResolver()を使用してCASE WHENステートメントで更新を実行する方法

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

context.getContentResolver()を使用して実行するにはどうすればよいですか?それとも他の方法ですか?

+0

これはあなた自身の「ContentProvider」ですか?他の人であれば、サポートしているSQL構文があればそれを知る方法がありません。 – CommonsWare

+0

@CommonsWare、ありがとう!その後、おそらく私の質問は、パラメタを必要としないこのタイプの生のSQLを実行する方法をアンドロイドにする必要がありますか? – lannyf

+0

もう一度、あなた自身の 'ContentProvider'ですか?または、他の誰かの 'ContentProvider'に問い合わせていますか? – CommonsWare

答えて

1

あなたがのContentProviderで行くとパスのアプローチは、私はあなたには、いくつかのヘルパークラスを使用することをお勧めします場合:より良いあなたはあなたのブランドでURIを作成するには、いくつかのヘルパーメソッドを持っているあなたのコンテンツプロバイダでは

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、のようなもの:あなたのコードの生活の中でこのすべてを持っていた後

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 
} 

UPDATE: を私はあなたがリスクを理解し、あなたのContentProviderパブリックではないであろうことを示唆しています。このアプローチを使用すると、任意のSQLとバックドアのセキュリティの面で実行できます:)

1

ContentProviderがSQLiteデータベースでバックアップされている場合、ContentProvider自体は、execSQL()を使用して、UPDATEステートメントを実行できます。

することができます、あなたは、この特定のUPDATEを行うことがしたいことを指定するには:あなたのContentProvidercall()をトリガーContentResolver

  • 使用call()、。これにより、基本的なパターンに合わないリクエストに対して、独自のプロトコルを作成することができます。

  • または、Uriの専用パスをupdate()と一緒に使用できます。たとえば、通常content://your.authority/stuffを使用してプロバイダーにアクセスする場合は、content://your.authority/stuff/special_updateupdate()を使用して、ContentProviderにこの特別なUPDATEを送信するよう通知します。

関連する問題