由于表变异,触发器无法执行

2023-12-26

我想知道这个问题是什么问题,当我执行存储过程时,它不断向我显示此错误。我的目标是在使用存储过程将数据更新到表中之前,我想检查用户输入的触发器中的错误

SQL> exec PRC_PAY_TRIP(1031,2031,'Cash',200)
BEGIN PRC_PAY_TRIP(1031,2031,'Cash',200); END;

*
ERROR at line 1:
ORA-04091: table TEST.PAYMENT is mutating, trigger/function may not see it
ORA-06512: at "TEST.TRG_PAYMENT_VALIDATION", line 10
ORA-04088: error during execution of trigger 'TEST.TRG_PAYMENT_VALIDATION'
ORA-06512: at "TEST.PRC_PAY_TRIP", line 45
ORA-06512: at line 1

我去搜索问题,解决方案之一就是简单地将触发器内的“之后”更改为“之前”

“付款更新之前”-->像这样

但还是不行

存储过程

CREATE OR REPLACE PROCEDURE PRC_PAY_TRIP(CUST_ID IN NUMBER,PAYMENT_ID IN NUMBER,PAYMENT_TYPE IN VARCHAR2,AMT_PAY IN NUMBER)AS


v_paymentstatus VARCHAR2(15) := 'Paid';
v_temppaymentid NUMBER(4) := PAYMENT_ID;
v_truenumber NUMBER(10);


no_null_on_custID EXCEPTION;
no_null_on_payID EXCEPTION;
invalid_paymentid EXCEPTION;
invalid_paymenttype EXCEPTION;
invalid_paymentamt EXCEPTION;


BEGIN

v_truenumber := v_temppaymentid-1000;


IF CUST_ID < 0
THEN
RAISE no_null_on_custID;
END IF;

IF PAYMENT_ID < 0
THEN
RAISE no_null_on_payID;
END IF;

IF CUST_ID ^= v_truenumber THEN
RAISE invalid_paymentid;
END IF;

IF PAYMENT_TYPE ^= 'Cash' AND PAYMENT_TYPE ^= 'E-Wallet' THEN
RAISE invalid_paymenttype;
END IF;

IF AMT_PAY < 0 THEN
RAISE invalid_paymentamt;
END IF;



UPDATE Payment
SET paymenttype = PAYMENT_TYPE,paymentdate = TO_CHAR(sysdate,'DD/MON/YYYY'), paymentstatus = v_paymentstatus
where paymentid = PAYMENT_ID;


EXCEPTION

WHEN no_null_on_custID then
DBMS_OUTPUT.PUT_LINE('Invalid Customer ID');

WHEN no_null_on_payID then
DBMS_OUTPUT.PUT_LINE('Invalid Payment ID');

WHEN invalid_paymenttype then
DBMS_OUTPUT.PUT_LINE('You can either choose Cash or E-Wallet only!');

WHEN invalid_paymentid then
DBMS_OUTPUT.PUT_LINE('Payment id is not yours, just add 1000 from your Customer ID and that will be your Payment ID');

WHEN invalid_paymentamt then
DBMS_OUTPUT.PUT_LINE('Amount pay cannot be negative value!');

END;
/

TRIGGER

CREATE OR REPLACE trigger trg_payment_validation
 before update on payment
 for each row

DECLARE

 v_paymentstatus payment.paymentstatus%type;
 v_customerid booking.customerid%type;
 v_paymentid payment.paymentid%type;
 v_paymentamt payment.paymentamount%type;

BEGIN 

select po.paymentstatus into v_paymentstatus
 from payment po
 where po.paymentid = :new.paymentid;


select po.paymentamount into v_paymentamt
 from payment po
where po.paymentid = :new.paymentid;

if SQL%FOUND then
    if v_paymentstatus = 'Paid' then
      RAISE_APPLICATION_ERROR(
        -20950,
        'You already paid for your trip, have a nice day'
      );
    elsif v_paymentamt < :old.paymentamount then
      RAISE_APPLICATION_ERROR(
        -20950,
        'Insufficient amount entered, pls pay the exact amount'
      );
    end if;
  end if;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    NULL;
END;
/

如果您在更新时检查同一行中的数据,则不要使用SELECT声明,而是检查:NEW and :OLD绑定变量:

CREATE OR REPLACE trigger trg_payment_validation
  before update on payment
  for each row
BEGIN 
  if :OLD.paymentstatus = 'Paid' then
    RAISE_APPLICATION_ERROR(
      -20950,
      'You already paid for your trip, have a nice day'
    );
  elsif :NEW.paymentamount < :old.paymentamount then
    RAISE_APPLICATION_ERROR(
      -20950,
      'Insufficient amount entered, pls pay the exact amount'
    );
  end if;
END;
/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

