4

私はETL操作にScriptellaを使用しており、自動生成されたIDで参照される多くのテーブルを操作しています。サブクエリを使用せずにこれらのIDを再利用したいのですが、これはetlファイルのスクリプトフラグメントです。

<script connection-id="out" if="rownum>1">

SELECT nextval('SQC_CLASE') AS claseId;
INSERT INTO zoologia.clase VALUES( ?claseId, ?phylumId, ?clase, ?subclase, ?infraclase, true );

SELECT nextval('SQC_ORDEN') AS ordenId;
INSERT INTO zoologia.orden VALUES( ?ordenId, ?claseId, ?orden, ?suborden, true );

SELECT nextval('SQC_SUPERFAMILIA') AS superfamiliaId;
INSERT INTO zoologia.superfamilia VALUES( ?superfamiliaId, ?ordenId, ?superfamilia, true );

SELECT nextval('SQC_FAMILIA') AS familiaId;
INSERT INTO zoologia.familia VALUES( ?familiaId, ?superfamiliaId, ?familia, ?subfamilia, ?tribu, true );

SELECT nextval('SQC_GENERO') AS generoId;
INSERT INTO zoologia.genero VALUES( ?generoId, ?familiaId, ?genero, true );

SELECT nextval('SQC_ESPECIE') AS especieId;
INSERT INTO zoologia.especie VALUES( ?especieId, ?generoId, ?especie, ?subespecie, ?variedad, ?genero, true );

</script>

SELECTスクリプト内で実行できないため、これは明らかに間違っていますよね?サブクエリなしでそれを行う方法がよくわかりません。私はPostgreSQLを使用しています。

編集:私が達成したいのは、たとえば、レコードが参照される必要があるため、2番目のテーブルの挿入で使用するために、最初のテーブルの挿入で使用される自動生成されたIDの値を取得することです

4

2 に答える 2

3

Scriptellaフォーラムのユーザーのおかげで、これが解決策であり、シーケンスのすべての値を含む単一のクエリです。

<query connection-id="external">
    <query connection-id="sizoo">
        SELECT nextval('SQC_PHYLUM') AS phylumId
        , nextval('SQC_CLASE') AS claseId
        , nextval('SQC_ORDEN') AS ordenId
        , nextval('SQC_SUPERFAMILIA') AS superfamiliaId
        , nextval('SQC_FAMILIA') AS familiaId
        , nextval('SQC_GENERO') AS generoId
        , nextval('SQC_ESPECIE') AS especieId;

        <script connection-id="sizoo" if="rownum>1">
            INSERT INTO zoologia.phylum VALUES( ?phylumId, ?phylum, true );
            INSERT INTO zoologia.clase VALUES( ?claseId, ?phylumId, ?clase, ?subclase, ?infraclase, true );
            INSERT INTO zoologia.orden VALUES( ?ordenId, ?claseId, ?orden, ?suborden, true );
            INSERT INTO zoologia.superfamilia VALUES( ?superfamiliaId, ?ordenId, ?superfamilia, true );
            INSERT INTO zoologia.familia VALUES( ?familiaId, ?superfamiliaId, ?familia, ?subfamilia, ?tribu, true );
            INSERT INTO zoologia.genero VALUES( ?generoId, ?familiaId, ?genero, true );
            INSERT INTO zoologia.especie VALUES( ?especieId, ?generoId, ?especie, ?subespecie, ?variedad, ?genero, true );
        </script>
    </query>
</query>
于 2012-10-10T17:33:09.113 に答える
1

あなたのコードは最初は完全に偽物のように見えました。何もSELECT以下に接続していないように見えるINSERTので、それが実行されたとしても、IDを生成して破棄するだけです。ただし、スクリプトツールがSELECT列エイリアスの結果を後のクエリで参照できる変数として自動的に定義しているようです。Scriptellaチュートリアルの「別のデータベースにコピーする」を参照してください。それを一目見れば、やりたいことがうまくいくかもしれないが、それを行うにはネストされたブロックを使用する必要が<query/>あり<script/>ます。

シーケンスで生成されたIDを使用する正しい方法は、次のいずれかです。

INSERT INTO zoologia.especie VALUES( nextval('SQC_ESPECIE'), ?generoId, ?especie, ?subespecie, ?variedad, ?genero, true );

INSERT INTO zoologia.especie VALUES( DEFAULT, ?generoId, ?especie, ?subespecie, ?variedad, ?genero, true );

INSERT INTO zoologia.especie(generoId, especie, subespecie, variedad, genero, someothercol) 
VALUES( ?generoId, ?especie, ?subespecie, ?variedad, ?genero, true );

あなたの質問は当初、削除されたID(つまりギャップのないシーケンス)の再利用に関するもののように見えましたが、それを削除するためにそれを明確にしたようです。


編集後の更新+コメントにより、質問の意味が変更されました。

後続のsの1つの行から生成されたIDを使用しようとしている場合は、次INSERTのいずれかを行う必要があります。

  • を使用して、またはの後にINSERT ... RETURNING呼び出すことによってIDをキャプチャし、スクリプト言語のクライアント側変数にIDを格納し、それを後続のsに渡します。またcurrval('the_id_sequence')INSERTINSERT

  • 後続の挿入のリストで使用currval('the_id_sequence')します。VALUES

Scriptellaを使用したことは言うまでもなく、聞いたことがないので、クライアント側の変数を使用する最初のオプションを手伝うことはできません。SELECTただし、またはの結果を保存しINSERT ... RETURNINGて後で使用する方法がなかった場合は、非常に驚​​きます。<query/>非常に一見すると、ネストされた<script/>ブロックで行われていることがわかりますが、チュートリアルでは30秒でわかります。

2番目のオプションは単純です。挿入したとしましょう:

INSERT INTO zoologia.genero VALUES( DEFAULT, ?familiaId, ?genero, true );

挿入したばかりののをespecie含む新しい行を挿入したい。のIDシーケンスがPostgreSQLが使用する標準の命名に従うと仮定すると、、を使用します。generoIdgenerogenerotablename_columnname_id_seq

INSERT INTO zoologia.especie VALUES( DEFAULT, currval('genero_generoId_seq'), ...);

見る:

于 2012-10-10T06:20:21.260 に答える