【问题标题】:Cannot find data after commiting in PL/SQL procedure?在 PL/SQL 过程中提交后找不到数据?
【发布时间】:2009-12-07 20:39:00
【问题描述】:

我的 PL/SQL 过程中有代码 sn-p,它执行以下操作:

INSERT INTO payment_operations (id, subscriber, amount, description) VALUES (payment_id, 1234, 5, 'Test');
COMMIT;

SELECT subscriber INTO test_subscriber FROM payment_operations_view WHERE id = payment_id;

在此之后我得到一个异常“no_data_found”!但是,如果我在运行过程后自己执行相同的 SELECT 语句,我会看到记录。

请注意,我是从视图中选择,而不是直接从表中选择。为什么我插入后看不到这些数据?

【问题讨论】:

  • 我的理解是Oracle的默认隔离级别允许SELECT在提交之前达到峰值。
  • 你的代码背后的想法是好的,但是你的陈述“如果我做同样的 SELECT 语句......”让我想知道你是否对 PL/SQL 变量和 column_names 有一些混淆 - 是视图中有一个名为 payment_id 的列?
  • 你使用的是默认的事务隔离级别吗?
  • 这是“标准”视图还是物化视图?

标签: sql oracle


【解决方案1】:

这是一种预感:

payment_options 表是否有 payment_id 列?

我问是因为在以下语句中,在 PL/SQL 中,如果 payment_id 作为列存在,那么将使用该列而不是本地 PL/SQL 变量:

SELECT subscriber 
INTO test_subscriber 
FROM payment_operations_view 
WHERE id = payment_id;

由于它使用payment_id 列,如果它存在,并且由于它没有在插入中设置,您可能正在执行where id = null,它永远不会评估为真。

我使用 v_ 来表示变量。因此,您的 sn-p 将变为(其余程序相应更改):

INSERT INTO payment_operations (id, subscriber, amount, description) 
VALUES (v_payment_id, 1234, 5, 'Test');    
COMMIT; 

SELECT subscriber 
INTO v_test_subscriber 
FROM payment_operations_view WHERE id = v_payment_id;  

【讨论】:

    【解决方案2】:

    看起来您所指的视图是“物化”视图。如果是,请在获取数据之前尝试此代码 sn-p 手动刷新视图:

    ...
        INSERT INTO payment_operations (id, subscriber, amount, description) VALUES (payment_id, 1234, 5, 'Test');
    
        COMMIT;
    
        DBMS_SNAPSHOT.REFRESH( 'payment_operations_view','c');
        SELECT subscriber INTO test_subscriber FROM payment_operations_view WHERE id = payment_id;
    
        DBMS_OUTPUT.PUT_LINE('--> ' || test_subscriber);
    
    ...
    

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      您正在插入基表,然后从视图中进行选择。视图是否有任何过滤条件?如果是这样,您插入的数据可能与视图的条件不匹配。

      正如其他人指出的那样,视图也有可能是物化视图,在这种情况下可能需要刷新。

      我不得不问......为什么逻辑需要选择你刚刚插入的数据?除非您期望其他东西修改了 INSERT 和 SELECT 之间的数据,否则为什么不直接使用您刚刚插入的 subscriber 值而不是查询来再次获取它?

      【讨论】:

        【解决方案4】:

        在插入语句后显式放置一个提交并检查。

        在我看来,在插入之后实际发生提交之前,select 语句正在运行。

        【讨论】:

        • @Rajat:在 INSERT 和 SELECT 语句之间有一个COMMIT;
        • 即使他没有包含 COMMIT,这也不是问题。
        猜你喜欢
        • 1970-01-01
        • 2016-04-03
        • 2013-08-24
        • 2012-06-09
        • 2023-03-11
        • 1970-01-01
        • 2016-06-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多