0

Oracle 11g RAC を実行しています。

FOR EACH ROW BEFORE INSERTテーブルにCREATED_DATE (DATE)using を設定するトリガーがありsysdateます。

DATEデータ型の粒度は? INSERTこのようなトリガーを介して入力されたときに、RAC で 2 つの行がまったく同じ日付/時刻を持つことは可能ですか?

4

3 に答える 3

4

RAC がなくても簡単に実行できます。

17:25:47 (455)SYSTEM@dwal> create table t (k int primary key, d date);

Table created.

Elapsed: 00:00:00.35
17:32:00 (455)SYSTEM@dwal> ed
Wrote file S:\spool\dwal\BUF_SYSTEM_455.sql

  1  create trigger t_bi before insert on t for each row
  2  begin
  3  :new.d := sysdate;
  4* end;
17:32:04 (455)SYSTEM@dwal> /

Trigger created.

Elapsed: 00:00:00.10
17:32:04 (455)SYSTEM@dwal> insert into t(k) select rownum from dual connect by rownum <= 1e3;

1000 rows created.

Elapsed: 00:00:00.02
17:32:30 (455)SYSTEM@dwal> select d, count(*) from t group by d;

D                     COUNT(*)
------------------- ----------
18.09.2013 17:32:37       1000

Elapsed: 00:00:00.01

DATE タイプには秒単位の粒度があります。より粒度が必要な場合は、TIMESTAMP を使用することをお勧めします。

17:34:51 (455)SYSTEM@dwal> alter table t add (ts timestamp);

Table altered.

Elapsed: 00:00:00.17
17:36:01 (455)SYSTEM@dwal> ed
Wrote file S:\spool\dwal\BUF_SYSTEM_455.sql

  1  create or replace trigger t_bi before insert on t for each row
  2  begin
  3  :new.d := sysdate;
  4  :new.ts := systimestamp;
  5* end;
17:36:05 (455)SYSTEM@dwal> /

Trigger created.

Elapsed: 00:00:00.13
17:36:05 (455)SYSTEM@dwal> insert into t(k) select rownum from dual connect by rownum <= 1e3;

1000 rows created.

Elapsed: 00:00:00.12
17:36:47 (455)SYSTEM@dwal> select d, min(ts) mn, max(ts) mx, count(*) from t group by d;

D                   MN                             MX                               COUNT(*)
------------------- ------------------------------ ------------------------------ ----------
18.09.2013 17:36:19 18-SEP-13 05.36.19.481071 PM   18-SEP-13 05.36.19.593846 PM         1000

Elapsed: 00:00:00.02
于 2013-09-18T09:37:49.810 に答える
1

SQL ステートメントで sysdate を参照する場合、sysdate の単一の値のみが使用されます。

したがって、sysdate を CREATED_AT 列に割り当てることを含む 1,000,000 レコードの挿入を実行し、挿入に 15 分かかった場合、1,000,000 レコードすべてが同じ CREATED_AT 値を持つことになります。

ただし、トリガーによって CREATED_AT の値が入力されると、その値はトリガーの実行ごとに再評価されると思います。AskTomでそれについての議論があります。その結論の 1 つは、SQL から呼び出された関数で SYSDATE を使用する必要がある場合、タイミングが重要な場合は、SQL ステートメントから SYSDATE の値を渡す必要があるかもしれないということです。 SYSDATE の複数の値を参照しています。

同じことが TIMESTAMP 値にも当てはまると思います。

したがって、一意性を提供するために created_at 列に依存することはできません。これは、シーケンスによって生成された値によって達成されるべきものです。

于 2013-09-18T11:15:52.193 に答える