是的,這真是一團糟。默認情況下,MySQL和PostgreSQL都使用反斜槓轉義。這是一個可怕的痛苦,如果你也用反斜槓而不是使用參數化來再次轉義字符串,並且根據ANSI SQL:1992也是不正確的,它表示在普通字符串轉義的頂部沒有額外的轉義字符,並且因此無法包含文字%
或_
。
我推測這個簡單的反斜槓替換方法也出了問題,如果你關閉反斜槓逃逸(它們本身是不符合ANSI SQL),使用MySQL的NO_BACKSLASH_ESCAPE
的sql_mode或standard_conforming_strings
CONF PostgreSQL中(其中,PostgreSQL的開發人員現在已經威脅要做幾個版本)。
唯一真正的解決方案是使用鮮爲人知的LIKE...ESCAPE
語法爲LIKE
模式指定明確的轉義字符。這在MySQL和PostgreSQL中被使用,而不是反斜槓轉義,使它們符合其他人的做法,並提供包含帶外字符的保證方式。例如與=
符號作爲轉義:
# look for term anywhere within title
term= term.replace('=', '==').replace('%', '=%').replace('_', '=_')
sql= "SELECT * FROM things WHERE description LIKE %(like)s ESCAPE '='"
cursor.execute(sql, dict(like= '%'+term+'%'))
這適用於的PostgreSQL,MySQL和ANSI兼容SQL的數據庫(模這當然在不同的分貝模塊改變paramstyle)。
MS SQL Server/Sybase可能仍然存在問題,這顯然也允許LIKE
表達式中的[a-z]
樣式字符組。在這種情況下,您希望也可以通過.replace('[', '=[')
轉義文字[
。但是根據ANSI SQL轉義不需要轉義的字符是無效的! (唉!)雖然它可能仍然可以在真正的DBMS中工作,但是您仍然不符合ANSI標準。嘆息......
你忘了「'」和'「' –
@JensTimmerman這個函數只能轉義類似的標記,在結果中使用正常的字符串轉義,然後在查詢中使用它,正確的字符串轉義依賴於標準的'standard_conforming_stings'和所以最好使用庫代碼 – Jasen