2013-02-08 29 views

回答

6

我認爲這是完全可以接受的如果JDBC驅動程序允許?運算符被原樣使用和使用,但它可能會1)使您的解析器複雜化,以便真正識別來自該運算符的參數; 2)可能會混淆用於?的人員(也可能是工具)只意味着參數eter佔位符。

所以我的建議是提供某種逃避(或替代運算符)。但是,在查看JDBC規範時,驅動程序應該只使用JDBC轉義語法來實現JDBC規範中定義的轉義(13.4.2:「轉義語法不打算用於調用用戶定義的或供應商特定的標量函數。 「;雖然這具體是關於{fn ...}轉義)。

因此,無論您需要使用替代轉義還是'打破'規則(我不認爲任何人會介意)。如果你想得到更多的答案,你可以發送你的問題到jdbc-spec-discuss mailinglist。我相信Lance Andersen(JDBC spec lead)會提供一個答案。

編輯

同樣有趣的是,JDBC規範第6.2節(原則和要求)說:

驅動程序應該提供訪問由底層數據源,包括實現所有功能擴展JDBC API的功能。目的是讓使用JDBC API的應用程序能夠訪問與本機應用程序相同的功能集。

因此,基於你應該(不應該)支持? - 運算符,你只需要找到一個切實可行的辦法來做到這一點。基於該discussion on jdbc-spec-discuss


更新據蘭斯安徒生JDBC規範遵循SQL規範方面的問號:它們只能用作查詢文本參數佔位符(當然除了在註釋和引用文本中),因爲在PostgreSQL hstore運算符中使用?將不被允許。 (請參閱this message

可用的選項是爲操作員提供別名或轉義,前提是這與以後的更改不衝突(如果沒有透視,這很難做到)。最好的解決方案 - 防止未來JDBC更改的問題 - 可能是一種自定義轉義。

JDBC並未實際定義供應商轉義,但Lance Andersen確實提供了類似於JDBC轉義的轉義:{postgres <thing to be escaped>};在此轉義中使用供應商名稱或驅動程序名稱將提供一種名稱空間格式,以防止與規範衝突。(見this message

要與「正常」的JDBC函數轉義行,我會建議定義一個逃逸,將允許在你的問題中查詢被表述爲:

SELECT * FROM tbl WHERE {postgres containskey(tbl.data, 'abc')} 

我選擇containskey基於?hstore documentation中的含義。對?&的相似建議:containsallkeys)和?|containsanykey。爲了保持一致性,您可以考慮爲其他hstore運營商執行此操作。

你也可以決定只逃避問號本身。例如用{postgres '?'}{postgres qm}(問號爲qm)轉義。我認爲可讀性不到我的函數逃生建議:

SELECT * FROM tbl WHERE tbl.data {postgres '?'} 'abc' 
4

我在JDBC specification中看不到任何東西可以讓?轉義。幾乎所有的它說,大約?是:「?」

參數標記,通過SQL字符串來表示,用於指定輸入值可在運行時改變說法。 [1]

後來...

參數序,其是傳遞到選擇恰當的設置方法的整數,請參考參數標記( 「?」)中的發言,開始在一個。 [2]

而且它僅定義逸出語法的小集合的特徵,其中沒有一個看起來他們可以應用於?

JDBC定義逃脫的語法如下:

  • 標量函數
  • 日期和時間文字
  • 外部聯接
  • 調用存儲過程
  • 轉義字符爲LIKE子句[3]

總體而言,它似乎並不像JDBC規範已經很 「嚴格」 的語言(相較於,例如,一些使用的W3C規範文檔必須是應該是很多),所以我不知道是否允許?轉義的驅動程序在技術上不符合規範,但它可能不是 - 所以,compatib樂。

甚至連Postgres驅動程序都不會允許它,因爲驅動程序中實際解析SQL語句的方法爲?doesn't check for any escape characters


1. JDBC 4.1 Specification,Section 13。2 —的PreparedStatement接口
2. JDBC 4.1規範,第13.3.2節—設置參數
3. JDBC 4.1規範,第13.4節—轉義語法

+0

所以JDBC純粹主義可能不會抱怨,如果[Postgres JDBC實施逃避'?'](http://www.postgresql.org/message-id/[email protected]) ? – 2013-02-08 23:04:17

+0

嗯,除了我自己,我真的不能說任何人,但是我會說爲了使用hstore操作符而執行'?'的轉義會產生反作用,因爲在我看來,'?'hstore操作符意味着簡短易讀,不得不逃避它會使它變得笨重和呆板。 (無論如何,它會是什麼樣子?'c {?}'foo''?)正如[aymeric的答案](http://stackoverflow.com/a/11958394/658907)中指出的那樣,已經有一種解決方法使用'exists '這將在JDBC中工作。 – matts 2013-02-08 23:27:14

+0

@matts但是,正如答案中的一條評論指出的那樣:它不起作用('exists'不使用索引) – 2013-02-09 08:59:20

6

如果您有最新的PostgreSQL驅動程序,您可以使用:

?? 

更改原始查詢:

SELECT * FROM tbl WHERE tbl.data ?? 'abc' 

詳細信息在這個拉請求 - https://github.com/pgjdbc/pgjdbc/pull/227 這個改變是在原來的問題後很長時間,但值得注意的是,有一個簡單的答案呃現在。

+1

有趣。讓我們只希望永遠不會有'??'操作符...... – 2016-07-14 11:01:42

相關問題