邮政编码/邮政编码只属于一个街道+城市

时间:2017-04-03 16:09:26

标签: sql triggers sql-server-2014

我有一个名为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 ║
║        ║                   ║             ║            ║
╚════════╩═══════════════════╩═════════════╩════════════╝

我知道这张桌子没有正常规范化,请不要介意。

1 个答案:

答案 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位数字。单个地址可以有多个邮政编码。