Mysql 如果不存在(在单个查询中),是否插入一对多关系?
考虑下表: 产品Mysql 如果不存在(在单个查询中),是否插入一对多关系?,mysql,sql,Mysql,Sql,考虑下表: 产品 +----+------+-------------+ | id | name | category_id | +----+------+-------------+ | 1 | foo | 1 | +----+------+-------------+ 类别 +----+------+ | id | name | +----+------+ | 1 | food | +----+------+ 现在假设有人发布了一个新产品: { "name"
+----+------+-------------+
| id | name | category_id |
+----+------+-------------+
| 1 | foo | 1 |
+----+------+-------------+
类别
+----+------+
| id | name |
+----+------+
| 1 | food |
+----+------+
现在假设有人发布了一个新产品:
{
"name": "bar",
"category": "drink"
}
在这种情况下,我们需要自动创建新类别:
INSERT IGNORE INTO categories (name) VALUES ('drink')
然后,我们最终可以插入实际的产品行:
INSERT INTO products (name, category_id) VALUES ('bar', SELECT id FROM categories WHERE name = 'drink')
然而,尽管这样做可行,但需要安全的事务设置,因为这似乎不是一个超级复杂的查询,我想知道是否可以将两个查询合并在一起(例如,将类别的插入查询放入产品插入的选择子查询中)?否,这是不可能的。但是,您可以做的是在product表上插入触发器之前创建一个
,并检查触发器内部是否存在该类别。如果它不存在,您可以在那里创建它
触发器将在与INSERT
-语句相同的事务中自动执行,因此不需要额外的事务
我看到的唯一问题是,当您忘记触发器时,您可能会开始纳闷,为什么每个新产品都会自动显示具有新类别的类别(类似的情况也发生在我身上)
更新:
您可以在中看到简单触发器的示例
您可以在插入前使用new.column\u name
在触发器中访问要插入的新值,因此对您来说,它将是新的。类别我建议不要插入忽略
,原因是@Bill Karwin。此外,如以下文件所述:
如果表格包含AUTO_INCREMENT
列并插入或更新行,则函数将返回AUTO_INCREMENT
值。例外:对于更新,在MySQL 5.1.12之前没有意义。但是,您可以通过使用解决此问题。假设id
是AUTO_INCREMENT
列。要使更新有意义,请按如下方式插入行:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
然后可以获得id
(无论是预先存在的还是新插入的),如下所述:
如果将记录插入到包含AUTO_INCREMENT
列的表中,则可以通过调用函数获取存储在该列中的值
[ deletia ]
当然,如果需要原子性,这些语句仍然需要在事务中执行。好主意!如何从触发器查询中访问类别名称?使用NEW.category
-查看我的答案更新中的更多详细信息和链接我得到的是“新的未知列类别”?如何定义触发器?在哪个表上?在插入产品之前创建触发器类别插入忽略到类别(名称)值(新的.category);嘿,我读到了关于“插入…重复密钥更新”,但决定反对它,因为我读到它增加了自动递增计数器。这是真的吗?正常插入的行是否会跳过ID?@bodokaiser:请参阅。
INSERT INTO categories (name) VALUES ('drink')
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
INSERT INTO products (name, category_id) VALUES ('bar', LAST_INSERT_ID());