mysql 的Escape跳脫字元串

pythontab發表於2018-09-03

一、轉義的意義


使用者輸入如果沒有任何限制的話,則必須對特殊字元進行變換。

如果對單引號不進行變換,輕者不能正常執行功能,重則會發生資料庫錯誤,甚至可能導致系統崩潰。


二、需要轉義的字元型別


在字串中,某些序列具有特殊含義。這些序列均用反斜線(‘\’)開始,即所謂的跳脫字元。MySQL識別下面的轉義序列:

\0

ASCII 0(NUL)字元。

\'

單引號(‘'’)。

\"

雙引號(‘"’)。

\b

退格符。

\n

換行符。

\r

回車符。

\t

tab字元。

\Z

ASCII 26(控制(Ctrl)-Z)。該字元可以編碼為‘\Z’,以允許你解決在Windows中ASCII 26代表檔案結尾這一問題。(如果你試圖使用mysql db_name < file_name,ASCII 26會帶來問題)。

\\

反斜線(‘\’)字元。

\%

‘%’字元。參見表後面的註解。

\_

‘_’字元。參見表後面的註解。

這些序列對大小寫敏感。例如,‘\b’解釋為退格,但‘\B’解釋為‘B’。

‘\%’和‘\_’序列用於搜尋可能會解釋為萬用字元的模式匹配環境中的‘%’和‘_’文字例項。請注意如果你在其它環境中使用‘\%’或‘\_’,它們返回字串‘\%’和‘\_’,而不是‘%’和‘_’。

在其它轉義序列中,反斜線被忽略。也就是說,跳脫字元解釋為彷彿沒有轉義。

有幾種方式可以在字串中包括引號:

在字串內用‘'’引用的‘'’可以寫成‘''’。

在字串內用‘"’引用的‘"’可以寫成‘""’。

可以在引號前加跳脫字元(‘\’)。

在字串內用‘"’引用的‘'’不需要特殊處理,不需要用雙字元或轉義。同樣,在字串內用‘'’引用的‘"’也不需要特殊處理。

下面的SELECT語句顯示了引用和轉義如何工作:

mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';

+-------+---------+-----------+--------+--------+

| hello | "hello" | ""hello"" | hel'lo | 'hello |

+-------+---------+-----------+--------+--------+

mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";

+-------+---------+-----------+--------+--------+

| hello | 'hello' | ''hello'' | hel"lo | "hello |

+-------+---------+-----------+--------+--------+

mysql> SELECT 'This\nIs\nFour\nLines';

+--------------------+

| This

Is

Four

Lines |

+--------------------+

mysql> SELECT 'disappearing\ backslash';

+------------------------+

| disappearing backslash |

+------------------------+

如果你想要在字串列內插入二進位制資料(例如BLOB),必須透過轉義序列表示下面的字元:

NUL

NUL位元組(ASCII 0)。用‘\0’表示該字元(反斜線後面跟一個ASCII‘0’字元)。

\

反斜線(ASCII 92)。用‘\\’表示該字元。

'

單引號(ASCII 39)。用‘\'’表示該字元。

"

雙引號(ASCII 34)。用‘\"’表示該字元。

當編寫應用程式時,在包含這些特殊字元的字串用於傳送到MySQL伺服器的SQL語句中的資料值之前,必須對它們正確進行轉義。可以用兩種方法來完成:

用轉義特殊字元的函式處理字串。例如,在C程式中,可以使用mysql_real_escape_string() C API函式來跳脫字元。參見25.2.3.52節,“mysql_real_escape_string()”。Perl DBI介面提供一個quote方法來將特殊字元轉換為正確的轉義序列。參見25.4節,“MySQL Perl API”。

顯式轉義特殊字元,許多MySQL API提供了佔位符功能,允許你在查詢字串中插入特殊標記,然後當你發出查詢時將資料值同它們繫結起來。在這種情況下,API關注轉義值中的特殊字元。

3、具體的應用


(1)單引號

不過迴避方法卻非常簡單,只要將單引號[']轉換成兩個單引號['']就可以了。

例:SELECT * FROM TBL WHERE COL = 'ABC''DEF';

(2)萬用字元

模糊查詢的語句雖然不會發生SQL錯誤,但是不進行迴避的話,則無法得到要檢索的值。


迴避方法較單引號複雜。需要使用轉義符。將[%]轉為[/%]、[_]轉為[/_],

然後再加上[ESCAPE '/']就可以了。

例:SELECT * FROM TBL WHERE COL LIKE 'ABC/%/_%' ESCAPE '/';

最後一個%是萬用字元。

(3)全形字元

如果做日文專案的話,會出現全形字元的[%]、[_],

而這兩個全形字元同樣會作為半形萬用字元處理。所以在變換時,同時需要將全形的[%]、[_]進行變換。

例:SELECT * FROM TBL WHERE COL LIKE 'ABC/%/_/%/_%' ESCAPE '/';

(4)轉義符

變換成這樣似乎結束了,可是不要忘了還有轉義符自身,萬一使用者輸入轉義符的話,


以上的處理就會發生SQL錯誤。所以也必須對轉義符進行變換。變換方法就是將[/]轉換為[//]。

例:SELECT * FROM TBL WHERE COL LIKE 'ABC/%/_/%///_%' ESCAPE '/';

(5)字元型別

以上的操作都針對於一般的資料型別,如CHAR、VARCHAR2。


如果出現NCHAR、NVARCHAR2的話,以上的處理就會出現ORA-01425錯誤。

如果改成以下寫法,則會發生ORA-01424錯誤。

SELECT * FROM TBL WHERE COL LIKE '%/_%' ESCAPE TO_NCHAR('/')

正確的寫法應該是

SELECT * FROM TBL WHERE COL LIKEC '%/_%' ESCAPE TO_NCHAR('/')

(6)模糊查詢like

最後要說明的是每個like都應該寫ESCAPE語句。

例:

SELECT * FROM TBL

WHERE COL1 LIKE '%/_%' ESCAPE '/' OR COL2 LIKE '%/_%' ESCAPE '/'

SQL> select * from test;

TEST

--------------------

sdd_kk

d'd

dfsfsa

dffa%asfs

12345

1%2345

1%54321

2%54321

%%54321

A&B

已選擇9行。

(7)特殊字元

其中包含特殊的字元分別為%,_,&等等,有可能包含這些字元的資料含有錯誤,或者需要查詢包含這些字元的資料。


SQL> select * from test where test like 'sdd _%' escape ' ';

TEST

--------------------

sdd_kk

1)跳脫字元為' '(空格);

SQL> select * from test where test like 'sdd/_%' escape '/';

TEST

--------------------

sdd_kk


相關文章