【问题标题】:Having trouble with a procedure in MariaDBMariaDB 中的程序遇到问题
【发布时间】:2020-04-01 18:22:06
【问题描述】:

我正在使用 MariaDB 创建一个基本的机场管理系统 SQL 数据库。我想创建一个包含事务的过程,以确保: 每当乘客被转移到另一个航班时,与该乘客相关(属于)的行李将被转移到同一航班。我不断收到错误代码:

错误代码:1054。“字段列表”中的未知列“Flight_ID”

哪里出错了?这是我的程序代码以及数据库中的相关表:

Code for the procedure

Tables referenced

程序:

DELIMITER //
CREATE PROCEDURE PassengerTransfer (
    IN vPassportNo VARCHAR(9), vOldFlightID VARCHAR(4), vNewFlightID VARCHAR(4), OUT vStatus VARCHAR(45))
BEGIN
    START TRANSACTION;
    SET SQL_SAFE_UPDATES = 0;
    UPDATE TRAVELS
    SET Flight_ID = vNewFlightID
    WHERE Flight_ID = vOldFlightID AND Passport_no = vPassportNo;

    UPDATE CARRIES INNER JOIN LUGGAGE ON LUGGAGE.LuggageID = CARRIES.LuggageID
    SET CARRRIES.Flight_ID = vNewFlightID
    WHERE LUGGAGE.Passport_no = vPassportNo;

    IF (TRAVELS.Flight_ID = vNewFlightID AND TRAVELS.Passport_no = vPassportNo)
    AND (CARRIES.Flight_ID = vNewFlightID AND LUGGAGE.LuggageID = CARRIES.LuggageID
    AND LUGGAGE.Passport_no = vPassportNo)
        THEN SET vStatus = "Trasaction PassengerTransfer committed!"; COMMIT;
        ELSE SET vStatus = "Transaction PassengerTransfer rollback"; ROLLBACK;
    END IF;
END; //
DELIMITER ;

引用的表格:

CREATE TABLE Travels(
Passport_no varchar(9) not null,
Flight_ID varchar(4) not null,
PRIMARY KEY (Passport_no),
FOREIGN KEY (Flight_ID) REFERENCES Flight(Flight_ID) ON UPDATE CASCADE,  
FOREIGN KEY (Passport_no) REFERENCES Passenger(Passport_no) ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE TABLE Luggage(
LuggageID       varchar(5) not null,
Weight          decimal(4,2),                   
Passport_no     varchar(9) not null, 
PRIMARY KEY (LuggageID),
FOREIGN KEY(Passport_no) REFERENCES Passenger(Passport_no) ON UPDATE CASCADE
);

CREATE TABLE Carries(
LuggageID       varchar(5) not null,
Flight_ID   varchar(4) not null,
PRIMARY KEY (LuggageID)
);

【问题讨论】:

  • 复制并粘贴代码。 (我们想要它。)
  • 我认为这不是决定是否使用COMMIT 的有效方法——您正在处理数据的快照,因此必须设置该值。您需要在每个UPDATE 之后检查错误。

标签: sql database transactions mariadb procedure


【解决方案1】:

NEWOLD 关键字仅在触发器中可用,在过程中不可用。所以代码如下:

UPDATE TRAVELS SET NEW.Flight_ID = vNewFlightID
WHERE OLD.Flight_ID = vOldFlightID AND Passport_no = vPassportNo;

应该写成:

UPDATE TRAVELS 
SET Flight_ID = vNewFlightID
WHERE Flight_ID = vOldFlightID AND Passport_no = vPassportNo;

您的代码:

UPDATE CARRIES SET NEW.Flight_ID = vNewFlightID
WHERE LUGGAGE.LuggageID = CARRIES.LuggageID AND
LUGGAGE.Passport_no = vPassportNo;

应该写成:

UPDATE CARRIES 
   INNER JOIN LUGGAGE ON LUGGAGE.LuggageID=CARRIES.LuggageID
SET CARRIES.Flight_ID = vNewFlightID
WHERE LUGGAGE.Passport_no = vPassportNo;

【讨论】:

  • 进行了建议的更改,但它仍然给我完全相同的错误代码...:/
  • 您是否更改了其余代码?您无需检查对数据库所做的更改。如果出现错误,该过程将失败。
  • 我删除了新的。和老。前缀并重写了您指出的两个代码块。好像它无法识别我所引用的属性 Flight_ID。
  • 删除IF-子句。如前所述,您不需要检查您所做的更改和代码语法是否不正确。
  • 但是在程序中进行交易的想法是确保乘客和相关行李的转移“作为一个实体”发生。因此,例如,如果数据库(假设地)崩溃,在第二个关于行李的更新语句之前,那么整个事务应该回滚。所以我需要一种方法来检查两个更新语句是否都已执行。对?或者 SQL 是否已经知道在中断时回滚,因为更新语句是在事务范围内编写的?哪里语法不正确?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
  • 2017-10-07
相关资源
最近更新 更多