我的表格如下:
表“帖子”
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'
所以我需要一个查询,检查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'));
使用该函数,仅当标记尚不存在时才插入“标记”,并返回现有标记或新创建标记的ID。 Yipeee:)
答案 0 :(得分:0)
您必须插入帖子,然后插入标签。 SQL中没有多表插入解决方案。
您甚至无法将帖子文本插入标签触发器的帖子,因为插入标签只能携带属于标签的列。
如果您需要避免在tags表中重复,可以使用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来自成功的最后一个INSERT并生成了一个id。
使用INSERT INTO posts (text,tag1,tag2,tag3)
重新进行更新。这叫做repeating groups。如果您需要四个标签怎么办?如果帖子只有两个标签怎么办?如何对具有给定标记的帖子进行索引搜索?