2016-07-02 5 views
1

は、I列(配列COL1COL2COL3)とテーブルmy_tableを有します。他のテーブルからクエリされた値をテーブルに挿入したいとします。つまり、insert into my_table select <query from other tables>です。問題は、プライマリキーが4つの列であるため、挿入する行の数まで0から始まるシーケンスを追加する必要があります(順序は問題ではありません)。実際には、論理的にそれを行うものとし、毎回全体行を挿入しようとしているr_count回ループし、シーケンス列を追加して列を挿入する方法は? Oracleデータベース(11gR2の)で

DECLARE 
    j NUMBER; 
    r_count number; 
BEGIN 
    select count(1) into r_count from <my query to be inserted>; 
    FOR j IN 0 .. r_count 
    LOOP 
     INSERT INTO my_table 
       select <my query, incorporating r_count as sequence column> ; 
    END LOOP; 
END; 

しかし、それは動作しませんでした:

は、私はこのようなループを使用してみました。期待どおりの目標を達成し、シーケンス列を追加して行を挿入するにはどうすればよいですか?

答えて

1

はその後idと3つのデータ列を、ターゲット表を作成

-- This is your source query table (can be anything) 
CREATE TABLE source_table 
    (
    source_a VARCHAR(255), 
    source_b VARCHAR(255), 
    source_c VARCHAR(255) 
); 

insert into source_table (source_a, source_b, source_c) values ('A', 'B', 'C'); 
insert into source_table (source_a, source_b, source_c) values ('D', 'E', 'F'); 
insert into source_table (source_a, source_b, source_c) values ('G', 'H', 'I'); 

(データのソースをシミュレートする)のは、サンプルデータを持つテーブルを作成してみましょう。

-- This is your target_table 
CREATE TABLE target_table 
    (
    id  NUMBER(9,0), 
    target_a VARCHAR2(255), 
    target_b VARCHAR2(255), 
    target_c VARCHAR2(255) 
); 

-- This is sequence used to ensure unique number in 1st column 
CREATE sequence target_table_id_seq start with 0 minvalue 0 increment BY 1; 

最後に、挿入、配列からロードID、ソース・テーブルからのデータの残りの部分を実行します。

INSERT INTO target_table 
SELECT target_table_id_seq.nextval, 
    source_a, 
    source_b, 
    source_c 
FROM source_table; 

結果は、後でいくつかの値を追加した場合、彼らは4,5,6などの番号を継続します

1 A B C 
2 D E F 
3 G H I 

ように見えるかもしれません...それともあなただけのグループ内での順序を取得したいです?したがって、あなたが2行以上JKLとMNOを追加した場合、テーブルを標的とするために、この

1 A B C 
2 D E F 
3 G H I 
1 J K L 
2 M N O 

ようになり、あなたが別のソリューションが必要(でもシーケンサーを必要としない)

SELECT 
    RANK() OVER (ORDER BY source_a, source_b, source_c), 
    source_a, 
    source_b, 
    source_c 
FROM source_table; 

技術的にはあなたはROWNUMを使用することができます私は一貫した結果のために、分析機能を超えてRANK()を選択します。これは、同じ行を2回挿入しようとすると複雑な主キーに違反することに注意してください(私の最初の解決策はありません)

+0

あなたはどのように地球上に1人の担当者しかいないのですか? :) ありがとうございました – amyassin

2

これをループで実行しないでください。ただ、row_number()を使用します。

INSERT INTO my_table(seq, . . .) 
    select row_number() over (order by NULL) - 1, . . . 
    from . . .; 
0

をので、あなたはすでにテーブルを持って、それが行の必要な数を持っており、今では、という名前の列の順序で、総行数マイナス1に0から番号を追加したいですか? (おそらくない「配列」が、Oracleと衝突する可能性が低いものが予約語?)

は、この作業をする必要があり:

update my_table set seq = rownum - 1; 
+0

いいえ、私はすでにテーブルを持っていますが、私はカップル他のテーブルから取得して、シーケンスを追加したいと思います。 – amyassin

+0

...しかし、新しい数字がシーケンス内の既存の数字と衝突しないようにする必要がありますか? – mathguy

+0

あなたは正しいです。幸いなことに、この特定のシナリオでは、col1はこの特定の挿入のための新しいユニークな値なので、他のシーケンスは異なるcol1を持つため衝突しません。 – amyassin

2

明らかに、あなたはOracleのシーケンスを使用する必要があります。
まず、シーケンスを作成します。

create sequence seq_my_table start with 0 minvalue 0 increment by 1; 

をし、それを使用します。

INSERT INTO my_table (sequence, ...) 
select seq_my_table.nextval, <the rest of my query>; 

シーケンス番号が連続して挿入されます。

関連する問題