mysql - 无法创建 MySQL/MariaDB 存储过程

标签 mysql database stored-procedures mariadb

我有一个包含 20 万条记录的 XML 文件。我必须插入或更新数据库中的记录。我的数据库结构如下:

+----+------+-------+-----+-----+------------+
| Id | name | stock | sku | ean | updated_by |
+----+------+-------+-----+-----+------------+

为了插入记录,我使用了 Doctrine。但是需要很长时间才能插入或更新所有记录。因此我想创建一个存储过程。

我尝试了以下存储过程,但它不起作用。

delimiter $$
create trigger insert
before insert on Product
for each row
begin
IF(exists(select 1 From Product WHERE sku = new.sku))
THEN
    BEGIN
    UPDATE Product SET stock = new.stock WHERE sku = sku;
    END;    
END IF;
end$$
delimiter

错误:

General error: 1442 Can't update table 'Product' in stored function/trigger because it is already used by statement which invoked this stored function/trigger

更新:

最佳答案

您不能按照您描述的方式使用 MySQL 触发器。您不能更新为其定义了触发器的表。这将导致无限循环。

即使您编写的触发器代码有效,MySQL 也不支持“代替”触发器。也就是说,它会执行 UPDATE,但随后它也会尝试 INSERT。因此,它会创建具有相同 sku 值的另一行,否则如果您对 sku 有唯一约束,插入将导致错误并回滚 INSERT并从触发器运行更新。

这就是为什么 REPLACEINSERT...ON DUPLICATE KEY UPDATE陈述存在。

我知道您想对所有操作使用 ORM 方法,但这将是一般规则的一个很好的例子:ORM 不支持所有操作。您不可避免地会遇到这样的情况如果您想做一些特别的事情,请编写 SQL。与所有 ORM 库一样,Doctrine 支持一种绕过 ORM 方法运行文字 SQL 语句的方法。

参见 Doctrine: ON DUPLICATE KEY UPDATE例如。

关于mysql - 无法创建 MySQL/MariaDB 存储过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57837037/

相关文章:

插入触发器后的 MySQL - MyISAM 与 InnoDB

php - Mysql搜索设计

SQL 查询 - 长时间运行/占用 CPU 资源

mysql - 按条件加入新列

php - 从表中选择所有属性和某些属性在 codeigniter 中得到不同的结果

mysql - 列出 MySQL 表外键的高效方法?

sql - 如何只允许sql中的某些字符(oracle)

MYSQL从存储过程中的准备语句获取更新的行数

mysql - 使用 C# 调用存储过程

c# - 使用 Entity Framework 从存储过程中获取数据