Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:如何防止插入所有列均为NULL的行?_Mysql_Null_Definition - Fatal编程技术网

MySQL:如何防止插入所有列均为NULL的行?

MySQL:如何防止插入所有列均为NULL的行?,mysql,null,definition,Mysql,Null,Definition,在我的MySQL表中,每一列本身都可以为NULL,但必须至少有一列具有非NULL值。目前,我正在将insert语句包装到一个存储过程中,以防止插入所有空行,但这当然不会阻止任何人使用本机insert语句,从而绕过我的包装过程 是否有“本机”方法来定义具有该约束的表?仅授予执行权限,以便用户或应用程序用户只能调用存储的进程 仅授予执行权限,以便用户或应用程序用户只能调用存储的进程 添加简单检查约束 CHECK(COALESCE(Field1, Field2, ... FieldN) IS NOT

在我的MySQL表中,每一列本身都可以为NULL,但必须至少有一列具有非NULL值。目前,我正在将insert语句包装到一个存储过程中,以防止插入所有空行,但这当然不会阻止任何人使用本机insert语句,从而绕过我的包装过程


是否有“本机”方法来定义具有该约束的表?

仅授予执行权限,以便用户或应用程序用户只能调用存储的进程

仅授予执行权限,以便用户或应用程序用户只能调用存储的进程

添加简单检查约束

CHECK(COALESCE(Field1, Field2, ... FieldN) IS NOT NULL)
更新:


发现mysql不支持检查约束解析,但忽略,一个可能的解决方法是:使用触发器查找添加简单的检查约束

CHECK(COALESCE(Field1, Field2, ... FieldN) IS NOT NULL)
更新:


发现mysql不支持检查约束解析,但忽略,一种可能的解决方法是:使用触发器查找

,因为mysql不强制检查约束,所以您可能希望使用触发器模拟检查约束。我建议查看这篇MySQL Forge文章:

其思想是将您的检查逻辑移动到触发器。如果检查失败,则调用通过引发唯一密钥冲突而失败的存储过程。这允许我们将描述性错误消息返回给客户端

您的触发器可能如下所示:

DELIMITER $$
CREATE TRIGGER check_not_all_null BEFORE INSERT ON your_table FOR EACH ROW
BEGIN
   IF COALESCE(field_1, field_2, field_3) IS NOT NULL THEN
      CALL fail('All fields cannot be null');
   END IF;
END $$
DELIMITER ;
我们需要使fail存储过程引发唯一的密钥冲突,以便在检查失败时中止插入。上述文章建议创建一个内存表,定义如下:

CREATE TABLE `Error` (                                                               
   `ErrorGID` int(10) unsigned NOT NULL auto_increment,                               
   `Message`  varchar(128) default NULL,                                
   `Created`  timestamp NOT NULL default CURRENT_TIMESTAMP
              ON UPDATE CURRENT_TIMESTAMP,           
    PRIMARY KEY (`ErrorGID`),                                                   
    UNIQUE KEY `MessageIndex` (`Message`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED 
然后,可以按如下方式实施失败存储过程:

DELIMITER $$
CREATE PROCEDURE `fail`(_message VARCHAR(128))
BEGIN
  INSERT INTO error (message) VALUES (_message);
  INSERT INTO error (message) VALUES (_message);
END$$
DELIMITER ;
双重插入将确保引发唯一密钥冲突。如果表中已经存在相同的消息,则在第一次插入时将引发冲突,但只要失败就无所谓

我们可以从命令行尝试失败存储过程:

mysql> CALL fail('All fields cannot be null');
ERROR 1062 (23000): Duplicate entry 'All fields cannot be null' for key 2

好消息是我们返回了一条可读的错误消息。但是,我们没有返回正确的错误代码,并且实际上没有重复的条目。这显然是此方法的一个限制,尤其是在使用错误处理的过程中更新或插入记录时,特别是在处理1062重复条目错误时。

由于MySQL不强制执行检查约束,您可能希望使用触发器模拟一个。我建议查看这篇MySQL Forge文章:

其思想是将您的检查逻辑移动到触发器。如果检查失败,则调用通过引发唯一密钥冲突而失败的存储过程。这允许我们将描述性错误消息返回给客户端

您的触发器可能如下所示:

DELIMITER $$
CREATE TRIGGER check_not_all_null BEFORE INSERT ON your_table FOR EACH ROW
BEGIN
   IF COALESCE(field_1, field_2, field_3) IS NOT NULL THEN
      CALL fail('All fields cannot be null');
   END IF;
END $$
DELIMITER ;
我们需要使fail存储过程引发唯一的密钥冲突,以便在检查失败时中止插入。上述文章建议创建一个内存表,定义如下:

CREATE TABLE `Error` (                                                               
   `ErrorGID` int(10) unsigned NOT NULL auto_increment,                               
   `Message`  varchar(128) default NULL,                                
   `Created`  timestamp NOT NULL default CURRENT_TIMESTAMP
              ON UPDATE CURRENT_TIMESTAMP,           
    PRIMARY KEY (`ErrorGID`),                                                   
    UNIQUE KEY `MessageIndex` (`Message`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED 
然后,可以按如下方式实施失败存储过程:

DELIMITER $$
CREATE PROCEDURE `fail`(_message VARCHAR(128))
BEGIN
  INSERT INTO error (message) VALUES (_message);
  INSERT INTO error (message) VALUES (_message);
END$$
DELIMITER ;
双重插入将确保引发唯一密钥冲突。如果表中已经存在相同的消息,则在第一次插入时将引发冲突,但只要失败就无所谓

我们可以从命令行尝试失败存储过程:

mysql> CALL fail('All fields cannot be null');
ERROR 1062 (23000): Duplicate entry 'All fields cannot be null' for key 2

好消息是我们返回了一条可读的错误消息。但是,我们没有返回正确的错误代码,并且实际上没有重复的条目。这显然是此方法的一个限制,尤其是在使用错误处理的过程中更新或插入记录时,特别是在处理1062重复条目错误时。

并非所有版本的MySQL都支持检查约束,不幸的是:@Daniel,谢谢。他非常惊讶。选中已解析但未使用的复选框:并非所有版本的MySQL都支持检查约束,不幸的是:@Daniel,谢谢。他非常惊讶。选中已解析但未使用的复选框:哇!非常感谢您的详细回复!!:-哇!非常感谢您的详细回复!!:-