电脑技术学习

了解ASE中的外键验证技术

dn001

 看来并非所有的用户都了解有关 ASE 中的外键技术的一些问题。本文将通过说明一些鲜为人知的外键限制问题以及用于验证外键的各种查询,尽力填补这一知识空缺。我们还将演示一种用来分析和综合临时表的技术。

  外键和 ANSI 外部连接

  假定我们有两个名为 FK 和 PK 的表(其意图很明显)。表 FK 可以改动,这样 PK 就成了 FK 的主键表。或者,如果外键已经存在,则用批量拷贝程序 (BCP) 将数据复制到表 FK 即可。在其中任何一种情况下,外键限制都是无效的,尽管这些操作没有任何错误。

  我们如何确定是否存在无效外键呢?这可以通过使用 not in, not exists 语句、含有 group by 子句的外部连接或临时表来完成。不过,对 ASE 15.0 版以下的用户而言,最有效的途径是使用 ANSI 外部连接语法。(有关详细信息,请参阅 Rob Verschoor 的《Tips, Tricks & Recipes for Sybase ASE》一书,其中包括所有外键列均不可为空时的性能比较。)

  假设表 FK 包含可以为空的列 —A 和 B,并且与此对应的名称相同的列形成了表 PK 的唯一键或主键,则找出 FK 表中的无效外键所需的查询为:

  select FK.A, FK.B

  from FK

  left join PK

  on coalesce (FK.A, PK.A) = PK.A

  and coalesce (FK.B, PK.B) = PK.B

  where PK.A is NULL

  and PK.B is NULL

  and FK.A is not NULL

  and FK.B is not NULL

  什么是有效的外键值?

  由于引用约束,您期望现在可以“清除任何新数据。不过,ASE 仅支持最低外键要求。如果新行的 FK.A 或 FK.B 为 NULL,则(在检查或规则约束的限制范围内)另外一列可以是任意值!该行为符合 ANSI SQL-92 标准。

  如果存在可以为空的外键列,笔者当然喜欢有更多限制的行为。ANSI 为外键定义确定了两个附加选项,不过大多数 RDBMS 均不支持这两个选项。(根据 ISUG 的增强功能请求 2296,Sybase 计划将来支持下面的两个 ANSI 选项。)部分匹配 (Match Partial) 意味着对于包含任何 NULL 子键的行,该行的非 NULL 子键必须至少要有一个包含相同值的对应主键行。完全匹配 (Match Full) 则意味着只有在所有子键均为 NULL 时,才允许有“NULL 行。如果需要其中一个标准的话,您必须在外键表上创建或修改 insert 和 update 触发器。主键表上还需要有 Delete 和 update 触发器。

  现在,我们假设所有脏数据已经修改过,并且除外键限制外还创建了触发器。针对上述选项,我们回到“如何确定是否存在无效外键?这一问题上来。请执行下列符合部分匹配条件的语句:

  select FK.A, FK.B

  from FK

  left join PK

  on coalesce (FK.A, PK.A) = PK.A

  and coalesce (FK.B, PK.B) = PK.B

  where PK.A is NULL

  and PK.B is NULL

  and ((FK.A is not NULL) or (FK.B is not NULL))

  请执行下列符合完全匹配条件的语句:

  select FK.A, FK.B

  from FK

  left join PK

  on FK.A = PK.A

  and FK.B = PK.B

  where PK.A is NULL

  and PK.B is NULL

  and ((FK.A is not NULL) or (FK.B is not NULL))

  若 FK.A 不可为空,则应用 FK.A 来取代合并(FK.A、PK.A),并且去除这些查询中(FK.A 不可为 NULL)的条件。这会使性能有很大差别,因为上述 SQL 示例会用到表扫描,但若是对不可为空的列进行了建议的 SQL 更改,则将使用索引。