如何完成有关 Oracle 触发器的练习

2024-01-09

我必须解决这个关于触发器的练习:

考虑以下用于表示的关系数据库模式 项目信息:

人员(身份证、姓氏、姓名、国籍)

项目(姓名、经理、 起始年份,参与人数,国际)

人员(项目、人员 ID)

指定Oracle中需要的触发器来维护以下内容 完整性约束:

a) 参与项目的人数(属性 NumPeopleInvolved) 必须与元组数量一致 输入该项目的人员

b) 如果项目是国际性的(国际属性 仅假设两个值)那么该项目必须至少涉及两个 不同国籍的人

我对 b) 部分有疑问。

我不知道如何处理给定项目没有人员参与的情况。如果我尝试插入第一个人,我不能有两个不同国籍的人,因为我只有一个人。

这种情况应该如何处理呢?

我应该使用语句级触发器吗?我没有使用触发器的经验,所以我仍然不太清楚我可以/不能使用一种触发器做什么。

我尝试了这种方式,但它显然没有按预期工作:

CREATE TRIGGER InsertPersonnelInternational
AFTER INSERT ON Personnel
FOR EACH ROW
BEGIN
    SELECT ProjectName
    FROM Personnel INNER JOIN Project
    WHERE PersonID = :new.ID Project = Name

    SELECT International
    FROM Personnel INNER JOIN Project
      ON Project = Name

    SELECT COUNT(*) AS NumPersonnel
    FROM Personnel
    WHERE Project = :new.Project

    IF NumPersonnel >= 1 THEN
    BEGIN
        SELECT COUNT(*) AS NumNationalities
        FROM Personnel INNER JOIN Person
        ON Project = ProjectName
        GROUP BY Nationality

        IF International THEN
            IF NumNationalities = 1 Then
            BEGIN
                raise_application_error(-1)
            END
        ELSE
            IF NumNationalities <> 1 THEN
            BEGIN
                raise_application_error(-1)
            END
        END
    END
END

当表上有行级触发器时Personnel那么你不能在表上运行任何 SELECTPersonnel在触发器内 - 你会得到一个ORA-04091: table PERSONEL is mutating ... error.

我想你的老师期待的是这样的事情:

CREATE TRIGGER ProjectConsistency
    BEFORE INSERT OR UPDATE ON PROJECT
    FOR EACH ROW
    
    p_count INTEGER;
    n_count INTEGER;

BEGIN

    SELECT COUNT(*)
    INTO p_count
    FROM Personnel
    WHERE PROJECT = :new.NAME;
        
    IF :new.NumPeopleInvolved <> p_count THEN
        RAISE_APPLICATION_ERROR(-20010, 'The number of people involved in a project must be consistent with the number of tuples entered in Personnel for that project');
    END IF;

    IF :new.International = 'YES' THEN
        SELECT COUNT(DISTINCT Nationality)
        INTO n_count
        FROM Personnel
        WHERE PROJECT = :new.NAME;
        
        IF n_count < 2 THEN
            RAISE_APPLICATION_ERROR(-20010, 'The project must involve at least two people of different nationalities')
        END IF;    
    END IF;

END;

实际上,您不会使用触发器来实现此类要求,而是会使用 PL/SQL 过程。

属性NumPeopleInvolved是无用的,即多余的。通常你会通过以下方式解决它

UPDATE PROJECT proj 
SET NumPeopleInvolved = 
    (SELECT COUNT(*)
    FROM Personnel p
    WHERE PROJECT = :new.NAME)
WHERE NAME = :new.NAME;

例如,这样的更新可以通过触发器来完成。

实际上你也需要在表上使用类似的触发器Personnel and Person,因为人员可能会发生变化,项目会变得不一致。我不知道练习是否应该考虑这一点。

想象一下,一个人被释放,即从表 Person 中删除:

  • 应用程序会引发错误 - 人员无法被释放(如果人员因新冠死亡会发生什么:-))?
  • 项目会无效吗?
  • 项目会自动更新吗?

那么,你应该never引发错误,例如raise_application_error(-1)- 始终让用户知道出了什么问题!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何完成有关 Oracle 触发器的练习 的相关文章

