スキーマ・オブジェクトの構文およびSQL文の構成要素

SQL文のコンテキストでスキーマ・オブジェクトとそれらの部分を参照する方法について説明します。次の項目について説明します。

  • オブジェクトを参照するための一般的な構文

  • Oracleがオブジェクトへの参照を変換する方法

  • 自分のスキーマ以外のスキーマ内のオブジェクトを参照する方法

  • リモート・データベース内のオブジェクトを参照する方法

  • 表と索引のパーティションおよびサブパーティションを参照する方法

次に、オブジェクトやそれらの部分を参照するための一般的な構文を示します。

database_object_or_part::=

(dblink::=)

説明:

  • objectは、オブジェクトの名前です。

  • schemaは、オブジェクトを含むスキーマです。この修飾子を指定することによって、自分のスキーマ以外のスキーマ内のオブジェクトを参照できます。その場合には、自分のスキーマ以外のスキーマ内のオブジェクトを参照するための権限が必要です。この修飾子を指定しないと、自分自身のスキーマ内のオブジェクトを参照するものとみなされます。

    スキーマ・オブジェクトのみがschemaで修飾できます。スキーマ・オブジェクトについては、規則8を参照してください。規則8に示す非スキーマ・オブジェクトはスキーマ・オブジェクトではないため、schemaでは修飾できません。ただし、パブリック・シノニムは例外で、「PUBLIC」で修飾できます。この場合、引用符が必要です。

  • partは、オブジェクトの部分です。この識別子によって、スキーマ・オブジェクトの部分(たとえば、表の列またはパーティション)を参照できます。なお、すべてのタイプのオブジェクトが部分を持っているとはかぎりません。

  • dblinkは、Oracle Databaseの分散オプションを使用している場合にのみ適用されます。オブジェクトを含むデータベースの名前です。この修飾子dblinkを指定することによって、ローカル・データベース以外のデータベース内のオブジェクトを参照できます。このdblinkを指定しないと、自分自身のローカル・データベース内のオブジェクトを参照するものとみなされます。なお、すべてのSQL文でリモート・データベースのオブジェクトにアクセスできるとはかぎりません。

オブジェクトを参照する際のコンポーネントを区切っているピリオドの前後には、空白を入れることができます。ただし、通常は入れません。

Oracle Databaseによるスキーマ・オブジェクト参照の変換方法

SQL文内のオブジェクトが参照される場合、OracleはそのSQL文のコンテキストを検討して、該当するネームスペース内でそのオブジェクトの位置を確認します。そのオブジェクトの位置を確認してから、そのオブジェクトに対して文が指定する操作を実行します。指定した名前のオブジェクトが適切なネームスペース内に存在しない場合、Oracleはエラーを戻します。

次の例で、OracleがSQL文内のオブジェクト参照を変換する方法について説明します。名前departmentsで識別される表にデータ行を追加する次の文を考えます。

INSERT INTO departments
  VALUES (280, 'ENTERTAINMENT_CLERK', 206, 1700);

文のコンテキストに基づいて、Oracleは、departmentsが次のようなオブジェクトであると判断します。

  • 自分のスキーマ内の表

  • 自分のスキーマ内のビュー

  • 表またはビューに対するプライベート・シノニム

  • パブリック・シノニム

Oracleは、文を発行したユーザーのスキーマ外のネームスペースを考慮する前に、そのユーザーのスキーマ内のネームスペースからオブジェクト参照を変換しようとします。この例では、Oracleは次の方法で名前departmentsを変換しようとします。

  1. Oracleは、最初に、表、ビューおよびプライベート・シノニムを含む文を発行したユーザーのスキーマ内のネームスペースで、オブジェクトの位置を確認しようとします。そのオブジェクトがプライベート・シノニムである場合は、Oracleはそのシノニムが表すオブジェクトの位置を確認します。このオブジェクトは、ユーザーのスキーマに存在することもあれば、別のスキーマまたは別のデータベースに存在することもあります。このオブジェクトが別のシノニムである場合もあります。その場合、Oracleはそのシノニムが表すオブジェクトの位置を確認します。

  2. オブジェクトがネームスペース内に存在する場合、Oracleはそのオブジェクトに対して文を実行しようとします。この例では、Oracleはデータ行をdepartmentsに追加しようとします。オブジェクトがその処理にとって正しい型でない場合、Oracleはエラーを戻します。この場合、departmentsは、表またはビュー、あるいは表またはビューとなるプライベート・シノニムである必要があります。departmentsが順序である場合、Oracleはエラーを戻します。

  3. 前述の処理で検索されたネームスペースにオブジェクトが存在しない場合、Oracleはパブリック・シノニムを含むネームスペースを検索します。オブジェクトがそのネームスペースに存在する場合、Oracleはそのオブジェクトに対して文を実行しようとします。オブジェクトがその処理にとって正しい型でない場合、Oracleはエラーを戻します。この例では、departmentsが順序のパブリック・シノニムである場合、Oracleはエラーを戻します。

