2011-08-31 81 views
3

在我的表,我有兩個領域:v_idip_address。只有當IP地址不存在時,我纔想將一些數據插入此表中。INSERT INTO查詢只如果記錄不存在

Google'ing後,我遇到了INSERT IGNORE INTO聲明,這是我的代碼:

public function update_visits($ip_address) 
{ 
    $sql = 'INSERT IGNORE INTO `24h_visits` (ip_address) VALUES (?)'; 
    if($this->db->query($sql, array($ip_address))) 
    { 
     return TRUE; 
    } 
    return FALSE; 
} 

它運行正常,沒有錯誤,但重複的行仍在做,即使同一IP傳遞作爲參數。

任何人都得到了線索?謝謝。

+0

是ip_address表上的主鍵? –

+0

也許你可以使用'WHERE NOT EXISTS' – ocodo

回答

5

UNIQUE約束添加到您的ip_address列。

然後,如果您的查詢嘗試添加重複的ip_address行(除非您使用INSERT IGNORE),則會失敗。

+0

+1爲是第一:) –

6

你必須爲INSERT IGNORE創建ip_address一個UNIQUE指數工作:

ALTER TABLE 24h_visits 
    ADD UNIQUE INDEX(ip_address) 

然而,我還沒有看到你的架構的全部,但我認爲有一個列存儲上次訪問的時間戳。這是唯一有意義的方法(所以你可以每隔24小時清除訪問次數)。

在這種情況下,你其實不想INSERT IGNORE,但INSERT ... ON DUPLICATE KEY UPDATE代替。假設你有一欄叫last_visit

INSERT INTO 24h_visits (ip_address, last_visit) 
    VALUES ('$ip_address', NOW()) 
    ON DUPLICATE KEY UPDATE last_visit = NOW(); 

隨着INSERT IGNORE,新行是永遠不會插入,這樣的話你總是有第一個值永遠插在last_visit,這(我看到它的方式)不完全正確。

+1

+1'UNIQUE'約束是最好的方式。您可以在數據庫中加強完整性。 – alex

+0

@alex:你今天是如此DBAish :-) – zerkms

+1

@zerkms不同的日子,不同的帽子:d – alex

3

其他的答案實際上不回答這個問題:創建唯一索引防止被插入,這是一個好主意重複的,但它並沒有回答「如何插入如果不是已經在那裏。」
這是你如何做到這一點:

INSERT IGNORE INTO 24h_visits (ip_address) 
select ? 
where not exists (select * from 24h_visits where ip_address = ?) 

此外,這種方法不需要對架構進行任何更改。

+2

我試圖回答與不是有人問這個問題,但我相信OP實際上想要。 – NullUserException

+0

我只是對你的初始答案進行了大膽的處理*放一個獨特的索引,我認爲這是一個糟糕的主意 - 那麼在正常處理過程中你必須處理異常。當然把這個指數,但你不想*避免*例外 – Bohemian