MySQL/MariaDB 存储过程编译时有拼写错误

Lee*_*Lee 3 mysql mariadb

我只是问了一个类似的问题,但结果是因为 MySQL 列名不区分大小写,而我造成了歧义。我接受了给出的建议,并在所有参数前加上了 p。问题是,如果我输入拼写错误的参数值,SP 仍然可以编译,但在运行时会失败。我能做些什么吗?

下面是一个例子:

DELIMITER $$

USE `MobiFit_Dev` $$

DROP PROCEDURE IF EXISTS `User_Signup` $$

CREATE DEFINER = `root` @`localhost` PROCEDURE `User_Signup` (
    pEmail VARCHAR (250),
    pHashedPassword BINARY(60),
    pFirstName VARCHAR (100),
    pLastName VARCHAR (100),
    pGender ENUM ('Male', 'Female'),
    pDateOfBirth DATE,
    pHeight DECIMAL (3, 2),
    pCurrentWeight DECIMAL (4, 1) 
    -- CALL User_Signup('lee@gmail.com', 'password', 'Lee', 'Brooks', NULL, NULL, NULL, NULL);
    -- CALL User_Signup('lee@gmail.com', 'password', 'Lee', 'Brooks', 'Male', CURRENT_DATE(), 1.85, 101.3);
) 
BEGIN
    DECLARE vRoleId INT;

    SELECT 
        id INTO vRoleId 
    FROM
        Role 
    WHERE `Code` = 'CUSTOMER' ;


    INSERT INTO USER (
        Email,
        HashedPassword,
        RoleId,
        FirstName,
        LastName,
        Gender,
        DateOfBirth,
        Height,
        CurrentWeight,
        CreatedAt
    ) 
    VALUES
        (
            pEmail,
            pHashedPassword,
            vRoleId,
            pFirstName,
            pLastName,
            pGender,
            pDateOfBirth,
            pHeight,
            pCurrentWeigh, << Note the typo, this still compiles
            UTC_TIMESTAMP()
        ) ;
END $$

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

Mic*_*bot 5

这里的解释与在另一个问题中发现的相同情况有关……这里的表达至少可能是模棱两可的,因此无法在定义的时间合理地进行验证。它可以指尚未定义的事物。

MySQL 在定义时验证存储过程的语法,但它不会验证任何潜在的歧义或在程序实际运行时可能变得有效的东西。

在存储过程中:

-- unambiguous

SET foo      -- definition rejected if 'foo' is not a valid local or system variable
    = bar;   -- definition rejected if 'bar' is not a valid local variable

-- potentially ambiguous, probably intended to be a column name if 'foo' isn't a variable
-- could be a reference to a not-yet-created or altered base or temp table

UPDATE buzzfizz SET foo = bar; -- checked for syntax only, server assumes you know best
Run Code Online (Sandbox Code Playgroud)

存储过程中引用的表在声明过程时甚至不必存在,或者在过程运行时可能具有不同的结构......毕竟,您可以在存储过程中创建表(基表和临时表)程序。如果一个过程只能针对已经存在的对象声明,这将严重缺乏灵活性。您还可以通过创建具有相同名称的临时表来“屏蔽”基表,这在这里会产生混乱的影响。

存储函数和事件遵循相同的一般规则,尽管那里的情况略有不同,因为这些程序确实与过程有所不同……例如,您不能在存储函数中创建基表,因为存储函数不是t 允许隐式或显式导致 a COMMIT

触发器有些不同,因为它们一被声明就被解析和缓存,所以如果它们的定义与它们定义的表不匹配(即,通过NEWOLD别名引用表中不存在的列),触发器被拒绝...但对其他表的引用未经过验证,因为其他表可能尚不存在,并且可能是“列名”的事物确实可以引用列或可以引用其他对象。

看法有些不同。它们在定义的时间被验证,并且被引用的对象必须存在。这就是为什么mysqldump生成 SQL 语句来创建一个与每个视图具有相同名称和大致相同列定义的虚拟表,只是后来导致这些表被删除并替换为视图本身。否则,如果视图引用了尚不存在的其他视图,则无法从备份中恢复视图。您可以从视图下更改底层对象,这将导致错误,稍后当您尝试访问该视图时......但是您可以通过将表放回其来修复以这种方式破坏的视图原始状态。当然,视图没有局部变量,不能创建或更改表或操作事务。