2

select语句返回两行

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

我有点期待三行

编号 || 描述
1 一个
1 两个
2 两个
根据链接中的声明,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;

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

4

1 回答 1

3

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

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

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

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

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

如果您查看版本数据伪列,您可以看到这两行都被视为带有当前数据的插入:

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需要调用,但没有它们就无法正常工作(伪列是空白的,只显示当前数据)。我认为我从来没有见过一个很好的解释,但在现实世界的案例中这不太可能成为问题。


文档中

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

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

于 2013-09-27T08:09:54.423 回答