如何在 SAP ASE Sybase 16 中从具有外键的表中删除行

Posted

技术标签:

【中文标题】如何在 SAP ASE Sybase 16 中从具有外键的表中删除行【英文标题】:How to delete rows from tables with foreign keys in SAP ASE Sybase 16 【发布时间】:2019-11-01 00:20:37 【问题描述】:

我正在尝试从表employee 中执行行删除,该表employee 在'emp_id' 列上设置了主键,并被其他表及其外键引用。 Sybase 不允许我执行删除。返回的示例味精是:

引用完整性约束中的依赖外键约束违反。 dbname = 'giraffe',表名 = 'branch',约束名 = 'client_800002850'。 命令已中止。

如果您使用 ON DELETE 子句指定外键,则使用 mysql 可以轻松地进行这种删除,但 Sybase 不支持。此 RDBMS 中外键的唯一可选子句是 'MATCH FULL'

如果设置了外键,如何在 Sybase 中删除行或将值设置为 NULL?我是 t-sql 和 DBA 的新手。据我了解,拥有这样的数据库模式,它根本不需要外键,或者我错过了什么?也许这个模式是 MySQL 特定的,它应该以不同的方式编码以满足 Sybase t-sql 标准?

这里是 DDL。课程链接 - https://www.youtube.com/watch?v=HXV3zeQKqGY

============================

    CREATE TABLE employee (
      emp_id INT PRIMARY KEY,
      first_name VARCHAR(40),
      last_name VARCHAR(40),
      birth_day DATE,
      sex VARCHAR(1),
      salary INT,
      super_id INT,
      branch_id INT
    );

    CREATE TABLE branch (
      branch_id INT PRIMARY KEY,
      branch_name VARCHAR(40),
      mgr_id INT,
      mgr_start_date DATE,
      FOREIGN KEY(mgr_id) REFERENCES employee(emp_id) ON DELETE SET NULL
    );

    ALTER TABLE employee
    ADD FOREIGN KEY(branch_id)
    REFERENCES branch(branch_id)
    ON DELETE SET NULL;

    ALTER TABLE employee
    ADD FOREIGN KEY(super_id)
    REFERENCES employee(emp_id)
    ON DELETE SET NULL;

    CREATE TABLE client (
      client_id INT PRIMARY KEY,
      client_name VARCHAR(40),
      branch_id INT,
      FOREIGN KEY(branch_id) REFERENCES branch(branch_id) ON DELETE SET NULL
    );

    CREATE TABLE works_with (
      emp_id INT,
      client_id INT,
      total_sales INT,
      PRIMARY KEY(emp_id, client_id),
      FOREIGN KEY(emp_id) REFERENCES employee(emp_id) ON DELETE CASCADE,
      FOREIGN KEY(client_id) REFERENCES client(client_id) ON DELETE CASCADE
    );

    CREATE TABLE branch_supplier (
      branch_id INT,
      supplier_name VARCHAR(40),
      supply_type VARCHAR(40),
      PRIMARY KEY(branch_id, supplier_name),
      FOREIGN KEY(branch_id) REFERENCES branch(branch_id) 

这是此“员工”表的约束列表

branch_1008003591 branch FOREIGN KEY (mgr_id) REFERENCES employee(emp_id) 2019 年 6 月 18 日上午 11:58 employee_880003135 员工 FOREIGN KEY (branch_id) REFERENCES branch(branch_id) 2019 年 6 月 18 日上午 10:44 works_with_848003021 works_with FOREIGN KEY (emp_id) REFERENCES employee(emp_id) 2019 年 6 月 17 日晚上 7:26 employee_752002679 员工外键(super_id)自引用员工(emp_id)2019 年 6 月 17 日晚上 7:24 employee_960003420 employee FOREIGN KEY (super_id) SELF REFERENCES employee(emp_id) MATCH FULL 2019 年 6 月 18 日上午 11:17 employee_6720023941 主键索引(emp_id):集群,外引用

我要执行以下 DML:

DELETE from dbo.employee
WHERE employee.emp_id = 102

在那个 MySQL 课程中,如果 'branch' 表的外键已使用 ON DELETE SET NULL 子句设置,则后续自动操作会将 branch.mgr_id 值从 102 设置为 NULL。

我尝试将 branch.mgr_id 设置为 NULL,因为它不是表的 PK,但显然它没有帮助。

【问题讨论】:

【参考方案1】:

快速的答案是,您将在删除主行以删除依赖项之前更新下面的依赖表 - 将以前数据模型所需的外键列在目标表中保留为空(IMO 无论如何)是不好的做法。在您的示例中,员工创建了数据,例如与该员工相关联的分支数据 - 当然,您不会只是返回 null,因为这可能会严重影响诸如使用内部连接或基于这些 ID 分组的每个分支的报告并且不考虑员工 ID 为空。

如果这是类似于此示例的业务需求,您可以添加一个删除触发器,该触发器将对相关数据进行更新: http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc32300.1550/html/sqlug/X15877.htm

【讨论】:

【参考方案2】:

删除主键行时,删除从属表中对应的外键行。这通过确保在删除主行时删除详细信息行来保持参照完整性。如果您不删除相关表中的相应行,您最终可能会得到一个包含无法检索或识别的详细行的数据库。要正确删除相关外键行,请使用执行级联删除的触发器。

对titles 执行delete 语句时,会从titles 表中删除一行或多行并添加到deleted。 触发器可以检查相关表(titleauthor、salesdetail 和 roysched)以查看它们是否有任何带有 title_id 的行,该行与从标题中删除的 title_ids 匹配并且现在存储在已删除的表中。如果触发器找到任何此类行,则会将其删除。

create trigger delcascadetrig 
on titles 
for delete 
as 
delete titleauthor 
from titleauthor, deleted 
where titleauthor.title_id = deleted.title_id 
/* Remove titleauthor rows that match deleted
** (titles) rows.*/
delete salesdetail 
from salesdetail, deleted 
where salesdetail.title_id = deleted.title_id 
/* Remove salesdetail rows that match deleted
** (titles) rows.*/ 
delete roysched 
from roysched, deleted 
where roysched.title_id = deleted.title_id 
/* Remove roysched rows that match deleted
** (titles) rows.*/

来源:-

“http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc32300.1600/doc/html/san1390612501571.html”

【讨论】:

嘿安库什。事实上,触发器涵盖了 sybase 中的引用完整性。这是 mysql 中 ON DELETE 主键参数的对应项。不方便,但很管用 如果可行,请接受或喜欢该解决方案。谢谢

以上是关于如何在 SAP ASE Sybase 16 中从具有外键的表中删除行的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Sybase ASE smalldatetime/datetime/bigdatetime 转换为标准格式

如何使用 Kafka Connect for Sybase ASE 数据库实现变更数据捕获 (CDC)?

Sybase ASE 15.7 - 如何将两个数据库中的对象合并到一个数据库中?

sybase ase 怎样修改表的所有者

linux下如何启动和停止sybase的服务

带有 Sybase ASE 15.5 的 LINQToEntities