mysql - 如何在 MySQL 中强制存储具有特定格式的数字(必须以除 0 以外的任何单个整数开头并且恰好是特定长度)?

标签 mysql

编辑:当我一直在阅读和回复优秀的回复时,我发现我原来的问题是不完整的。我更新了标题以及问题本身,使其更具体。我希望这是反射(reflect)我对这个问题的思考演变的一种可接受的方式。正如我所说, react 非常好,并引导我更准确地陈述问题。

这是重述的问题: 是否可以强制在 MySQL 中存储具有特定格式的数字?格式为:数字必须以除 0 以外的任何整数开头,且长度正好为 5 位数字。作为正则表达式,它看起来像这样:/[1-9]\d\d\d\d/。

有效示例:

10001
20002
33333

一些无效的例子:

00001
010
100
1000

如果有任何不同,该字段将用于连接。

有没有办法在 MySQL 中强制执行此“类型”?

谢谢! 格雷格

最佳答案

没有声明性的方法可以将列中存储的值限制在指定的域:“五位数字”。

我们认为这意味着这将存储为数字,并且不会有小数点。也就是说,规范只允许在 1000099999 范围内的五位正整数。

要让数据库强制执行此类型限制,我们需要实现 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/

相关文章:

php - 从复选框获取多个值并将其存储在 DB php 中

php - 我在 wamp 中的 mysql 数据库有什么问题?

mysql - 具有多重连接的数据库搜索

php - MySQL/PHP - 性能 - 缓存或实时查询

php - 如何检查数据库列中存在的字符串?

MySQL 和在 Hibernate 启动时导入存储过程

mysql - 如何改进试图从两个表中查找不同值的 MySql 查询?

MySQL异常: Execute SQL Transaction

mysql - 提高MySQL效率

mysql - 仅清除单个表的 Rake 任务