我使用 Mysql Workbench 创建了一个表ORDER
,如下所示:
CREATE TABLE IF NOT EXISTS `rr`.`ORDER` (
`Order No.` INT UNSIGNED NOT NULL COMMENT 'The order of the inspected equipment',
`Order_Type` CHAR(8) NOT NULL COMMENT 'External or Internal work',
`Engine_Description` VARCHAR(45) NOT NULL COMMENT 'Description of the Engine',
`Equipment_Quantity` INT UNSIGNED NOT NULL COMMENT ' Number of the inspected equipment',
`Required_Task` VARCHAR(8) NOT NULL COMMENT 'Whether Repair or Overhaul',
PRIMARY KEY (`Order No.`))
ENGINE = InnoDB
COMMENT = '\n';
所以我需要知道如何制定一个约束条件,如果Order_Type
字段的值为“外部”,那么该值的值Engine_Description
将自动为,NULL
否则将添加一个值?
另外,如果我想对两个不同的实体做同样的事情?
这可以使用MySQL >= 8.0.16
CHECK
中的约束非常优雅地完成,如下所示(fiddle available here):你的桌子(略有变化)
填充它:
然后
结果:
到目前为止,一切都很好。
然后我们尝试这样做:
我们收到错误消息:
这正是我们想要的!
为了涵盖
or else a value will be added?
问题中的情况,我认为您的意思是- 如果我们特别从要编辑的值列表中DEFAULT
排除如下:engine_description
INSERT
我们
SELECT
:我们获得:
我强烈建议你升级到 MySQL 8——它现在是 8.0.22 版,所以现在任何主要的版本变化问题都已经解决了——你会得到各种各样的好处——比如
CHECK
我刚刚概述的约束,COMMON TABLE EXPRESSION
s(可用从 8.0.1,又名WITH
子句)和GENERATED
列(5.7.5)。如果您无法升级到版本 8,那么您将不得不使用
TRIGGER
s(根据@nbk 的回答),但您要求限制,所以这就是我提供的。另外,你到底是什么意思:
如果您的意思是同一个表(-table)中两个字段之间的约束
intra
,那么您有上面的示例,如果您的意思是两个表之间(inter
-table),那么在任何服务器(bar Firebird)上,您都必须使用TRIGGER
s!最后,提个建议——不要使用SQL 关键字作为表名或列名(在这种情况下
Order
)——这会造成混淆,使调试更加困难,而且不是好的做法。通常,我使用单数表名,但我(显然)为 s 做了一个例外ORDER
- 表是一个集合,应该是单数(恕我直言)。ps 欢迎来到论坛!
正如我在评论中所说,为此目的使用触发器
如此处所示,您已将每个约束都添加为 if 子句到您的触发器。因为 mysql 5.x 不支持
CHECK
约束另请注意,这
Order
是一个保留字,您不应在表名或列名中使用它们,否则您必须始终在每个查询中使用反引号您的字段
Engine_Description
被声明为NOT NULL所以它不能被设置为 NULL 我将它设置为一个空的描述db<>在这里摆弄