2017-02-10 87 views
-2

我有我在Android Uri的列,其格式應該是這樣運行的LIKE查詢:SQL LIKE查詢:逃避通配符

  1. 內容://com.android.externalstorage.documents/tree/ 0000-0000%3A_Issues /文件/ 0000-0000%3A _Issues%2F ParentB
  2. 內容://com.android.externalstorage.documents/tree/0000-0000%3A_Issues/document/0000-0000% 3A _Issues%2F ParentA
  3. 內容://com.android.externalstorage.documents/tree/0000-0000%3A_Issues/document/0000-0000%3A _Issues%2F ParentA%2F ParentB

這些對應這個文件樹:

_Issues 
|-ParentA 
    |-ParentB 
|-ParentB 

我已經嘗試了各種手工查詢逃避通配符,但我似乎無法得到適當的匹配。我簡化了下來,這個測試:

select name from meta where parent LIKE '%_Issues%2FParentB%'; 
  1. 如果我逃跑 '%':

%_Issues \%2FParentB%」

我沒有得到任何結果在所有。

  • 如果我不逃脫:
  • '%_Issues%2FParentB%'

    我匹配兩個淺ParentB(期望的)和嵌套的ParentB(不希望的)。我明白這是因爲我允許在問題和ParentB之間使用%進行任何操作。

    我不明白爲什麼查詢1沒有結果。我錯過了什麼?


    更新

    select name from meta where parent LIKE '%_Issues_2FParentB%';

    工作,注意 '_',所以 '\' 顯然不是逃避這個分貝。明確說明轉義字符作爲@GordonLinoff提示我的電腦上工作:

    select name from meta where parent LIKE '%_Issues\%2FParentB%' escape '\';

    我們弄清楚我們如何來完成相同的Android中......

    +1

    編輯你的問題,節目你正在使用的代碼。 –

    +0

    編輯,由於我缺乏知識,結果比我想象的要複雜得多。 – Anthony

    回答

    3

    是。最簡單的方法是使用=,如果適合的話。

    否則,LIKE語法包含轉義字符。在你的榜樣,$不會出現在任何地方,所以你可以這樣做:

    where x like replace(y, '%', '$%') escape '$' 
    

    我相信,在所有數據庫中,默認是\,所以你也可以這樣做:

    where x like replace(y, '%', '\%') 
    

    然而,我更喜歡使用escape關鍵字,因此意圖非常清楚。

    +1

    應該是: '其中x像替換(y,'%','\%')',對不對?匹配%不是\。 – Anthony

    +0

    MySQL&PostgreSQL獲得了默認值,但至少在Oracle,SQL Server和Teradata中沒有默認轉義字符(符合標準SQL)。 SQL不是一種編程語言,默認是愚蠢的,因爲它除了具有特殊含義的'_'和'%'之外添加了第三個字符,如果不轉義它或者改變轉義字符,就不能搜索'\'.. – dnoeth

    +0

    @ dnoeth。 。 。無論如何,我更喜歡顯式的形式,如果我需要使用'escape'。 –

    0

    爲了擴大對@GordonLinoff答案,這裏是具體我如何在Android中沒有它,因爲它是稍微令人費解:

    /*** 
    * Creates a LIKE selection statement with all of the given arguments 
    * @param column column to select on 
    * @param likes array of arguments to select on 
    * @param selectionArgs out: formatted arguments to pass to query 
    * @param joiner joiner between individual LIKE 
    * @param NOT true to set NOT LIKE for all selection arguments 
    * @param argStart set a wildcard before every selection argument 
    * @param argEnd set a wildcard after every selection argument 
    * @return selection statement to query 
    */ 
    public static String createLike(String column, String[] likes, List<String> selectionArgs, 
               String joiner, boolean NOT, 
               @Nullable String argStart, @Nullable String argEnd, 
               @Nullable String escapeChar) 
    { 
        StringBuilder selection = new StringBuilder(); 
        for (int i = 0; i < likes.length; i++) 
        { 
         if (i > 0) selection.append(joiner); 
    
         if (argStart == null) 
          argStart = ""; 
         if (argEnd == null) 
          argEnd = ""; 
    
         selection.append(column) 
           .append(NOT ? " NOT LIKE ?" : " LIKE ?"); 
    
         if (escapeChar != null) 
          selection.append(" ESCAPE '\\'"); 
    
         String argument = likes[i]; 
         if (escapeChar != null) 
          argument = argument.replace(escapeChar, "\\" + escapeChar); 
         argument = argStart + argument + argEnd; 
         selectionArgs.add(argument); 
        } 
    
        return selection.toString(); 
    } 
    

    ,並呼籲:

    DbUtil.createLike(Meta.PARENT, 
            filter.hiddenFolders.toArray(new String[filter.hiddenFolders.size()]), 
            selectionArgs, 
            AND, // Requires AND so multiple hides don't negate each other 
            true, // NOT 
            null, // No wild to start, matches path exactly 
            "%", // Wildcard end to match all children 
            "%")); // Uri contain '%' which means match any so escape them