mysql (SQL)输入验证不起作用,输入被设置为INT并设置一个条件(如果输入是十进制),但它仍然接受非整数(如2.52)

kuhbmx9i  于 2023-01-29  发布在  Mysql
关注(0)|答案(1)|浏览(94)

我现在正在学习SLQ(MySQL),我正在玩参数验证。我正在构建一个过程,返回具有特定id的客户作为输入参数(要求提供id,然后返回该客户的所有收据)。
我想添加两个验证条件,第一个用于负数(有效),第二个用于十进制数(因为customer_id总是整数)。
我很困惑为什么即使我指定数据类型为INT,程序也接受十进制数,为什么我添加的条件也不起作用,如果我输入一个十进制数(如3.24),它返回的结果就好像id是十进制数的整数部分一样(id = 3时返回)。
有人能解释一下为什么会发生这种情况,以及如何建立一个有效的验证吗?谢谢!
我的代码

BEGIN
    IF 
        customer_id != TRUNCATE(customer_id,0) THEN SIGNAL SQLSTATE '58002' SET MESSAGE_TEXT = 'Invalid id code1';
    ELSEIF  customer_id<0 THEN SIGNAL SQLSTATE '58002' SET MESSAGE_TEXT = 'Invalid id code2';
    ELSE
            SELECT * FROM receipts r WHERE customer_id = r.customer_id; 
    
    END IF;
END
mzsu5hc0

mzsu5hc01#

处理参数的方式取决于服务器是否处于严格模式。请考虑以下简单的存储过程-

CREATE PROCEDURE `test_sp`(IN customer_id INT)
BEGIN
    SELECT customer_id;
END

如果会话以非严格模式运行-

SET @@session.sql_mode = sys.list_drop(@@session.sql_mode, 'STRICT_ALL_TABLES');
SET @@session.sql_mode = sys.list_drop(@@session.sql_mode, 'STRICT_TRANS_TABLES');

CALL test_sp(3.24); # outputs 3
CALL test_sp(3.54); # outputs 4
CALL test_sp(-3.24); # outputs -3
CALL test_sp(-3.54); # outputs -4

传入sp的十进制值会自动四舍五入,不会出现任何错误或警告。如果我们在严格模式下执行相同操作,则会得到完全相同的结果,不会出现任何错误或警告-

SET @@session.sql_mode = sys.list_add(@@session.sql_mode, 'STRICT_ALL_TABLES');

CALL test_sp(3.24); # outputs 3
CALL test_sp(3.54); # outputs 4
CALL test_sp(-3.24); # outputs -3
CALL test_sp(-3.54); # outputs -4

因此,无论我们是否处于严格模式,十进制值总是四舍五入以给予有效的整数输入。
如果我们这样定义sp,我们得到的结果会略有不同-

CREATE PROCEDURE `test_sp`(IN customer_id INT UNSIGNED)
BEGIN
    SELECT customer_id;
END

在非严格模式下同样的四个调用我们得到-

SET @@session.sql_mode = sys.list_drop(@@session.sql_mode, 'STRICT_ALL_TABLES');
SET @@session.sql_mode = sys.list_drop(@@session.sql_mode, 'STRICT_TRANS_TABLES');

CALL test_sp(3.24); # outputs 3
CALL test_sp(3.54); # outputs 4
CALL test_sp(-3.24); # outputs 0
CALL test_sp(-3.54); # outputs 0

所以负值会被强制为0如果我们检查,就会发出警告-

mysql> SHOW WARNINGS;
+---------+------+------------------------------------------------------+
| Level   | Code | Message                                              |
+---------+------+------------------------------------------------------+
| Warning | 1264 | Out of range value for column 'customer_id' at row 1 |
+---------+------+------------------------------------------------------+
1 row in set (0.00 sec)

现在,在严格模式下做同样的事情,我们得到了不同的结果-

SET @@session.sql_mode = sys.list_add(@@session.sql_mode, 'STRICT_ALL_TABLES');

CALL test_sp(3.24); # outputs 3
CALL test_sp(3.54); # outputs 4
CALL test_sp(-3.24); # Error Code: 1264. Out of range value for column 'customer_id' at row 1
CALL test_sp(-3.54); # Error Code: 1264. Out of range value for column 'customer_id' at row 1

因此,您尝试检查十进制输入失败,因为在它到达代码之前,该值已经舍入为整数。

相关问题