随机推荐

  • ASP.Net 会话超时:为什么默认使用 20 分钟?

    在 ASP Net 中 默认会话超时设置为 20 分钟 为什么这样 这背后有什么具体原因吗 不应将其设置为高于 20 分钟 特殊情况除外 因为每个打开的会话都会占用内存 From MSDN 站点上的 Session Timeout http
  • 我可以控制 RealityKit 中的 Reality Composer 行为吗?

    我想使用 SwiftUI 制作一个按钮 当按下按钮时 模型将隐藏 我已经阅读了此链接中的教程 创建触发器 https developer apple com documentation realitykit creating a trigg
  • OpenGLES 中的屏幕到世界坐标转换是一项简单的任务吗?

    iPhone 上的屏幕与世界问题e 我有一个在 EAGLView 中渲染的 3D 模型 CUBE 我希望能够检测到何时触摸立方体的给定面 从任何方向角度 的中心 听起来很容易 但事实并非如此 问题 如何准确地将屏幕坐标 触摸点 与世界坐标
  • JAVAFX / WebView / WebEngine FireBugLite 或其他一些调试器?

    我正在开发一个应用程序 需要在应用程序的 WebView WebEngine 部分运行调试器 以便我可以更好地调试我的应用程序 但我在互联网上找到的注入 Firebug Lite 的代码由于某种原因无法正常工作 如果我在 Firefox 控
  • 处理来自 IOS 设备的请求时发生异常

    我正在尝试在 iOS 设备上播放视频 当我尝试玩时出现以下错误 27 Apr 2015 06 59 30 GET media 2015 04 VID 20150327 112644 mp4 HTTP 1 1 200 18 Exception
  • 未在 Blazor 服务器端应用程序中创建本地化 Cookie

    我设置了本地化Startup cs services AddLocalization options gt options ResourcesPath Resources and var supportedCultures new en U
  • 将代码从 RestSharp 转换为 HttpClient

    有人可以帮我将这个使用 RestSharp 的 ASP Net Core 示例 在我的 Web Api 中使用以使用来自 Auth0 的管理 API 转换为使用 HttpClient 的示例吗 var client new RestClie
  • 如何在Python中运行并行程序

    我有一个 python 脚本来使用 os subprocess 模块运行一些外部命令 但其中一个步骤需要花费大量时间 因此我想单独运行它 我需要启动它们 检查它们是否完成 然后执行下一个不并行的命令 我的代码是这样的 nproc 24 fo
  • 使用 PHP 保护文档

    我有一个简单的登录 访问控制系统来保护一些受限制的页面 但在这些页面内有一些需要保护的链接 即Word文档 因此 如果我将这些资源保留在 webroot 中 它们就可以通过 URL 访问 保护受限制页面内的这些资源的最佳方法是什么 我知道我
  • Activity.java 中的多个选定项 RecyclerView

    我有一个RecyclerView来自本地的数据JSON in CardView 当单击一个或某个项目时 更改所选项目的背景或突出显示 例如在 Line App 中编辑 但没有 Button 或 我需要在选定的项目上实现longpress 但
  • Aptana 配置:配置的解释器在文件系统中不存在

    标题里说的差不多了 我已经更新到最新版本了Aptana 在 Windows 上 现在我的解释器无法工作 我已经重新创建了PYTHONPATH变量 删除并重新配置python解释器Aptana 在我的项目中删除并重新创建它 仍然不起作用 它给
  • 有人知道为什么 lintr 将我的 jupyter r 内核的第一个字符串标记为红色吗?

    我刚刚在 vscode 中设置了 R 来与 Jupyter 笔记本一起使用 但它用红色标记了我的内核的第一个字符串 我收到的消息是 Failed to run diagnostics error in callr subprocess Ca
  • Openshift 将 wp-admin 重定向到 https

    在 WordPress 的常规选项中 我已将 WordPress 目录更改为 onhttp mywebsite com但 WordPress 仪表板仍处于 HTTPPS 中 导致混合内容警告 即使在 Firefox 上禁用混合内容过滤器后
  • Rails 单元测试是否应该访问数据库?

    我一直在为我的 Rails 应用程序编写测试 我使用 TestUnit 进行单元测试和功能测试 我也使用 Cucumber 进行 GUI 测试 但我发现http www dcmanges com blog rails unit record
  • 如何通过 Flutter web 直接发送电子邮件

    我正在构建一个 flutter web 我必须通过电子邮件将表单数据发送到我的 Gmail 电子邮件地址 我该怎么办 请帮我 我有用户 mailer 3 0 4 和 flutter email sender 2 2 2 但他们都没有工作 这
  • 在 Java 中什么时候适合使用引用相等与对象相等?

    我了解这两个术语之间的区别 以及如果您想检查两个对象是否具有引用或相同的值 您将使用什么方法 我的问题是 什么时候你必须检查两个对象是否具有相同的引用 而不是检查两个对象是否具有相同的内容或值 从来没有一次我必须检查两个对象是否具有相同的引
  • 未找到 ID 为“osgi”的插件

    我正在尝试建立一个项目 https github com fge btf https github com fge btf 本地使用 gradle 有一个插件 osgi 正在使用 但每当我构建它时 我都会收到错误插件未找到 我尝试过提供不同
  • 如何从gradle Android Studio中的jar文件中删除单个模块

    如何从 jar 文件中删除单个包 我有两个来自不同供应商的 SDK 并且两个 SDK 都有谷歌 gson包包含在 jar 文件中 因为这导致我在 android studio 中运行构建时出现问题 它显示下图中的错误 我知道如何从存储库中排
  • formControlName 和 FormControl 有什么区别?

    我在用着ReactiveFormsModuleAngular2 创建一个包含表单的组件 这是我的代码 foo component ts constructor fb FormBuilder this myForm fb group full
  • 如何完成有关 Oracle 触发器的练习

    我必须解决这个关于触发器的练习 考虑以下用于表示的关系数据库模式 项目信息 人员 身份证 姓氏 姓名 国籍 项目 姓名 经理 起始年份 参与人数 国际 人员 项目 人员 ID 指定Oracle中需要的触发器来维护以下内容 完整性约束 a 参