2013-05-20 133 views
1

我正在爲客戶的網站編寫靈活的搜索機制。我正在使用聯合子句來查詢數據庫中的許多不同字段,以搜索用戶輸入的字符串值。這工作正常,除了一個問題。嚴格匹配字符串和整數

將文本字符串與當前設置爲零的整數進行比較時,匹配始終返回true。換句話說,根據MySQL,「[email protected]」等於0.

我嘗試過使用CAST和CONVERT函數將其轉換爲字符串比較的標準字符串,但我無法得到正確的語法。我的嘗試要麼重複上述問題,要麼在一些匹配時不返回任何行。我也擔心這樣做會影響績效,因爲我結合了很多工會。

我真正需要的是輸入的字符串和數據庫中的值之間的嚴格比較,無論是整數還是字符串。編號: 下面是一個例子。

CREATE TABLE `test_table` (
`id` INT NOT NULL AUTO_INCREMENT , 
`email` VARCHAR(255) NOT NULL , 
`phone` BIGINT(19) NOT NULL DEFAULT '0' , 
PRIMARY KEY (`id`)) 
ENGINE = MyISAM; 

INSERT INTO `test_table` (`id`, `email`, `phone`) VALUES (1, '[email protected]', 0); 

SELECT * FROM test_table WHERE phone = '[email protected]'; 

執行此操作,插入的一行將返回。我的問題是,它不應該!

+0

如果您不顯示您的代碼,我們無法告訴您您做了什麼錯誤。通常在調用'prepare()'時指定要使用的數據類型(假設您正在使用準備語句,因爲您應該避免SQL注入)。 – Barmar

+0

我已編輯該帖子以提供示例。在字符串到達​​查詢之前,我正在處理SQL注入和其他安全措施。 – Tanoro

+0

在你的例子中,你將字符串與一個整數進行比較? – Barmar

回答

1

該查詢應失敗:

SELECT * FROM test_table WHERE cast(phone as char) = '[email protected]'; 

原問題的原因是比較字符串和數字時,將字符串轉換爲數字(所以你可以寫where phone = '123')。您需要使用字段的明確轉換才能進行字符串到字符串的比較,以防止此默認轉換。

不幸的是,像這樣的轉換可能會阻止它使用索引。即使該字段已經是char,投射顯然會阻止其編入索引。

您也可以在輸入驗證期間解決它:如果phone是一個整數,則不允許用戶在搜索字段中提供非整數值。

+0

您重複我在上面關於性能的原始文章中表達的一些擔憂。索引的使用正是我所暗示的。我很高興你提出了我試圖利用的解決方案 - CAST功能。無論哪種情況,您都給了我一個有效的語法示例,這對我來說似乎很有用。我最初的測試沒有向我顯示任何與我正在使用的記錄數量有關的立即性能問題,所以我現在可能會確定。謝謝。 – Tanoro

+0

我在2.5M行的表上試了一下,查詢耗時7秒。 – Barmar

0

如何替換:

SELECT * FROM test_table WHERE phone = '[email protected]' 

與:

SELECT * FROM test_table WHERE phone = '[email protected]' and phone <> 0 

<>是指從不同的。

這將適用於您,因爲您在電話欄中使用0來表示沒有電話號碼(儘管在沒有電話號碼時使用NULL會更好)。

+0

這不一定有效。如果'phone'爲1,'WHERE phone ='1email @ example.com'將爲true。 – Barmar