2017-12-13 6 views
0

私は3つの属性を持つ1つのテーブルA:挿入データは、あるクエリでFKと他のテーブルを更新

ID(PK)、単位(VARCHAR2)、VALUE(番号)

そして私は外部キーを介してテーブルAのPKを参照する別のテーブルBを持っています。

ID、表BにおいてFK_TABLE_A

は既に記録されているが、属性FK_TABLE_Aの値がヌルです。私が欲しいのは、表Bのすべてのレコードは、表Aに新しいデータを挿入し、私が持っているどのような表B.

に外部キーとして新しく作成された主キーを参照することにより、表AのPKに独自参照を得ることであり、 私は今、次のSQLを経由して新しいデータを挿入することができます:これまでに行われ

INSERT INTO TABLE_A(ID, UNIT, VALUE) VALUES (TABKE_A_SEQ.nextval, 'SOME_STRING', 1); 

そして、私は

UPDATE TABLE_B SET FK_TABLE_A = 123; //123 is just an example PK 

表Bに手でrefernceを更新することができます。しかし、私は、各RECOを照会する必要はありません毎回DBを使用するのではなく、最初のinsertと2番目のupdateを1つのクエリで組み合わせる必要があります。 この更新では、テーブルAの新しく作成されたPKが参照として使用されます。

これは可能ですか?

私はDBとしてOracleを使用しています。あなたが持っていないなどが

INSERT INTO TABLE_A(ID, UNIT, VALUE) VALUES (TABKE_A_SEQ.nextval, 'SOME_STRING', 1); 
UPDATE TABLE_B SET FK_TABLE_A = TABKE_A_SEQ.currval; 

(:あなたはあなたのセッションでシーケンスを使用したら

+0

あなたは自分のアップデートでは、 '123' insteadof' TABKE_A_SEQ.currval'を使用して意味しますか? PK/FKの関係がまだない場合、更新するテーブルBの行をどのように知っていますか? –

+0

あなたのTABLE_BはTABLE_Aを参照しています。更新する子行をどのように知っていますか? TABLE_Aに挿入されている場合は、TABLE_Bの挿入でなければならず、更新する必要はありません。 –

+0

Table_Bの各レコードはもちろん、異なる外部キーを取得する必要があります。 (これは、表Aの新しく作成された項目の主キーです) – mrkernelpanic

答えて

0

することは、あなたはuse the currval pseudocolumnは最後nextvalの呼び出しによって、あなたのセッションで発行された最後のシーケンス値を取得することができます同じFK値にテーブルB内のすべての行を更新しますフィルタ、;おそらくあなたは、関連する行を識別するために、より複雑な何かをやっている...)


あなたは、1対1の場合どの行がどのPK値を取得するかは気にしない、あなたは制約を延ばすようにすることができます。シーケンスを使用してすべての表B行を更新し、それらを使用して表A行を作成します。迅速なデモテーブルで

create table table_a (id number primary key, unit varchar2(20), value number); 
create table table_b (id number, 
    fk_table_a number references table_a(id) initially deferred deferrable); 
create sequence table_a_seq; 
create sequence table_b_seq start with 50; 

insert into table_b (id) select table_b_seq.nextval from dual connect by level <= 5; 

その後、単一のトランザクションでは、すべての行を更新し、単一の挿入を行います。

update table_b set fk_table_a = table_a_seq.nextval; 

insert into table_a (id, unit, value) 
select fk_table_a, 'SOME_STRING', 1 
from table_b; 

制約ができるように遅延可能である必要があります最初に更新する。そうでなければ、ORA-02291を取得します。

単位/値はtable_aから来ている場合は、代わりに固定されたリテラルを使用するクエリのものを含めることができます。あなたが実際にそれらに必要なものを教えるのは難しいです。

今あなたが持っている:

select * from table_a; 

     ID UNIT      VALUE 
---------- -------------------- ---------- 
     1 SOME_STRING     1 
     2 SOME_STRING     1 
     3 SOME_STRING     1 
     4 SOME_STRING     1 
     5 SOME_STRING     1 

select * from table_b; 

     ID FK_TABLE_A 
---------- ---------- 
     50   1 
     51   2 
     52   3 
     53   4 
     54   5 
+0

これは、Table_Aで1つの項目のみを作成します。テーブルBの各レコードに対してテーブルAの新しいエントリを作成し、TABLE_BのTABLE_Aから新しく作成したPKを参照したいと考えました。 – mrkernelpanic

+0

テーブルBのどの行がどのPK/FK値を取得するかをどのように決定しますか?あなたはテーブルBから別のテーブルに値を引き出し、それを参照したいのですか? (ユニットやバリューは現在Bに存在していますが、重複していますか?)また、1対1の関係のように聞こえます。その場合、なぜ2つのテーブルにデータを分割するのですか? –

+0

はい、それは1対1の関係です。私はそれを分割することに決めました。なぜなら、TABLE_Bはすでに多くの属性を持っているからです(表Bでは明示的に使用されていません)。 Table_Bは、テーブルAの作成されたエントリの直ちに作成されたPK値を取得する必要があります。そのため、私はワンショットコマンドを考えました: – mrkernelpanic

0

はTABLE_Bの行を作成する(TABLE_A上の)トリガーを使用してください。例えば

(あなたがPKを生成するSEQUENCEを使用していると仮定)

CREATE OR REPLACE TRIGGER TR_TABLE_A_AI 
AFTER INSERT 
ON TABLE_A 
FOR EACH ROW 
BEGIN 
    INSERT INTO TABLE_B VALUES (SEQ_TABLE_B.NEXTVAL, :NEW.ID); 
END; 
+0

私は移行スクリプトの一部として一度だけやりたいですが、永続的ではありません。 – mrkernelpanic

関連する問題