データベース間および同じデータベースの表同士の間でCHAR、DATE、LONG、NUMBERまたはVARCHAR2のデータをコピーするには、SQL*PlusのCOPYコマンドを使用します。COPYコマンドを使用すると、次のようなデータベース間でのデータのコピーが可能です。
リモート・データベースからローカル・データベースへのデータのコピー
ローカル(デフォルト)・データベースから(ほとんどのシステム上の)リモート・データベースへのデータのコピー
あるリモート・データベースから(ほとんどのシステム上の)別のリモート・データベースへのデータのコピー
注意:
一般に、COPYコマンドは、Oracle DatabaseとOracle以外のデータベースの間でデータをコピーするために使用するように設計されています。Oracle Database間でデータをコピーするには、SQLコマンド(CREATE TABLE ASおよびINSERT)を使用してください。
COPY FROM database TO database action - destination_table (column_name, column_name, - column_name ...) USING query
COPY FROM HR@BOSTONDB - TO TODD@CHICAGODB - CREATE NEWDEPT (DEPARTMENT_ID, DEPARTMENT_NAME, CITY) - USING SELECT * FROM EMP_DETAILS_VIEW
FROM句またはTO句の中でデータベースを指定するには、ローカル・データベースおよびリモート・データベースに対して有効なユーザー名およびパスワードが必要で、適切なOracle Netサービス名を指定する必要があります。 COPYは、Oracle Databaseセキュリティに従うため、表にアクセスするには、指定するユーザー名に表へのアクセス権限が必要です。どのデータベースが使用可能であるかについては、DBAに問い合せてください。
リモート・データベースからローカル・データベースにコピーする場合は、TO句を省略できます。ローカル・データベースからリモート・データベースにコピーする場合は、FROM句を省略できます。リモート・データベース間でコピーする場合は、必ず両方の句を指定します。両方の句を挿入すると、スクリプトが読みやすくなります。
COPYコマンドの動作は、宛先の表がすでに存在するかどうかおよびユーザーが入力したアクション句(例ではCREATE)によって異なります。詳細は、宛先の表の扱いを制御する方法についてを参照してください。
デフォルトでは、宛先の表にコピーされた列は元の表での名前と同じ名前になります。宛先の表の中で列に新しい名前を指定する場合は、宛先の表名の後に新しい名前をカッコで囲んで入力します。1つでも列名を入力する場合は、コピーするすべての列の名前を入力する必要があります。
注意:
Oracle DatabaseとOracle以外のデータベースの間でデータをコピーできるようにするため、NUMBER列は宛先の表の中でDECIMAL列に変更されます。したがって、Oracle Database間でコピーする場合、精度がないNUMBER列はDECIMAL(38)列に変更されます。Oracle Database間でコピーする場合は、SQLコマンド(CREATE TABLE ASおよびINSERT)を使用するか、列に精度が指定されている必要があります。
USING句を使用すると、元の表に対して問合せを行うことによって、COPYで宛先の表にコピーするデータを指定できます。COPYコマンドでコピーするデータを選択するには、任意の形式でSQLのSELECTコマンドを使用できます。
次に示すCOPYコマンドの例では、ソース表から2つの列のみをコピーし、DEPARTMENT_IDの値が30である行のみをコピーします。
COPY FROM HR@BOSTONDB - REPLACE EMPCOPY2 - USING SELECT LAST_NAME, SALARY - FROM EMP_DETAILS_VIEW - WHERE DEPARTMENT_ID = 30
長いCOPYコマンドは、コマンド・プロンプトから直接入力するよりも、スクリプトに入力して編集する方が簡単です。
宛先の表の扱いを制御するには、REPLACE、CREATE、INSERTまたはAPPENDの4つの制御句のいずれかを入力します。
REPLACE句は、宛先のデータベース内に作成する表の名前を指定し、次のアクションを指定します。
宛先の表がすでに存在する場合、COPYは既存の表を削除し、コピーされたデータが入った表に置き換えます。
宛先の表が存在しない場合、COPYはコピーされたデータを使用してその表を作成します。
既存の表を誤って上書きしないように、CREATE句を使用することができます。CREATEは、次のアクションを指定します。
宛先の表がすでに存在する場合、COPYはエラーを報告して停止します。
宛先の表が存在しない場合、COPYはコピーされたデータを使用してその表を作成します。
既存の表にデータを挿入するには、INSERTを使用します。INSERTは、次のアクションを指定します。
宛先の表がすでに存在する場合、COPYはコピーされたデータを宛先の表に挿入します。
宛先の表が存在しない場合、COPYはエラーを報告して停止します。
既存の表にデータを挿入する場合、または宛先の表が存在しないときに新しい表を作成する場合は、APPENDを使用します。APPENDは、次のアクションを指定します。
宛先の表がすでに存在する場合、COPYはコピーされたデータを宛先の表に挿入します。
表が存在しない場合、COPYは表を作成し、コピーされたデータをその表に挿入します。
COPY FROM HR@BOSTONDB - CREATE EMPCOPY - USING SELECT * FROM HR
Array fetch/bind size is 15. (arraysize is 15) Will commit when done. (copycommit is 0) Maximum long size is 80. (long is 80)
その後、SQL*Plusは表EMPLOYEE_COPYを作成し、行をコピーします。
Table SALESMAN created. 5 rows selected from HR@BOSTONDB. 5 rows inserted into SALESMAN. 5 rows committed into SALESMAN at DEFAULT HOST connection.
このCOPYコマンドにFROM句を指定した場合は、BOSTONDBで指定されたデータベースに、ユーザー名HRで接続されます。
コマンドの終わりにセミコロンを付ける必要はありません。COPYは問合せを含んでいても、SQLコマンドではなくSQL*Plusコマンドです。ほとんどのCOPYは長さが1行を超えるので、最終行を除く各行の終わりにハイフン(-)を使用する必要があります。ハイフンの前に空白を付けてもかまいません。
例B-1 CREATEを使用したリモート・データベースからローカル・データベースへのコピー
リモート・データベースからユーザー自身のデータベース上にあるEMPLOYEE_COPYという表にHRをコピーするには、次のコマンドを入力します。
COPYによって表示される最初の3つのメッセージは、そのCOPY操作に影響するSETコマンド変数の値を示しています。最も重要なのはLONGで、これはLONG列の値の長さを制限します。(LONGは、CHARと同じように1つのデータ型です。)元の表にLONG列が含まれている場合、COPYでは、その列の値はシステム変数LONGで指定された長さまで切り捨てられます。
ARRAYSIZE変数は、SQL*Plusがデータベースから一度にフェッチする行数を制限します。これらの行は、バッチを形成します。COPYCOMMIT変数には、COPYでデータベースに変更がコミットされる前にコピーされるバッチの数を設定します。(COPYCOMMITを0に設定した場合、COPYはすべてのバッチがコピーされた後にのみ、変更をコミットします。)設定の変更方法など、SET変数の詳細は、「SET」コマンドを参照してください。
3つのシステム変数およびそれらの値が表示された後、コピーの間に表の削除、作成または変更があったかどうかが示されます。その後、選択、挿入およびコミットが実行された行数が表示されます。
ローカル・データベースの場合やデータベース・リンクを使用した問合せの場合と同様に、COPYコマンドの中で表名をユーザー名で修飾することによって、別のユーザー表を参照できます。
たとえば、ユーザー名ADAMSが所有し、Oracle Net接続識別子BOSTONDBに対応付けられているデータベース上にあるDEPARTMENTという名前の表のローカル・コピーを作成するには、次のように入力します。
COPY FROM HR@BOSTONDB - CREATE EMPLOYEE_COPY2 - USING SELECT * FROM ADAMS.DEPARTMENT
COPYにリモート・データベースへログインするよう指示することによって、ADAMSと同じ結果を得ることができます。ただし、ユーザー名ADAMSに対応付けられているパスワードを知らないと実行できません。