我获得了错误代码1442用于在MySQL中创建触发器,而我的其他触发器的另一个语法错误?我该如何修复?

发布于 2025-02-05 16:26:05 字数 2549 浏览 4 评论 0原文

我正在尝试在MySQL中创建触发器,但是我收到了语法错误消息。这是我创建表并插入值的代码:

第一表:

CREATE TABLE widgetSale (
id INTEGER auto_increment,
item_id INT,
customer_id INT,
quan INT,
price INT,
reconciled INT,
primary key (id));

INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (1, 3, 5, 1995, 0);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (2, 2, 3, 1495, 1);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (3, 1, 1, 2995, 0);
SELECT * FROM widgetSale;

我的第一个表的第一个触发器:

delimiter //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale for each row
BEGIN
IF NEW.reconciled = 1 THEN
SIGNAL SQLSTATE VALUE '45000'
  SET MESSAGE_TEXT = 'cannot update table "widgetSale" after it has been reconciled';
END IF;
END
//

这是我的表格为时间戳创建触发器的表:

DROP TABLE IF EXISTS widgetSale;
CREATE TABLE widgetCustomer(
id integer auto_increment,
name TEXT,
last_order_id INT,
stamp TEXT,
primary key(id) );

CREATE TABLE widgetSale (
id integer auto_increment,
item_id INT, 
customer_id INTEGER,
quan INT, 
price INT, 
stamp TEXT,
primary key(id) );

CREATE TABLE widgetLog (
id integer auto_increment,
stamp TEXT, 
event TEXT, 
username TEXT, 
tablename TEXT, 
table_id INT,
primary key(id));

INSERT INTO widgetCustomer (name) VALUES ('Bob');
INSERT INTO widgetCustomer (name) VALUES ('Sally');
INSERT INTO widgetCustomer (name) VALUES ('Fred');
SELECT * FROM widgetCustomer;

delimiter //
CREATE TRIGGER stampSale before insert on widgetSale for each row 
BEGIN
SET NEW.stamp = CURDATE();
update widgetCustomer set last_order_id = new.item_id where widgetCustomer.id = new.customer_id;
update widgetCustomer set stamp = new.stamp;
INSERT INTO widgetLog (stamp, event, username, tablename, table_id) VALUES (NEW.stamp, 'INSERT ', 'TRIGGER', 'widgetSale', NEW.customer_id);
END
//

INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (1, 3, 5, 1995);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (2, 2, 3, 1495);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (3, 1, 1, 2995);

SELECT * FROM widgetSale;
SELECT * FROM widgetCustomer;
SELECT * FROM widgetLog;

所以我的问题是:

  1. 我无法创建第一个触发器因为似乎在MySQL中不存在增加功能。建议我使用信号语句,但我不知道我应该放置什么语法?

  2. 我能够为时间戳创建触发器,但我有错误代码1442。我不知道我的语法出了什么问题?

*更新:我现在能够解决我的问题,对于第二个触发器,事实证明我需要在插入之前创建触发器,而不是在插入后(因为否则我无法更新表),并编写了两个更新语句以更新widgetCustomer表我想更新ID和邮票列,并且必须通过编写两个单独的更新语句来做到这一点。

I'm trying to create TRIGGERS in MySQL but I got a syntax error message. Here's my code for creating the tables and inserting the values:

The first table:

CREATE TABLE widgetSale (
id INTEGER auto_increment,
item_id INT,
customer_id INT,
quan INT,
price INT,
reconciled INT,
primary key (id));

INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (1, 3, 5, 1995, 0);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (2, 2, 3, 1495, 1);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (3, 1, 1, 2995, 0);
SELECT * FROM widgetSale;

My first trigger for the first table:

delimiter //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale for each row
BEGIN
IF NEW.reconciled = 1 THEN
SIGNAL SQLSTATE VALUE '45000'
  SET MESSAGE_TEXT = 'cannot update table "widgetSale" after it has been reconciled';
END IF;
END
//

And here are my tables to create trigger for timestamps:

DROP TABLE IF EXISTS widgetSale;
CREATE TABLE widgetCustomer(
id integer auto_increment,
name TEXT,
last_order_id INT,
stamp TEXT,
primary key(id) );

CREATE TABLE widgetSale (
id integer auto_increment,
item_id INT, 
customer_id INTEGER,
quan INT, 
price INT, 
stamp TEXT,
primary key(id) );

CREATE TABLE widgetLog (
id integer auto_increment,
stamp TEXT, 
event TEXT, 
username TEXT, 
tablename TEXT, 
table_id INT,
primary key(id));

