2013-10-03 68 views
0

INSERT IGNORE不起作用,因爲實際上不存在關鍵衝突。如果相關行不存在,則插入

這是一個進度隊列。對於一個應用程序,我不希望兩行的狀態爲S(對於「啓動」)。但是其他應用程序應該能夠 - 特別是如果我想強制兩個工作項目一次發生,我可以。所以這就是爲什麼它不是數據庫約束。

因此,在SQL中說「插入不存在的地方」有點棘手。這工作:

insert into user_queue_google 
(user_id, status, start_timestamp) 
(select 221, 'S', NOW() FROM filter_type 
WHERE 221 not in (select user_id from user_queue_google where status = 'S') limit 1); 

的問題是filter_type是一個完全不相關的表,我才知道是小,恰好永遠是空的。如果由於某種原因它是空的,則會失敗。

我可以在我的SQL程序中避免這種非常可怕的黑客而不訴諸存儲的程序或IF/THEN邏輯嗎?

+0

[MySQL的條件插入]的可能重複(http://stackoverflow.com/questions/913841/mysql-conditional-insert) – pilcrow

回答

0

使用dual系統虛表

insert into user_queue_google (user_id, status, start_timestamp) 
select 221, 'S', NOW() 
from dual 
WHERE not exists 
(
    select user_id 
    from user_queue_google 
    where status = 'S' 
    and user_id = 221 
) 

您被許可爲其中沒有表被引用

Source

+0

文檔中的這一點怎麼樣 - 「MySQL可能會忽略這些子句。」那有多糟糕? – djechlin

0

您需要在情況下,虛擬表名指定DUAL有UNIQUE索引INSERT IGNORE有效工作。你可以做的就是添加一個附加列,默認的東西無害的,但可以更改爲唯一的關​​鍵是:

CREATE UNIQUE INDEX index_block ON user_queue_google (user_id, force); 

設置force爲具有DEFAULT 0列。如果要強制兩份工作在同一時間運行,將其設置爲別的東西,以避免衝突:

UPDATE user_queue_google SET status='S', force=UNIX_TIMESTAMP() WHERE user_id=221 

這會騰出插入新工作新插槽。

0

這應該工作:

insert into user_queue_google 
(user_id, status, start_timestamp) 
select 
    A.user_id, 
    A.status, 
    A.start_timestamp 
FROM 
    (SELECT 
    221 user_id, 
    'S' status, 
    NOW() start_timestamp) AS A 
    LEFT JOIN user_queue_google ON A.user_id = user_queue_google.user_id AND A.status = user_queue_google.status 
WHERE 
    user_queue_google.user_id IS NULL; 

見附表小提琴Insert if row doesn't exist

相關問題