2

このselectステートメントは 2 つの行を返します

ID || 説明
1 2
2 2

私は一種の3行を期待しています

ID || 説明
1 ONE
1 2
2 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;

私が考えることができる唯一の理由は、タイムスタンプの最小値と最大値がDDLタイムスタンプ値ではなくDMLタイムスタンプ値を取る場合.....これに光を当ててください!

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、3 つの行とそれらがどのように変更されたかを確認できます。

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 ...2 つのタイムスタンプの間に存在した行のバージョンを取得するように指定します。どちらの式もタイムスタンプ値に評価される必要があり、NULL に評価できません。 それぞれ、利用可能な最も古いデータと最新のデータのタイムスタンプに解決されますMINVALUEMAXVALUE

通常MINVALUE、元に戻す保持によって制限されます。これは新しいテーブルであるため、テーブルが作成された時点に戻りますが、これは元に戻す保持よりも少なくなります。意味がないため、それ以上戻ることはできません。テーブルの作成時刻より前に明示的なタイムスタンプ値を使用しようとすると、テーブル構造が変更されたことがわかります。ただし、作成している DML/DDL の区別は実際には関係ありません。データをコミットしたときのために、2 つの行しか表示されません。

于 2013-09-27T08:09:54.423 に答える