INSERT INTO widgetCustomer (name) VALUES ('Bob');
INSERT INTO widgetCustomer (name) VALUES ('Sally');
INSERT INTO widgetCustomer (name) VALUES ('Fred');
SELECT * FROM widgetCustomer;

delimiter //
CREATE TRIGGER stampSale before insert on widgetSale for each row 
BEGIN
SET NEW.stamp = CURDATE();
update widgetCustomer set last_order_id = new.item_id where widgetCustomer.id = new.customer_id;
update widgetCustomer set stamp = new.stamp;
INSERT INTO widgetLog (stamp, event, username, tablename, table_id) VALUES (NEW.stamp, 'INSERT ', 'TRIGGER', 'widgetSale', NEW.customer_id);
END
//

INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (1, 3, 5, 1995);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (2, 2, 3, 1495);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (3, 1, 1, 2995);

SELECT * FROM widgetSale;
SELECT * FROM widgetCustomer;
SELECT * FROM widgetLog;

So my problem is:

  1. I could not create the first trigger because it seems the raise function does not exist in MySQL. I was advised to use Signal statement but I don't know what syntax should I put?

  2. I was able to create the trigger for timestamps but I got error code 1442. I don't know what went wrong with my syntax?

*Updated: I was able to solve my problems now, for the second trigger, turns out I need to CREATE TRIGGER BEFORE INSERT, not AFTER INSERT (because otherwise I cannot update the table), and wrote two UPDATE statements to update the widgetCustomer table in which I want to update the id and the stamp column, and I have to do that by writing two separate UPDATE statements.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生来就爱笑 2025-02-12 16:26:05

从上面注释线程中的错误摘要:

在MySQL客户端定义存储的例程时,您需要使用定界符。参见 https:// https://dev.mysq..mysql.com/doc.com/doc/doc/doc /refman/8.0/en/stored-programs-defining.html

使用Signal> Signal语句在MySQL存储的例程中提出错误。请参阅 https://dev.mysql.com/dev.mysql.com/doc/doc/doc/refman/8.8.8.8.8.8.8..0. /en/signal.html
您的条件似乎是Conledeced = 1,并且您在将触发器催生为new.reconconciled的行中引用该列。您无需从表中选择即可获取该列。

delimiter //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale
BEGIN
  IF NEW.reconciled = 1 THEN
    SIGNAL SQLSTATE VALUE '45000'
      SET MESSAGE_TEXT = 'cannot update table "widgetSale" after it has been reconciled';
  END IF;
END
//

用户blabla_bingo注意到您在某些不属于的插入语句中错误地引用了对帐。我想这是Copy&粘贴一些代码行。

RE错误1442:MySQL不允许您插入/更新/删除触发触发器的同一表。换句话说,如果触发器是用于widgetsale 上的操作,那么您不能在该触发器中更新widgetsale 。

但是,您无需更新表即可更改扳机产生的当前行中的一列。您只需使用new.columnname喜欢以下内容引用当前行的列,以将一个列设置为标量值:

SET NEW.stamp = CURDATE();

curdate()是编写的等效方法。日期(现在())

Summary of errors from above comment thread:

You need to use DELIMITER when defining stored routines in the MySQL client. See https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html

Use the SIGNAL statement to raise errors in a MySQL stored routine. See https://dev.mysql.com/doc/refman/8.0/en/signal.html
Your condition appears to be reconciled = 1, and you reference that column in the row that spawned the trigger as NEW.reconciled. You don't need to SELECT from the table to get that column.

delimiter //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale
BEGIN
  IF NEW.reconciled = 1 THEN
    SIGNAL SQLSTATE VALUE '45000'
      SET MESSAGE_TEXT = 'cannot update table "widgetSale" after it has been reconciled';
  END IF;
END
//

User blabla_bingo noticed you had mistakenly referenced reconciled in some INSERT statements where it didn't belong. I guess it was the result of copy & paste of some lines of code.

Re error 1442: MySQL does not allow you to INSERT/UPDATE/DELETE the same table for which the trigger was spawned. In other words, if the trigger is for an operation ON widgetSale, then you can't UPDATE widgetSale in that trigger.

But you don't need to UPDATE the table to change one column in current row for which the trigger spawned. You simply reference the columns of current row with NEW.columnName like the following to set one column to a scalar value:

SET NEW.stamp = CURDATE();

CURDATE() is an equivalent way of writing DATE(NOW()).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文