2013-03-20 22 views
0

我的表是這樣的:MySQL的插入,如果不存在於連接表

表「上崗」

posts.id = PK, auto-increment 
posts.text = varchar 
posts.tag_id 1 = int, FK to tags.id 
posts.tag_id 2 = int, FK to tags.id 
posts.tag_id 3 = int, FK to tags.id 

表「標籤」

tags.id = PK, auto-increment 
tags.tag = varchar 

現在我想插入以下數據:

text: 'lorem ipsum' 
tag1: 'music' 
tag2: 'pop' 
tag3: 'singer' 

所以我需要aq uery檢查tag1/tag2/tag3是否已經存在於「tags」中,否則插入它們,然後將它們作爲外鍵+「text」插入到「posts」中的新行中。

我看了一下mysql INSERT IF NOT EXISTS,但我只是卡住了,不知道從哪裏開始。我知道我可以用多個查詢處理它,但必須有另一種更輕的方法才能達到相同的結果。

有沒有人有這方面的經驗?

更新

我的一個朋友提出這樣的:

CREATE FUNCTION getTagID(tag VARCHAR('100')) RETURNS int 

INSERT INTO posts (text,tag1,tag2,tag3) 
VALUES ('lorem ipsum', getTagID('music'), getTagID('pop'), getTagID('singer')); 

當然getTagId的實施,至今下落不明,但是這是否合理? getTagID應該選擇帶給定標籤的id,如果它不存在,插入它並返回它。任何幫助表示讚賞。

解決方案

我創建MySQL中的自定義函數:

DELIMITER ;; 

CREATE FUNCTION getTagID(tag VARCHAR(100)) RETURNS BIGINT 
BEGIN 
    DECLARE tagID BIGINT; 
    SET tagID = (SELECT id FROM tags WHERE text = tag); 
    IF tagID IS NULL 
    THEN 
    INSERT INTO tags (text) VALUES (tag); 
    SET tagID = (SELECT LAST_INSERT_ID()); 
    END IF; 
    RETURN tagID; 
END;; 

DELIMITER ; 

,現在我可以插入帖子這樣的:

INSERT INTO posts (text,tag1,tag2,tag3) 
VALUES ('lorem ipsum', getTagID('music'), getTagID('pop'), getTagID('singer')); 

與功能,插入只有在標籤尚不存在時纔將其轉換爲「標籤」,並返回現有標籤或新創建的標籤的標識。 Yipeee :)

回答

0

你必須插入到文章,然後插入標籤。 SQL中沒有多表插入解決方案。

您甚至無法將帖子文本插入標籤觸發器中的帖子,因爲插入標籤只能包含屬於標籤的列。

如果您需要避免標記表中的重複項,則可以使用INSERT IGNORE或REPLACE或INSERT ... ON DUPLICATE KEY UPDATE。請參閱我對"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"的回答以瞭解更多詳情。


重新發表您的評論。

只有讓自動遞增機制生成新的ID,您才能獲得生成的PK。如果你讓自動增量發生,你保證不會導致重複的PK。

如果您指定一個ID並繞過自動增量,則無論如何您都無法獲取該ID。但是,如果您在INSERT中指定了值,則不需要查詢該值 - 您應該已經擁有該值。

唯一的另一種情況是,如果您有一個不是自動遞增的輔助唯一鍵。

CREATE TABLE foo (id int auto_increment primary key, name varchar(10), unique key (name)); 
INSERT INTO foo (name) VALUES ('bill'); 
SELECT LAST_INSERT_ID(); -- returns 1 
INSERT INTO foo (name) VALUES ('bill'); 
SELECT LAST_INSERT_ID(); -- returns 1 

這是稍顯混亂,因爲最後一個插入ID來自最後插入成功和生成的ID。


重新與INSERT INTO posts (text,tag1,tag2,tag3)更新。這就是repeating groups。如果你需要四個標籤怎麼辦?如果帖子只有兩個標籤會怎麼樣?你如何使用給定標籤對帖子進行索引搜索?

+0

謝謝!如果我使用INSERT IGNORE,插入後是否可以獲得PK?我可以在1次交易中的下一個聲明中使用它嗎? – 2013-03-20 14:35:22

+0

我在應用程序服務器端使用PDO/PHP – 2013-03-20 14:35:38

+0

在上面添加了另一個想法...沒有人關心;) – 2013-03-21 11:00:17