パブリック・シノニムに、依存表またはユーザー定義型がある場合は、依存オブジェクトと同じスキーマに、シノニムと同じ名前でオブジェクトを作成することはできません。

シノニムに、依存表またはユーザー定義型がない場合は、依存オブジェクトと同じスキーマに、依存オブジェクトと同じ名前で、オブジェクトを作成できます。すべての依存オブジェクトが無効になり、次のアクセス時に妥当性チェックが再実行されます。

関連項目:

識別子名を解決するPL/SQLの詳細は、Oracle Database PL/SQL言語リファレンスを参照

他のスキーマ内のオブジェクトの参照

自分が所有するスキーマ以外のスキーマ内のオブジェクトを参照するには、次のように、オブジェクト名の前にスキーマ名を付けます。

schema.object

たとえば、次の文は、サンプル・スキーマhr内のemployees表を削除します。

DROP TABLE hr.employees;

リモート・データベース内のオブジェクトの参照

ローカル・データベース以外のデータベース内のオブジェクトを参照するには、オブジェクト名の後に、そのデータベースへのデータベース・リンクの名前を続けます。データベース・リンクはスキーマ・オブジェクトであり、これによってOracleがリモート・データベースに接続され、そこにあるオブジェクトにアクセスします。この項では、次の項目について説明します。

  • データベース・リンクを作成する方法

  • SQL文でデータベース・リンクを使用する方法

データベース・リンクの作成

「CREATE DATABASE LINK」を使用して、データベース・リンクを作成します。この文では、データベース・リンクに関する次の情報を指定できます。

  • データベース・リンク名

  • リモート・データベースにアクセスするためのデータベース接続文字列

  • リモート・データベースに接続するためのユーザー名およびパスワード

これらの情報はデータ・ディクショナリに格納されます。

データベース・リンク名

データベース・リンクを作成するとき、データベース・リンク名を指定する必要があります。データベース・リンク名は、他のオブジェクト型の名前とは異なります。データベース・リンク名は128バイト以内の長さで指定し、ピリオド(.)とアットマーク(@)を使用できます。

データベース・リンクに付ける名前は、データベース・リンクが参照するデータベースの名前、およびデータベース名の階層内のそのデータベースの位置に一致している必要があります。次に、データベース・リンク名の書式を示します。

dblink::=

説明:

  • databaseには、データベース・リンクの接続先であるリモート・データベースのグローバル名のうち、nameの部分を指定します。このグローバル名は、リモート・データベースのデータ・ディクショナリに格納されます。この名前は、GLOBAL_NAMEデータ・ディクショナリ・ビューで確認できます。

  • domainには、データベース・リンクの接続先であるリモート・データベースのグローバル名のうち、domainの部分を指定します。データベース・リンクの名前にdomainを指定しないと、Oracleは、現在、データ・ディクショナリに存在しているローカル・データベースのドメインに、データベース・リンク名を付加します。

  • connection_qualifierによって、データベース・リンクをさらに修飾できます。接続修飾子を使用する場合、同じデータベースに複数のデータベース・リンクを作成できます。たとえば、接続修飾子を使用して、同じデータベースにアクセスするOracle Real Application Clustersの異なるインスタンスに、複数のデータベース・リンクを作成できます。

    関連項目:

    接続修飾子の詳細は、『Oracle Database管理者ガイド』を参照してください。

database.domainの組合せは、サービス名と呼ばれることもあります。

ユーザー名およびパスワード

リモート・データベースに接続するために、ユーザー名およびパスワードを使用します。データベース・リンクでは、ユーザー名およびパスワードはオプションです。

データベース接続文字列

データベース接続文字列は、Oracle Netがリモート・データベースにアクセスするために使用する仕様です。データベース接続文字列の記述方法については、使用しているネットワーク・プロトコル用のOracle Netのドキュメントを参照してください。データベース・リンクのデータベース接続文字列はオプションです。

データベース・リンクの参照

データベース・リンクは、分散オプションを指定してOracleを使用している場合にのみ利用できます。データベース・リンクを含むSQL文の発行時に、次のいずれかの方法でデータベース・リンク名を指定します。

  • データ・ディクショナリ内に格納される、databasedomain、およびオプションのconnection_qualifierコンポーネントを含む完全なデータベース・リンク名を指定します。

  • databaseとオプションのconnection_qualifierが含まれ、domainは含まれない、部分的データベース・リンク名を指定します。