由于表变异,触发器无法执行 的相关文章

  • 如何在 SQL 中选择“上一条”和“下一条”记录?

    I am building a blog post detail page on my site that will display display a previous and next link similar to how a typ
  • Postgres 上的 C 语言环境和 Posix 语言环境有什么区别?

    我知道 Postgres 上的数据库区域设置负责国家字符的正确顺序 正确的小写 大写等 但为什么有两种语言中立的语言环境 posix and c 它们之间有什么区别 还是只是一个中立的语言环境有两个不同的名称 UPDATE正如 Magnus
  • 如何手动设置auto_increment的下一个值?

    我手动向表中添加了一些行 并且还手动设置了 ID 自动增量 现在 当我尝试通过我的应用程序将新行添加到数据库表中时 我收到错误 创建的 ID 值已存在 如何手动设置下一个ID值 例如 在表中我必须有ID 那么如何告诉PostgreSQL 下
  • 使用sqlbulkcopy之前如何创建表

    我有一个 DBF 文件 我正在尝试导入该文件 然后将其写入 SQL 表 我遇到的问题是 如果我使用 SqlBulkCopy 它需要我提前创建表 但在我的场景中这是不可能的 因为 dbf 文件不断变化 到目前为止 这是我的代码 public
  • 在 WHERE 子句中使用可选参数

    我有一个SP ALTER PROCEDURE dbo sp Compare lst varchar 100 frst varchar 100 NULL passportNo varchar 50 NULL AS SELECT FROM db
  • 如何使用 ALTER TABLE 添加新列并使其唯一?

    我该如何使用ALTER TABLE添加新列并使其独一无二 取决于 DBMS 但我认为以下内容相当可移植 ALTER TABLE table name ADD column name datatype ALTER TABLE table na
  • 如何在Oracle中将“(Ab56.12345)some_string”的一个字符串列拆分为两列“Ab.12345”,“some_string”

    正如问题一样 如何拆分一个字符串列 Ab56 12345 some string到两列Ab56 12345and some string在甲骨文中 注意 并非所有列都 Ab56 12345 some string 部分列仅some stri
  • xQuery LIKE 运算符?

    有没有办法以与 SQL 相同的方式使用 XQuery 执行 LIKE 操作 我不想构造一些 startswith endswith 和 contains 表达式 我想要实现的目标的示例 for x in user where x first
  • PostgreSQL & regexp_split_to_array + 取消嵌套

    我有这样的绳子 测试1 纽约 X 测试 2 芝加哥 Y 测试 3 宾夕法尼亚州哈里斯堡 Z 我需要的结果是 Column1 Column 2 Column3 Test 1 new york X Test 2 chicago Y Test 3
  • C# 查询两个数据库的数据

    我目前有一个查询 我正在从两个不同的数据库获取数据 这些数据被附加到一个名为 accountbuys 的列表中 我的第一个表有三个数据条目 3个想要购买股票的帐户 下一张表有 17 个数据点 购买 17 只股票 I am merging t
  • 在bigquery中比较两个表的有效方法

    我有兴趣比较两个表是否包含相同的数据 我可以这样做 standardSQL SELECT key1 key2 FROM SELECT table1 key1 table1 key2 table1 column1 table2 column1
  • SQL 查询结果为字符串(或变量)

    是否可以将SQL查询结果输出到一个字符串或变量中 我的php和mysql不好 假设我有数据库 agents 其中包含列 agent id agent fname agent lname agent dept 使用此查询 sql SELECT
  • 如何显示 RSpec 测试生成的 SQL 查询日志?

    我正在为我的 Rails 3 应用程序编写规范 我想测试数据库事务是否真的有效 如果能够看到我的应用程序在规范驱动下生成的 sql 查询 这将非常有帮助 有没有办法像在 Rails 控制台中一样查看查询 我正在使用 Rails 3 0 9
  • 如何将变量设置为触发器 MYSQL 内存储过程的结果?

    我这里有一个小问题 我正在为我的数据库工作创建一个触发器 但我不知道如何在触发器内使用存储过程 我想将过程的结果保存在变量中 然后使用稍后在 IF 比较器上变量 这是我的代码 DELIMITER CREATE TRIGGER insert
  • If Else 条件的 SQLite 语法

    我正在使用 SQLite 数据库 我的表有一个名为 密码 的文本列 早些时候 为了检索我用来执行简单操作的值select from myTable询问 但现在的要求是 如果Password值不是NULL那么我需要将其显示为 是 或 否 它是
  • Solr 增量导入不起作用

    我使用的是solr 4 2 请注意 完全导入有效 但增量导入却无效 增量导入不会给出任何错误 但不会获取任何更改 这是数据配置文件
  • jDBI中如何进行内查询?

    我怎样才能在 jDBI 中执行这样的事情 SqlQuery select id from foo where name in
  • 从 C# 使用 Odbc 调用 Oracle 包函数

    我在 Oracle 包中定义了一个函数 CREATE OR REPLACE PACKAGE BODY TESTUSER TESTPKG as FUNCTION testfunc n IN NUMBER RETURN NUMBER as be
  • ActiveRecord 查询,按关联排序,最后一个 has_many

    我试图列出所有Users by the created at最近创建的关联记录 通讯 列 到目前为止我所拥有的 User includes communications order communications created at IS
  • 将十六进制转换为字符串

    我想用HEXTORAW 从 ASCII 十六进制代码 30 获取 char 值 ASCII HEX 30 应返回 varchar 0 该怎么做呢 是HEXTORAW 正确的功能 你可以使用utl raw http docs oracle c

随机推荐