我有一个名为ADDRESS的表,其中包含以下列:
╔════════╦════════════╦═════════════╦════════════╗
║ City ║ Street ║ HouseNumber ║ PostalCode ║
╠════════╬════════════╬═════════════╬════════════╣
║ ║ ║ ║ ║
║ London ║ 1st street ║ 5 ║ 1234 ║
║ London ║ 1st street ║ 6 ║ 1234 ║
║ Stoke ║ 1st street ║ 6 ║ 1235 ║
║ ║ ║ ║ ║
╚════════╩════════════╩═════════════╩════════════╝
我想创建一个触发器,在更新或插入后检查只有一个城市+街道组合属于一个邮政编码。上面的表格应该是可能的。此触发后,下表中的示例不可能。因此,如果postalCode尚不存在,则插入/更新必须继续。如果postcal代码退出,它必须检查它是否有效,如果是:插入/更新它,如果没有:rollback。
我真的必须保留这个表的结构,另一个选项对我来说是不可能的。
╔════════╦═══════════════════╦═════════════╦════════════╗
║ City ║ Street ║ HouseNumber ║ PostalCode ║
╠════════╬═══════════════════╬═════════════╬════════════╣
║ London ║ 1st street ║ 5 ║ 1111 ║
║ London ║ 1st street ║ 6 ║ 1111 ║
║ Stoke ║ 2nd street ║ 15 ║ 1111 ║
║ London ║ 1st street ║ 5 ║ 1115 ║
║ ║ ║ ║ ║
╚════════╩═══════════════════╩═════════════╩════════════╝
我知道这张桌子没有正常规范化,请不要介意。
答案 0 :(得分:0)
首先,我假设街道列是标准化的。这对于这类工作来说确实是必要的。
我不会使用触发器来执行此操作。我会用另一张桌子做这个。出于严格的验证目的,您可以定义:
create table ValidCityStreet (
City varchar(255) not null,
Street varchar(255) not null,
PostalCode varchar(255),
primary key (City, Street), -- this ensures only one postal code
unique (City, Street, PostalCode) -- good for a foreign key reference
);
然后,将外键约束添加到Address
:
alter table address add constraint fk_address_city_street
foreign key (city, street) references ValidCityStreet(city, street);
alter table address add constraint fk_address_city_street_postalcode
foreign key (city, street) references ValidCityStreet(city, street, postalcode);
这确保了每个城市/街道组合只有一个邮政编码(因为ValidCityStreet
中的主键)。并且Address.PostalCode
匹配它(因为第二个外键引用)。
也就是说,您需要一个(简单的)触发器来将新值插入ValidCityStreet
。
说了这么多,您可以考虑将city
/ street
对存储在带有邮政编码的表中。然后更改地址表以引用该表中的一行,其中门牌号是Address
中的单独列。
我应该注意到在美国,完整的邮政编码有9位数字。单个地址可以有多个邮政编码。