【问题标题】:SQL error: 'Column [name] cannot be null' when trying to insert into table that has trigger setSQL 错误:尝试插入已设置触发器的表时,“列 [名称] 不能为空”
【发布时间】:2021-05-07 20:40:29
【问题描述】:

我有一个触发器BEFORE INSERT,其中包含:

set new.order_id = concat(new.account_id, '.', lpad(new.id, 4, '0'))

现在,当我尝试使用 php 插入一些数据时:

$insertorder = '
INSERT INTO orders
(
  producten
)
VALUES
(
  "'.$conn->real_escape_string($encodedproductenarray).'"
)';

我收到以下错误:There was an error running the query [Column 'order_id' cannot be null]

所以我尝试像这样在order_id 列中插入一些数据:

$insertorder = '
INSERT INTO orders
(
  order_id,
  producten
)
VALUES
(
  "1"
  "'.$conn->real_escape_string($encodedproductenarray).'"
)';
$insertordercon = $conn->query($insertorder);

但这给出了同样的错误。为什么?我需要更改触发器中的某些内容吗?

触发器将account_idid(自动增量)与中间的一个点合并在一起,并将其设置为order_id

当我使用 phpmyadmin 插入空数据时,插入工作并且触发器也完成了它的工作(除了值是 0.0000,因为一切都是空的)但是由于某种原因,当使用下面的插入查询时我得到了错误。

【问题讨论】:

  • 注意在执行触发器之前验证列。

标签: mysql sql database triggers


【解决方案1】:

请检查 new.account_id 的可能值。如果它为空,那么连接的结果将为空,你会得到这个错误。

【讨论】:

  • 谢谢!这解决了它。
【解决方案2】:

触发器将 account_id 和 id(自动增量)与中间的一个点合并在一起,并将其设置为 order_id。

但在 BEFORE 触发器中,自动增量尚未生成值。所以id 为 NULL。

如果任何参数为 NULL,LPAD() 函数将返回 NULL。

mysql> select lpad(NULL, 4, '0');
+--------------------+
| lpad(null, 4, '0') |
+--------------------+
| NULL               |
+--------------------+

如果任何参数为 NULL,CONCAT() 函数将返回 NULL。

mysql> select concat('firstpart', '.', NULL);
+--------------------------------+
| concat('firstpart', '.', NULL) |
+--------------------------------+
| NULL                           |
+--------------------------------+

问题是您不能在 BEFORE 触发器中使用自动递增数字,也不能在 AFTER 触发器中更改 NEW.order_id

因此,您不能使用触发器根据自动增量值更改任何列。

您必须在 INSERT 之后的后续 UPDATE 中执行此操作。您可以在事务中执行这两个语句,这样其他会话就不会看到该行部分完成。

START TRANSACTION;

  INSERT INTO orders ...;

  UPDATE orders SET order_id = CONCAT(account_id, '.', LPAD(id, 4, '0'))
  WHERE id = LAST_INSERT_ID();

COMMIT;

P.S.:订单 #9999 之后会发生什么?

【讨论】:

  • 感谢您的解释。交易听起来是件好事。我以为在 9999 之后它会上升到 10000,但我想不是这样吗?我可能可以将 LPAD 和 concat account_id and id` 一起删除。
  • lpad 的典型用途是当您希望数字以一致的长度格式化时,对吧?但是9999之后,这个数字就更长了。是的,它会增加到 10000 甚至更多,但是你的 lpad 没有实际意义,因为这个数字已经超过 4 个字符。
【解决方案3】:

这部分不用你写:

(
  order_id,
  producten
)

当您使用 INSERT 指令时,您必须按顺序写入每列应具有的所有值。如果您想要一些“空”列,只需将值设为空即可。插入时使用此结构。

INSERT INTO table_name VALUES (value1,value2,value3)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    相关资源
    最近更新 更多