2

主キーが DCRDID である dcr_details_new と dcr_details_old の 2 つのテーブルがあります。

ここに画像の説明を入力

dcr_details_new テーブルと dcr_details_old テーブルはどちらも同じ構造を共有しています。主キーは DCRDID で、挿入ごとに 1 ずつインクリメントします。

dcr_details_old から dcr_details_new にすべての行をフェッチする必要があり、DOCREGNO と DCR_No でレコードをフィルター処理する必要があります。

したがって、通常の単一行​​のインポート/挿入は、次のように正確に実行されます。

INSERT INTO dcr_details_new 
SELECT (select Max(DCRDID) + 1 from dcr_details_new),
       TWNCODE,
       '100008',
       DOCCATOGARY,
       DCR_NO,
       VISIT_NO,
       GIVEAWAY,
       COMPETITORBRN,
       REMARK,
       DCRDRDATE,
       COM_ACTI
 FROM dcr_details_old  
WHERE DOCREGNO= 'T10037'
  and DCR_NO = 28766;

1 rows created.

dcr_noここで、フィルタリングをスキップして、異なる を持つレコードが多すぎるため、レコードを挿入したいと考えていますdcr_no。ここで、選択ステートメントのみでフィルタリングすると DOCREGNO多くのレコードが返され、ループして挿入しようとすると、必要に応じてインクリメントされないため、常に主キーを台無しにします。

これが私が試したループと私が得ているエラーです。

declare
  i integer := 1;
BEGIN 
  FOR x IN (select * from dcr_details_old  WHERE DOCREGNO= 'T10037')
  LOOP
    INSERT INTO dcr_details_new (DCRDID, TWNCODE, DOCREGNO, DOCCATOGARY,
                                 DCR_NO, VISIT_NO, GIVEAWAY, COMPETITORBRN,
                                 REMARK, DCRDRDATE, COM_ACTI)
    SELECT (select Max(DCRDID) + 1 from dcr_details_new),
           TWNCODE,
           '100008',
           DOCCATOGARY,
           DCR_NO, VISIT_NO, GIVEAWAY, COMPETITORBRN,
           REMARK, DCRDRDATE, COM_ACTI
      FROM dcr_details_old;

     i := i + 1;
  END LOOP;
END;

エラー:

**ERROR at line 1:
ORA-00001: unique constraint (SYS_C0061873) violated
ORA-06512: at line 5**

このエラーSYS_C0061873には主キーがありますDCRDID。ここに挿入する値は、手動で入力する必要'100008'がある新しい値です。docregno

続行する簡単な方法はありますか?どうぞよろしくお願いいたします。

4

4 に答える 4

1

OLDテーブルのすべてのレコードを新しい主キーを持つ新しいテーブルに挿入するは、次のステートメントを使用します。

キーの部分は、最大の既存のキーを取得し、ROWNUMを使用して作成することに注意してください。単一の移行ステップ (つまり、並行移行がなく、アプリケーションがダウンしている) の場合、これは安全な方法です。

 INSERT INTO dcr_details_new
 (DCRDID,TWNCODE,DOCREGNO,DOCCATOGARY,DCR_NO,VISIT_NO,GIVEAWAY,
 COMPETITORBRN,REMARK,DCRDRDATE,COM_ACTI)
 select 
  (select max(DCRDID) from dcr_details_new) + rownum as DCRDID,
  TWNCODE,DOCREGNO,DOCCATOGARY,DCR_NO,VISIT_NO,GIVEAWAY,
  COMPETITORBRN,REMARK,DCRDRDATE,COM_ACTI
 from dcr_details_old where DOCREGNO = 'T10037'
 ;
于 2015-10-28T14:35:46.413 に答える
0

あなたのすべての助けの後、これが私にとってうまくいった最終的な答えです。

INSERT INTO dcr_details_new
(DCRDID,TWNCODE,DOCREGNO,DOCCATOGARY,DCR_NO,VISIT_NO,GIVEAWAY,
COMPETITORBRN,REMARK,DCRDRDATE,COM_ACTI)
select 
(select max(DCRDID) from dcr_details_new) + rownum as DCRDID,
TWNCODE,'100008',DOCCATOGARY,DCR_NO,VISIT_NO,GIVEAWAY,
COMPETITORBRN,REMARK,DCRDRDATE,COM_ACTI
from dcr_details_old where DOCREGNO = 'T10037' ;

みんなありがとう

于 2015-10-29T03:41:16.383 に答える
0

あなたが求めているのは、次の行に沿った単一の挿入ステートメントだけだと確信しています。

INSERT INTO dcr_details_new (dcrdid,
                             twncode,
                             docregno,
                             doccatogary,
                             dcr_no,
                             visit_no,
                             giveaway,
                             competitorbrn,
                             remark,
                             dcrdrdate,
                             com_acti)
  SELECT (SELECT MAX(dcrdid) FROM dcr_details_new) + rownum,
         twncode,
         '100008',
         doccatogary,
         dcr_no,
         visit_no,
         giveaway,
         competitorbrn,
         remark,
         dcrdrdate,
         com_acti
  FROM   dcr_details_old;

「max(val) + some_val」を使用して新しい主キー値を生成することは、一般的には悪い考えです。これが、リリース スクリプトによってのみ挿入される静的データ テーブルである場合は、ほとんど問題ありません。個人的には、まだシーケンスを使用したいと思います!

現在の最大値 + 1 (またはその他の値) の開始値を持つシーケンスを作成new_seq.nextvalし、テーブルに行を追加するときに使用することを強くお勧めします。はるかにシンプルで、より確実です。

于 2015-10-28T14:35:02.927 に答える