【问题标题】:Flashback versions query闪回版本查询
【发布时间】:2013-10-03 09:54:16
【问题描述】:

select 语句返回两行

编号 ||描述 1 两个 2 两个

我有点期待三行

编号 ||描述 1 个 1 两个 2 两个 根据link 的声明 阅读It returns all the committed occurrences of the rows for a query of an object, while NOT displaying the UNCOMMITTED row versions. 代码如下:-


CREATE TABLE digits
(id NUMBER(2),
description VARCHAR2(15));
INSERT INTO digits VALUES (1,'ONE');
UPDATE digits SET description ='TWO' WHERE id=1;
INSERT INTO digits VALUES (2,'TWO');
COMMIT;
DELETE FROM digits;
SELECT id,description FROM digits
VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE;

我能想到的唯一原因是,如果 timestamp minvalue 和 maxvalue 采用 DML 时间戳值而不是 DDL 值.....请对此有所了解!

【问题讨论】:

    标签: sql oracle flashback


    【解决方案1】:

    您认为缺少的行将来自此:

    INSERT INTO digits VALUES (1,'ONE');
    

    ...但数据从未在该状态下提交,因为:

    UPDATE digits SET description ='TWO' WHERE id=1;
    

    ... 发生在您的 COMMIT 之前。因此,这与您引用的语句一致,1, ONE 不是该行的已提交事件。从来没有任何时间点可以让另一个会话看到这些值。

    如果您查看version data pseudocolumns,您会发现这两行都被视为插入当前数据:

    CREATE TABLE digits (id NUMBER(2), description VARCHAR2(15));
    EXEC dbms_lock.sleep(10);
    
    INSERT INTO digits VALUES (1,'ONE');
    UPDATE digits SET description ='TWO' WHERE id=1;
    INSERT INTO digits VALUES (2,'TWO');
    COMMIT;
    
    SELECT id, description, versions_xid, versions_operation
    FROM digits
    VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE;
    
            ID DESCRIPTION     VERSIONS_XID     V
    ---------- --------------- ---------------- -
             2 TWO             08001B005C0D0100 I
             1 TWO             08001B005C0D0100 I
    

    如果您在第一个 insertupdate 之间提交,您可以看到这三行以及它们是如何修改的:

    CREATE TABLE digits (id NUMBER(2), description VARCHAR2(15));
    EXEC dbms_lock.sleep(10);
    
    INSERT INTO digits VALUES (1,'ONE');
    COMMIT;
    EXEC dbms_lock.sleep(10);
    
    UPDATE digits SET description ='TWO' WHERE id=1;
    INSERT INTO digits VALUES (2,'TWO');
    COMMIT;
    
    SELECT id, description, versions_xid, versions_operation
    FROM digits
    VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE;
    
            ID DESCRIPTION     VERSIONS_XID     V
    ---------- --------------- ---------------- -
             2 TWO             060018007C0C0100 I
             1 TWO             060018007C0C0100 U
             1 ONE             05000B00450C0100 I
    

    我不完全确定为什么需要 SLEEP 调用,但没有它们就无法正常工作(伪列是空白的,只显示当前数据)。我认为我从未见过对此的良好解释,但在实际案例中这不太可能成为问题。


    来自the documentation

    指定 BETWEEN TIMESTAMP ... 以检索该行的版本 存在于两个时间戳之间。两个表达式都必须计算为 时间戳值,不能评估为 NULL。 MINVALUEMAXVALUE 解析最旧和最新可用数据的时间戳, 分别。

    通常MINVALUE 会受到撤销保留的限制;因为这是一个新表,它会回到创建表的点,这比撤消保留要少。您不能再回头,因为它没有任何意义:如果您尝试在表创建时间之前使用显式时间戳值,它会告诉您表结构已更改。但是,您所做的 DML/DDL 区别并不真正相关,由于您提交数据的时间,您只会看到两行。

    【讨论】:

    • @kushal - 添加了一些关于这些值的内容。
    猜你喜欢
    • 2017-07-07
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 1970-01-01
    相关资源
    最近更新 更多