2012-10-09 48 views
4

我正在使用Scriptella進行ETL操作,使用自動生成的id引用了許多表。我想重新使用這些編號,而不使用子查詢,這是ETL文件的我的腳本片段:Scriptella - 如何獲取和重新使用自動生成的ID?

<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。

編輯: 我想要實現的是,例如,獲取第一個表的插入中使用的自動生成的id的值,以便在第二個表的插入中使用它,因爲應該引用記錄

+0

*爲什麼*你想重新使用刪除項目的ID? –

+0

...爲什麼不使用子查詢?你說過「不使用子查詢」,而不是*爲什麼*。 –

回答

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> 
+0

感謝您的跟進。 –

+0

這隻適用於Postgres。似乎它會是一個更好的解決方案,如果Scriptella使用stmt.getGeneratedKeys()爲後面的插入提供了一個變量,我們可以用數據庫中性的方式做到這一點。 – chubbsondubs

1

你的代碼起初看起來完全是假的,因爲沒有任何東西似乎將SELECT連接到INSERT,所以即使它運行了,你也只是產生一個ID並丟棄它。看起來您的腳本編制工具可能會自動將列別名的結果定義爲可以在以後的查詢中引用的變量;見"copy to another database" in the Scriptella tutorial。快速瀏覽一下,表明你想要做的事情可能會起作用,但是你必須使用嵌套的<query/><script/>塊來做到這一點。

使用生成的序列號正確的方法是之一:

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); 

你的問題最初似乎是有關重新使用刪除的標識(即無間隙序列),但它看起來就像你澄清它去除那個。


更新後編輯+評論改變問題的意思是:

如果你想在以後的INSERT s到使用生成的ID從一排,你必須:

  • 使用INSERT ... RETURNING捕獲ID或在INSERT之後調用currval('the_id_sequence'),將ID存儲在您的腳本語言的客戶端變量中,並將其傳遞給後續的INSERT s;或

  • 在後續插入的VALUES列表中使用currval('the_id_sequence')

我從來沒有聽說過Scriptella更不用說用它,所以我不能使用客戶端變量的第一個選項幫助。不過,如果它沒有辦法儲存SELECTINSERT ... RETURNING的結果供以後使用,我會非常驚訝。一個非常快速的一瞥表明它使用嵌套的<query/><script/>塊完成,但這只是30秒的教程一瞥。

第二個選項很簡單。假設你剛剛插入:

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

,並希望插入especie新行具有剛插入generogeneroId。假定該爲genero的ID序列遵循標準的命名PostgreSQL使用,tablename_columnname_id_seq,你會使用:

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

參見:

+0

只是爲了澄清,這是一個腳本的片段,我正在使用ETL操作,我正在使用Scriptella。原因是,有7個表通過自動生成的ID互相引用,我需要在所有這些表中插入記錄,但使用Scriptella我無法獲得第一個表的自動生成的ID的值,例如,按順序用它插入第二張表,因爲這些記錄應該被引用 – Neotaku

+0

@ Neotaku好的,這比你原來的問題更有意義。很難弄清楚你想要什麼。答案已更新。 –

相關問題