1

私は自分が働いている多くのことに関する統計を収集して保存する必要があり、特に 1 つのテーブルのプロセスで突然問題が発生しました。これらの統計を取得するためのプロセスの関連部分には、データを一時テーブルにダンプし、そのテーブルから新しいデータをメイン テーブルに挿入するだけの作業が含まれます。だから私はこのようなものを持っています:

CREATE TABLE "TEMP_SCHEMA"."STATS_ORDERS"
(
  "ORDER_NO"      NUMBER(10,0)        NOT NULL ENABLE,
  "ORDER_DATE"    DATE                NOT NULL ENABLE,
  "ORDER_TYPE"    VARCHAR2(1 BYTE)    NOT NULL ENABLE
); /
GRANT SELECT,INSERT,UPDATE,DELETE
ON "TEMP_SCHEMA"."STATS_ORDERS" TO "MY_SCHEMA"; /

CREATE TABLE "MY_SCHEMA"."STATS_ORDERS"
(
  "ORDER_NO"      NUMBER(10,0)        NOT NULL ENABLE,
  "ORDER_DATE"    DATE                NOT NULL ENABLE,
  "ORDER_TYPE"    VARCHAR2(1 BYTE)    NOT NULL ENABLE,
  CONSTRAINT "PK_STATS_ORDERS" PRIMARY KEY ("ORDER_NO", "ORDER_TYPE")
); /

データを "TEMP_SCHEMA"."STATS_ORDERS" にダンプした後、次のようなことを試みています。

INSERT INTO MY_SCHEMA.STATS_ORDERS (ORDER_NO,ORDER_DATE,ORDER_TYPE)
SELECT
    DISTINCT TMP.ORDER_NO,TMP.ORDER_DATE,TMP.ORDER_TYPE
FROM
    (SELECT DISTINCT * FROM TEMP_SCHEMA.STATS_ORDERS) TMP
    LEFT JOIN MY_SCHEMA.STATS_ORDERS ORD
    ON TMP.ORDER_NO = ORD.ORDER_NO AND TMP.ORDER_TYPE = ORD.ORDER_TYPE
WHERE ORD.ORDER_NO IS NULL AND ORD.ORDER_TYPE IS NULL; /

これを実行すると、次のエラーが表示されます。

SQL Error: ORA-00001: unique constraint (MY_SCHEMA.PK_STATS_ORDERS) violated
00001. 00000 -  "unique constraint (%s.%s) violated"
*Cause:    An UPDATE or INSERT statement attempted to insert a duplicate key.
          For Trusted Oracle configured in DBMS MAC mode, you may see
          this message if a duplicate entry exists at a different level.
*Action:   Either remove the unique restriction or do not insert the key.

次のクエリを実行して、エラーの原因となっている行を見つけました。

SELECT ORDER_NO,ORDER_DATE,ORDER_TYPE
FROM
    MY_SCHEMA.STATS_ORDERS O
    INNER JOIN (
        SELECT DISTINCT TMP.ORDER_NO,TMP.ORDER_DATE,TMP.ORDER_TYPE
        FROM (SELECT DISTINCT * FROM TEMP_SCHEMA.STATS_ORDERS) TMP
          LEFT JOIN MY_SCHEMA.STATS_ORDERS ORD
          ON TMP.ORDER_NO = ORD.ORDER_NO AND TMP.ORDER_TYPE = ORD.ORDER_TYPE
        WHERE ORD.ORDER_NO IS NULL AND ORD.ORDER_TYPE IS NULL
    ) N
    ON O.ORDER_NO = N.ORDER_NO AND O.ORDER_TYPE = N.ORDER_TYPE; /

おそらく、これは違反の原因となっている行を返すはずですが、重複する可能性のあるものを明示的に除外しているため、もちろん何も返しません。

私は何を間違っていますか?

編集:私の例では、誤って元の名前を残しました。私の例の名前に変更しました。

4

2 に答える 2

6

問題のある行を特定する最も簡単な方法は、通常、DML エラー ログを使用することです。エラーテーブルを作成する場合

BEGIN
  dmbs_errlog.create_error_log( dml_table_name => 'STATS_ORDERS',
                                err_log_table_name => 'STATS_ORDERS_ERR',
                                err_log_table_owner => 'MY_SCHEMA' );
