如果符合条件,是否可以插入新行?
例如,我的表没有主键也没有唯一性
+----------+--------+
| image_id | tag_id |
+----------+--------+
| 39 | 8 |
| 8 | 39 |
| 5 | 11 |
+----------+--------+
如果image_id和tag_id的组合不存在,我想插入一行 例如;
INSERT ..... WHERE image_id!=39 AND tag_id!=8
答案 0 :(得分:7)
我想你在说:你需要避免在这个表中重复行。
有很多方法可以解决这个问题。最简单的一个:
INSERT INTO theTable (image_id, tag_id) VALUES (39, 8)
WHERE NOT EXISTS
(SELECT * FROM theTable
WHERE image_id = 39 AND tag_id = 8)
正如@Henrik Opel指出的那样,你可以在组合列上使用检查约束,但是你必须在其他地方使用try / catch块,这会增加不相关的复杂性。
编辑以解释该评论......
我假设这是一张映射电影和标签之间多对多关系的表格。我意识到你可能正在使用php,但我希望下面的C#伪代码足够清楚。
如果我有Movie
课程,添加标签的最自然方式是AddTag()
方法:
class Movie
{
public void AddTag(string tagname)
{
Tag mytag = new Tag(tagname); // creates new tag if needed
JoinMovieToTag(this.id, mytag.id);
}
private void JoinMovieToTag(movie_id, tag_id)
{
/* database code to insert record into MovieTags goes here */
/* db connection happens here */
SqlCommand sqlCmd = new SqlCommand("INSERT INTO theTable... /* etc */");
/* if you have a check constraint on Movie/Tag, this will
throw an exception if the row already exists */
cmd.ExecuteNonQuery();
}
}
在此过程中没有切实可行的方法来检查重复项,因为其他用户可能随时标记电影,因此无法解决此问题。
注意:如果尝试插入欺骗记录意味着存在错误,则抛出错误是合适的,但如果不是,则不希望错误处理程序中出现额外的复杂性。
答案 1 :(得分:0)
尝试使用数据库触发器,根据对表的更新,将行添加到不同的表中。
答案 2 :(得分:0)
我假设你的意思是你要插入一行,如果它不包含那些值。
我没有MySQL在我面前,但在一般的SQL中这应该有效:
INSERT INTO a_table (image_id, tag_id) SELECT ? image_id, ? tag_id WHERE image_id!=39 AND tag_id!=8
如果您只想在根本不存在这样的行时插入行,那么您可以这样做:
INSERT INTO a_table (image_id, tag_id) SELECT ? image_id, ? tag_id WHERE not exists (SELECT 1 from a_table WHERE image_id!=39 AND tag_id!=8)
答案 3 :(得分:0)
如果您正在使用带有转码的InnoDB,那么您可以先查询数据,然后在您的代码中随后执行插入,如果现在已经找到了包含值的行。或者,在两列上添加唯一的constaint,然后尝试插入。如果失败,如果它已经存在,你可以忽略。 (这比我的第一种方法更不优选。)
答案 4 :(得分:0)
当他发现我们都忽视了包括我在内的一个简单的唯一约束条件时,是否可以归功于Henrik Ope l。最终是最好的解决方案。
答案 5 :(得分:0)
To avoid duplicate row insertion use the below mentioned query:
INSERT INTO `tableName` ( `image_id`, `tag_id`)
SELECT `image_id`, `tag_id` FROM `tableName`
WHERE NOT EXISTS (SELECT 1
FROM `tableName`
WHERE `image_id` = '39'
AND `tag_id` = '8'
);