Oracleは、リモート・データベースに接続する前に次のタスクを実行します。

  1. 文中に指定されているデータベース・リンク名が部分指定の場合、Oracleは、データ・ディクショナリ内に格納されているグローバル・データベース名に見られるとおり、そのリンク名にローカル・データベースのドメイン名を付加します。現在のグローバル・データベース名は、GLOBAL_NAMEデータ・ディクショナリ・ビューで見ることができます。

  2. Oracleは、最初に、文を発行したユーザーのスキーマ内で、文の中のデータベース・リンクと同じ名前を持つプライベート・データベース・リンクを検索します。必要に応じて、同じ名前を持つパブリック・データベース・リンクを検索します。

    • Oracleは、必ず最初に一致したデータベース・リンク(プライベートまたはパブリック)のユーザー名およびパスワードを採用します。最初に一致したデータベース・リンクに対応付けられているユーザー名およびパスワードがあると、Oracleはそれを使用します。対応付けられているユーザー名およびパスワードがない場合、Oracleは、現在のユーザー名およびパスワードを使用します。

    • 最初に一致したデータベース・リンクに対応付けられているデータベース文字列が存在する場合、Oracleは、そのデータベース文字列を使用します。データベース文字列がない場合、Oracleは一致する次の(パブリック)データベース・リンクを検索します。一致するデータベース・リンクが存在しない場合、または一致するリンクに対応付けられているデータベース文字列が存在しない場合、Oracleはエラーを戻します。

  3. Oracleは、リモート・データベースにアクセスするためにデータベース文字列を使用します。リモート・データベースにアクセスした後で、GLOBAL_NAMESパラメータの値がtrueの場合は、Oracleは、データベース・リンク名のdatabase.domain部分がリモート・データベースの完全なグローバル名に一致しているかどうかを確認します。この条件が満たされている場合、Oracleはステップ2で選択したユーザー名とパスワードを使用して接続を続行します。それ以外の場合、Oracleはエラーを戻します。

  4. データベース文字列、ユーザー名およびパスワードを使用した接続が成功した場合、Oracleは、リモート・データベース上の指定されたオブジェクトにアクセスしようとします。このとき、この項の前半で説明した、オブジェクト参照を変換するための規則、および他のスキーマ内のオブジェクトを参照するための規則が使用されます。

リモート・データベースの完全なグローバル名が、データベース・リンクのdatabase.domain部分と一致する必要があるという要件を無効にするには、初期化パラメータGLOBAL_NAMESか、ALTER SYSTEMまたはALTER SESSION文のGLOBAL_NAMESパラメータにFALSEを設定します。

関連項目:

リモート・データベースの名前の変換の詳細は、『Oracle Database管理者ガイド』を参照してください。

パーティション表と索引の参照

表および索引はパーティション化できます。パーティション化されたスキーマ・オブジェクトは、パーティションと呼ばれる多数の部分で構成され、各パーティションのすべての論理属性は同じです。たとえば、表のパーティションはすべて同じ列定義と制約定義を共有し、索引のパーティションはすべて同じ索引列を共有します。

拡張パーティション名および拡張サブパーティション名を使用すると、パーティション・レベルやサブパーティション・レベルの操作(たとえば特定のパーティションまたはサブパーティションのすべての行の削除)を、1つのパーティションまたはサブパーティションのみに対して実行できます。拡張名を使用しないでそのような操作を実行する場合は、述語(WHERE句)の指定が必要になります。レンジ/リスト・パーティション表の場合は、パーティション・レベルの操作を述語で表現しようとすると、非常に複雑になることがあります(特に、レンジ・パーティション・キーで複数の列が使用されているとき)。ハッシュ・パーティション/サブパーティションの場合は、述語を使用するとさらに複雑になります(このようなパーティション/サブパーティションはシステム定義のハッシュ・ファンクションに基づいているため)。

拡張パーティション名を使用すると、パーティションを表と同じように扱うことができます。この方法の利点(レンジ・パーティション表に対して最も有益)は、これらのビューに対する権限を他のユーザーやロールに付与する(または権限を取り消す)ことによってパーティション・レベルのアクセス制御メカニズムを構築できることです。パーティションを表として使用するには、1つのパーティションからデータを選択してビューを作成し、このビューを表として使用します。

構文

構文にpartition_extended_name要素またはsubpartition_extended_name要素が指定されているSQL文には、拡張パーティション表名および拡張サブパーティション表名を指定できます。

partition_extended_name::=

subpartition_extended_name::=

DML文INSERTUPDATEDELETE、およびANALYZE文では、パーティション名またはサブパーティション名をカッコで囲む必要があります。細かな違いですが、partition_extension_clauseに影響します。

