web-dev-qa-db-ja.com

PL / SQLで一時表を作成する

Oracle 10gデータベースを使用していて、1つのテーブルからレコードのグループを抽出し、それを使用して一連の関連テーブルからレコードをプルしたいと考えています。

これがT-SQLの場合、次のようにします。

CREATE TABLE #PatientIDs (
  pId int
)

INSERT INTO #PatientIDs
  select distinct pId from appointments

SELECT * from Person WHERE Person.pId IN (select pId from #PatientIDs)

SELECT * from Allergies WHERE Allergies.pId IN (select pId from #PatientIDs)

DROP TABLE #PatientIDs

しかし、私が見ているすべての役立つページは、これをおそらくよりもはるかに多くの作業のように見せているので、私は明らかな何かを見逃しているに違いないと思います。

(ところで、これを1つのスクリプトとして実行する代わりに、Oracle SQL Developerでセッションを開き、一時テーブルを作成してから、各クエリを実行し、CSVにエクスポートします。これで機能しますか?)

6
SarekOfVulcan

Oracleには一時テーブルがありますが、明示的に作成する必要があります。

create global temporary table...

一時テーブルのデータは、それを作成したセッション専用であり、セッション固有またはトランザクション固有にすることができます。データがnotセッションが終了するまで削除される場合は、最後にON COMMIT PRESERVE ROWSを使用する必要があります。 createステートメント。また、それらのロールバックまたはコミットのサポートもありません...

あなたが与えた例では一時テーブルの必要はないと思います-一時テーブルが作成されていたためにAPPOINTMENTSテーブルに加えられた更新が反映されないリスクがあります。 IN/EXISTS/JOINを使用します:

SELECT p.* 
  FROM PERSON p
 WHERE EXISTS (SELECT NULL
                 FROM APPOINTMENTS a
                WHERE a.personid = a.id)

SELECT p.* 
  FROM PERSON p
 WHERE p.personid IN (SELECT a.id
                        FROM APPOINTMENTS a)

SELECT DISTINCT p.* 
  FROM PERSON p
  JOIN APPOINTMENTS a ON a.id = p.personid

1つのPERSONレコードに複数のAPPOINTMENTレコードが関連付けられている場合、JOINingは重複するリスクがあります。そのため、DISTINCTを追加しました。

12
OMG Ponies

Oracleには、SQLServerと同じように一時テーブルを何気なく作成する機能がありません。データベーススキーマでテーブルを明示的に作成する必要があります(create global tempory table)。これは、テーブルを作成するためのアクセス許可が必要であり、データベースの変更としてスクリプトを明示的にデプロイする必要があることも意味します。テーブルは、グローバル名前空間にも表示されます。

これは、OracleプログラミングとSQLServerプログラミングの慣用的な大きな違いです。慣用的なT-SQLは一時テーブルを広範囲に使用でき、手続き型T-SQLコードを作成するための真の要件は、実質的にこの機能のために非常にまれです。

慣用的なPL/SQLは、手続き型コードにドロップアウトするのがはるかに高速であり、一時テーブルを偽造しようとするよりも、これを行う方がおそらく良いでしょう。 PL/SQLには、カーソルおよびネストされた結果セット(カーソル式)に対する明示的な並列処理のためのフロー制御などのパフォーマンス指向の構造があることに注意してください。最近のバージョンにはJITコンパイラがあります。

手続き型PL/SQLコードをすばやく実行するためのさまざまなツールにアクセスできます。これは、間違いなく慣用的なPL/SQLプログラミングです。基礎となるパラダイムはT-SQLとは多少異なり、一時テーブルへのアプローチは、システムアーキテクチャとプログラミングイディオムが異なる主要なポイントの1つです。

正確な問題は解決されましたが、この分野で役立つスキルを身に付けたい場合は、PL/SQLコレクション、特にpl/sqlコレクションを使用したバルクSQL操作(BULK COLLECT/Bulk Binds)を見てみましょう。 RETURNING句、および%ROWTYPEを使用したコレクションの定義。

上記のすべてを理解することで、作成するpl/sqlコードの量を劇的に減らすことができます。ただし、すべてのSQLソリューションはほとんどの場合PL/SQLソリューションよりも優れていることを常に忘れないでください。

5
JulesLt