END;

LOG ERRORS INTO次に、DMLで句を使用できます

INSERT INTO MY_SCHEMA.STATS_ORDERS (ORDER_NO,ORDER_DATE,ORDER_TYPE)
  SELECT DISTINCT TMP.ORDER_NO,TMP.ORDER_DATE,TMP.ORDER_TYPE
    FROM (SELECT DISTINCT * FROM TEMP_SCHEMA.STATS_ORDERS) TMP
         LEFT JOIN MY_SCHEMA.STATS_ORDERS ORD
         ON TMP.ORDER_NO = ORD.ORDER_NO AND TMP.ORDER_TYPE = ORD.ORDER_TYPE
   WHERE ORD.ORDER_NO IS NULL AND ORD.ORDER_TYPE IS NULL
     LOG ERRORS INTO stats_orders_err
  REJECT LIMIT UNLIMITED;

これにより、制約によって拒否された行がstats_orders_errエラー テーブルに書き込まれます。

于 2012-12-03T16:24:19.293 に答える
1

このシナリオに当てはまらないことを確認します。

SQL> CREATE TABLE STATS_ORDERS_TMP
  2  (
  3    ORDER_NO      NUMBER(10,0)        NOT NULL ENABLE,
  4    ORDER_DATE    DATE                NOT NULL ENABLE,
  5    ORDER_TYPE    VARCHAR2(1 BYTE)    NOT NULL ENABLE
  6  );

Table created.

SQL>
SQL> CREATE TABLE STATS_ORDERS
  2  (
  3    ORDER_NO      NUMBER(10,0)        NOT NULL ENABLE,
  4    ORDER_DATE    DATE                NOT NULL ENABLE,
  5    ORDER_TYPE    VARCHAR2(1 BYTE)    NOT NULL ENABLE,
  6    CONSTRAINT PK_STATS_ORDERS PRIMARY KEY (ORDER_NO, ORDER_TYPE)
  7  );

Table created.

SQL> insert into STATS_ORDERS_TMP values (1, sysdate, 'A');

1 row created.

SQL> insert into STATS_ORDERS_TMP values (1, sysdate-1, 'A');

1 row created.

SQL> commit;

Commit complete.

SQL> insert into stats_orders (order_no,order_date,order_type)
  2  select
  3      distinct tmp.order_no,tmp.order_date,tmp.order_type
  4  from
  5      (select distinct * from stats_orders_tmp) tmp
  6      left join stats_orders ord
  7      on tmp.order_no = ord.order_no and tmp.order_type = ord.order_type
  8  where ord.order_no is null and ord.order_type is null;
insert into stats_orders (order_no,order_date,order_type)
*
ERROR at line 1:
ORA-00001: unique constraint (DTD_TRADE.PK_STATS_ORDERS) violated

つまり、「一時」テーブルに特定の注文タイプの日付が重複しています。

検証ではそれらが表示されません(メインテーブルにないため):

SQL> SELECT o.ORDER_NO,o.ORDER_DATE,o.ORDER_TYPE
  2  FROM
  3      STATS_ORDERS O
  4      INNER JOIN (
  5          SELECT DISTINCT TMP.ORDER_NO,TMP.ORDER_DATE,TMP.ORDER_TYPE
  6          FROM (SELECT DISTINCT * FROM STATS_ORDERS_TMP) TMP
  7            LEFT JOIN STATS_ORDERS ORD
  8            ON TMP.ORDER_NO = ORD.ORDER_NO AND TMP.ORDER_TYPE = ORD.ORDER_TYPE
  9          WHERE ORD.ORDER_NO IS NULL AND ORD.ORDER_TYPE IS NULL
 10      ) N
 11      ON O.ORDER_NO = N.ORDER_NO AND O.ORDER_TYPE = N.ORDER_TYPE;

no rows selected

しかし、それらは存在します:

SQL> select order_no, order_type, count(*) from stats_orders_tmp group by order_no, order_type having count(*) > 1;

  ORDER_NO O   COUNT(*)
---------- - ----------
         1 A          2
于 2012-12-03T16:31:42.410 に答える