编辑:当我一直在阅读和回复优秀的回复时,我发现我原来的问题是不完整的。我更新了标题以及问题本身,使其更具体。我希望这是反射(reflect)我对这个问题的思考演变的一种可接受的方式。正如我所说, react 非常好,并引导我更准确地陈述问题。
这是重述的问题: 是否可以强制在 MySQL 中存储具有特定格式的数字?格式为:数字必须以除 0 以外的任何整数开头,且长度正好为 5 位数字。作为正则表达式,它看起来像这样:/[1-9]\d\d\d\d/。
有效示例:
10001
20002
33333
一些无效的例子:
00001
010
100
1000
如果有任何不同,该字段将用于连接。
有没有办法在 MySQL 中强制执行此“类型”?
谢谢! 格雷格
最佳答案
没有声明性的方法可以将列中存储的值限制在指定的域:“五位数字”。
我们认为这意味着这将存储为数字,并且不会有小数点。也就是说,规范只允许在 10000
到 99999
范围内的五位正整数。
要让数据库强制执行此类型限制,我们需要实现 BEFORE INSERT 和 BEFORE UPDATE 触发器。
例如,每当尝试插入或更新超出范围的值时,我们都可以将通用 SQLSTATE 引发为错误。
假设mycol
被定义为整型:
DELIMITER $$
CREATE TRIGGER mytable_bi
BEFORE INSERT ON mytable
FOR EACH ROW
BEGIN
IF NOT ( NEW.mycol >= 10000 AND NEW.mycol <= 99999 ) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'value out of range 10000 to 99999'
, COLUMN_NAME = 'mycol'
, TABLE_NAME = 'mytable'
;
END IF;
END$$
还需要类似的BEFORE UPDATE
触发器。
在早期版本的 MySQL 中不支持 SIGNAL
,我们可以通过引发错误来模拟它。 (抛出错误将阻止触发 INSERT 或 UPDATE 操作成功完成。)代替 SIGNAL
,我们可以执行保证抛出错误的 SQL 语句。
另一种选择是对“域表”使用外键约束。
创建一个只有一列的表(与 mycol
相同的数据类型)并用一组所有可能的有效值填充它,并忽略所有无效值。 p>
CREATE TABLE five_digit_integers (i INT NOT NULL PRIMARY KEY );
INSERT INTO five_digit_integers VALUES (10000),(10001),(10002),...;
...
INSERT INTO five_digit_integers VALUES ...,(99998),(99999);
然后,创建一个外键约束:
ALTER TABLE mytable
ADD CONSTRAINT FK_mytable_mycol_five_digit_integer
FOREIGN KEY (mycol) REFERENCES five_digit_integer (i)
;
尝试在 mytable.mycol 中插入或更新“超出范围”的值将导致外键约束错误,并阻止 INSERT 或 UPDATE 成功完成。
当然,这不会阻止有人向 five_digit_integers
表中插入额外的值,或者通过发出 SET FOREIGN_KEY_CHECKS=0
来绕过约束。
关于mysql - 如何在 MySQL 中强制存储具有特定格式的数字(必须以除 0 以外的任何单个整数开头并且恰好是特定长度)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42448986/