partition_extension_clause::=

partition_extended_namesubpartition_extended_nameおよびpartition_extension_clauseでは、PARTITION FOR句およびSUBPARTITION FOR句を使用すると、名前がなくてもパーティションを参照できます。これらの句は、すべてのタイプのパーティション化に有効であり、特に時間隔パーティションで役立ちます。データが表に挿入されると、必要に応じて時間隔パーティションが自動的に作成されます。

partition_key_valueおよびsubpartition_key_valueには、パーティション化キー列1つにつき1つの値を指定します。複数列のパーティション化キーの場合は、パーティション化キーごとに1つの値を指定します。コンポジット・パーティションの場合は、パーティション化キーごとに1つの値を指定し、その後にサブパーティション化キーごとに1つの値を指定します。パーティション化キーの値はすべて、カンマで区切ります。時間隔パーティションには、1つのpartition_key_valueのみを指定できます。この値は、有効なNUMBERまたは日時値にする必要があります。指定した値が格納されているパーティションまたはサブパーティションが、SQL文による操作の対象となります。

関連項目:

時間隔パーティションの詳細は、CREATE TABLEINTERVAL句を参照してください。

拡張名の制限事項

現在、拡張パーティション表名および拡張サブパーティション表名の使用には、次の制限があります。

  • リモート表は使用できません。拡張パーティション表名または拡張サブパーティション表名には、データベース・リンク(dblink)、またはdblinkを使用して表に変換するシノニムを含めることはできません。リモートのパーティションやサブパーティションを使用するには、リモート・サイトで拡張表名の構文を使用してビューを作成し、そのリモート・ビューを参照します。

  • シノニムは使用できません。拡張パーティションまたは拡張サブパーティションは、実表を使用して指定する必要があります。シノニムやビューなど、他のオブジェクトは使用できません。

  • PARTITION FOR句およびSUBPARTITION FOR句は、ビューでのDDL操作に対しては無効になります。

  • PARTITION FOR句およびSUBPARTITION FOR句では、キーワードDEFAULTまたはMAXVALUE、あるいはpartition_key_valueまたはsubpartition_key_valueのバインド変数を指定できません。

  • PARTITIONおよびSUBPARTITION句では、パーティション名またはサブパーティション名にバインド変数を指定できません。

次の文のsalesは、パーティションsales_q1_2000を持つパーティション表です。単一パーティションsales_q1_2000のビューを作成でき、それを表のように使用できます。この例では、パーティションから行が削除されます。

CREATE VIEW Q1_2000_sales AS
  SELECT *
    FROM sales PARTITION (SALES_Q1_2000);

DELETE FROM Q1_2000_sales
  WHERE amount_sold < 0; 

オブジェクト型の属性とメソッドの参照

SQL文のオブジェクト型の属性とメソッドを参照するには、参照を表の別名で完全に修飾する必要があります。次の例では、cust_address_typ型、およびcust_address_typに基づくcust_address列を持つ表customersを含むサンプル・スキーマoeについて考えます。

CREATE TYPE cust_address_typ
  OID '82A4AF6A4CD1656DE034080020E0EE3D'
  AS OBJECT
    (street_address    VARCHAR2(40),
     postal_code       VARCHAR2(10),
     city              VARCHAR2(30),
     state_province    VARCHAR2(10),
     country_id        CHAR(2));
/
CREATE TABLE customers
  (customer_id        NUMBER(6),
   cust_first_name    VARCHAR2(20) CONSTRAINT cust_fname_nn NOT NULL,
   cust_last_name     VARCHAR2(20) CONSTRAINT cust_lname_nn NOT NULL,
   cust_address       cust_address_typ,
. . .

次に示すとおり、SQL文では、postal_code属性への参照は表別名を使用して完全に修飾する必要があります。

SELECT c.cust_address.postal_code
  FROM customers c;

UPDATE customers c
  SET c.cust_address.postal_code = '14621-2604'
  WHERE c.cust_address.city = 'Rochester'
    AND c.cust_address.state_province = 'NY';

引数を取らないメンバー・メソッドを参照する場合は、空のカッコを付ける必要があります。たとえば、サンプル・スキーマoeには、メンバー・ファンクションgetCatalogNameを含むcatalog_typに基づくオブジェクト表categories_tabが含まれます。SQL文でこのメソッドをコールするには、次の例のように、空のカッコを付ける必要があります。

SELECT TREAT(VALUE(c) AS catalog_typ).getCatalogName() "Catalog Type"
  FROM categories_tab c
  WHERE category_id = 90;

Catalog Type
------------------------------------
online catalog