2014-01-06 14 views
3

我正在編寫一個集成測試,它將一個複雜的order by傳遞給PostgreSQL,然後檢查數據是否以正確的順序返回。我正在用Java編寫這個集成測試,它的String.compareTo方法似乎與PostgreSQL有所不同。我跑這對我的PostgreSQL數據庫:我如何構建一個比較字符串的方式與PostgreSQL相同?

SELECT regexp_split_to_table('D d a A c b', ' ') ORDER BY 1; 

它反應了這一點:

a 
A 
b 
c 
d 
D 

然後我創造了這個單元測試來比較的方式的Java排序的事情:

import com.google.common.collect.Lists; 
import com.google.common.collect.Ordering; 
import org.junit.Test; 

import java.util.List; 

import static junit.framework.Assert.assertEquals; 

public class PostgresqlSortOrderTest { 

    @Test 
    public void whenJavaSortsStringsThenItIsTheSameAsWhenPostgresqlSortsStrings() { 
     List<String> postgresqlOrder = Lists.newArrayList("a", "A", "b", "c", "d", "D"); 
     Ordering<String> ordering = new Ordering<String>() { 
      @Override 
      public int compare(String left, String right) { 

       return left.compareTo(right); 
      } 
     }; 
     List<String> javaOrdering = ordering.sortedCopy(postgresqlOrder); 
     assertEquals(postgresqlOrder, javaOrdering); 
    } 

} 

此輸出失敗:

Expected :[a, A, b, c, d, D] //postgresql 
Actual :[A, D, a, b, c, d] //java 

我對這裏的術語一無所知。我想知道這些不同的字符串排序的名稱,所以我可以更好地溝通。但更重要的是,我怎樣才能讓PostgreSQL像Java那樣排序呢?

+2

Java以ASCII碼順序執行。 PG似乎按字母順序排列,同一字母的小寫和大寫順序排列(低於<上部)。這足以寫入比較器。 –

+0

@DaveNewton是真的,但如果有一個庫已經有了這樣一個比較器,我寧願使用它,而不是寫我自己的。你知道嗎? –

+1

Yep,String.CASE_INSENSITIVE_ORDER,在標準API中。 –

回答

5

晚一個答案來展示,但恐怕一個簡單的區分大小寫的搜索不一定會做你想要什麼。

您要搜索的關鍵字是collation(從更廣泛的意義上說,locales),PostgreSQL依賴底層操作系統爲此提供支持。排序很少是一個簡單的字符逐字比較。例如,在許多語言環境中,空格被忽略(en_GB當然就是這種情況)。此外,這意味着您可以在不同平臺上獲得不同的排序順序(取決於Apple或Microsoft是否同意Linus針對您所在國家/地區的默認排序)。

有一些討論,包括一個BSD許可的庫是否有意義提供跨平臺的一套一致的排序。但是,這是很多工作,然後意味着您可以從操作系統的其餘部分對數據庫進行不同的排序。雖然不同的提供商不同意如何處理這個問題,但恐怕沒有一個簡單的解決方案。

您可能需要調查「傳統」排序的「C」排序規則。恐怕我不能評論Java處理正確的區域排序 - 而不是我的領域。

+1

+1就像一個FYI Java一樣處理它。它是基於語言環境的,您可以使用[Collat​​or](http://docs.oracle.com/javase/7/docs/api/java/text/Collat​​or.html)類。 –

+0

@BrianRoach我想我需要那個。我的集成測試通過'String.CASE_INSENSITIVE_ORDER'本地傳遞,但是一旦它運行在我們的CI(不同的操作系統和可能的語言環境)上,它就失敗了。但我無法弄清楚如何爲默認語言環境獲取不區分大小寫的collactor。你知道怎麼做嗎? –

+1

@tieTYT - 這是問題;你試圖依賴於兩種不同系統的行爲,即跨平臺的基於區域的行爲。您需要明確地管理它們匹配的位置,或者選擇一個端點並讓它完成工作。如果是我,我需要在查詢後在數據庫之外插入排序(我假設這是問題),我只是在Java端進行排序。這裏有一個關於如何使用Java排序規則的教程:http://docs.oracle.com/javase/tutorial/i18n/text/collat​​ionintro.html另一個選項可能是重新考慮你的問題的方法。 –

3

使用比較器:String.CASE_INSENSITIVE_ORDER來分類CollectionStrings。它已在String類中實施。

看在字段摘要http://docs.oracle.com/javase/6/docs/api/java/lang/String.html

+2

值得注意的是,postgres中的ORDER BY'依賴於語言環境,就像Java一樣。 Postgres 9。3在我的機器上,例如,響應'[A,D,a,b,c,d]',如果你這樣做SELECT ORDER BY 1;' –

相關問題