スキーマ・オブジェクトの構文およびSQL文の構成要素
SQL文のコンテキストでスキーマ・オブジェクトとそれらの部分を参照する方法について説明します。次の項目について説明します。
-
オブジェクトを参照するための一般的な構文
-
Oracleがオブジェクトへの参照を変換する方法
-
自分のスキーマ以外のスキーマ内のオブジェクトを参照する方法
-
リモート・データベース内のオブジェクトを参照する方法
-
表と索引のパーティションおよびサブパーティションを参照する方法
次に、オブジェクトやそれらの部分を参照するための一般的な構文を示します。
database_object_or_part::=
説明:
-
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
を変換しようとします。
-
Oracleは、最初に、表、ビューおよびプライベート・シノニムを含む文を発行したユーザーのスキーマ内のネームスペースで、オブジェクトの位置を確認しようとします。そのオブジェクトがプライベート・シノニムである場合は、Oracleはそのシノニムが表すオブジェクトの位置を確認します。このオブジェクトは、ユーザーのスキーマに存在することもあれば、別のスキーマまたは別のデータベースに存在することもあります。このオブジェクトが別のシノニムである場合もあります。その場合、Oracleはそのシノニムが表すオブジェクトの位置を確認します。
-
オブジェクトがネームスペース内に存在する場合、Oracleはそのオブジェクトに対して文を実行しようとします。この例では、Oracleはデータ行を
departments
に追加しようとします。オブジェクトがその処理にとって正しい型でない場合、Oracleはエラーを戻します。この場合、departments
は、表またはビュー、あるいは表またはビューとなるプライベート・シノニムである必要があります。departments
が順序である場合、Oracleはエラーを戻します。 -
前述の処理で検索されたネームスペースにオブジェクトが存在しない場合、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を使用している場合にのみ利用できます。データベース・リンクを含むSQL文の発行時に、次のいずれかの方法でデータベース・リンク名を指定します。
-
データ・ディクショナリ内に格納される、
database
、domain
、およびオプションのconnection_qualifier
コンポーネントを含む完全なデータベース・リンク名を指定します。 -
database
とオプションのconnection_qualifier
が含まれ、domain
は含まれない、部分的データベース・リンク名を指定します。
Oracleは、リモート・データベースに接続する前に次のタスクを実行します。
-
文中に指定されているデータベース・リンク名が部分指定の場合、Oracleは、データ・ディクショナリ内に格納されているグローバル・データベース名に見られるとおり、そのリンク名にローカル・データベースのドメイン名を付加します。現在のグローバル・データベース名は、
GLOBAL_NAME
データ・ディクショナリ・ビューで見ることができます。 -
Oracleは、最初に、文を発行したユーザーのスキーマ内で、文の中のデータベース・リンクと同じ名前を持つプライベート・データベース・リンクを検索します。必要に応じて、同じ名前を持つパブリック・データベース・リンクを検索します。
-
Oracleは、必ず最初に一致したデータベース・リンク(プライベートまたはパブリック)のユーザー名およびパスワードを採用します。最初に一致したデータベース・リンクに対応付けられているユーザー名およびパスワードがあると、Oracleはそれを使用します。対応付けられているユーザー名およびパスワードがない場合、Oracleは、現在のユーザー名およびパスワードを使用します。
-
最初に一致したデータベース・リンクに対応付けられているデータベース文字列が存在する場合、Oracleは、そのデータベース文字列を使用します。データベース文字列がない場合、Oracleは一致する次の(パブリック)データベース・リンクを検索します。一致するデータベース・リンクが存在しない場合、または一致するリンクに対応付けられているデータベース文字列が存在しない場合、Oracleはエラーを戻します。
-
-
Oracleは、リモート・データベースにアクセスするためにデータベース文字列を使用します。リモート・データベースにアクセスした後で、
GLOBAL_NAMES
パラメータの値がtrue
の場合は、Oracleは、データベース・リンク名のdatabase.domain
部分がリモート・データベースの完全なグローバル名に一致しているかどうかを確認します。この条件が満たされている場合、Oracleはステップ2で選択したユーザー名とパスワードを使用して接続を続行します。それ以外の場合、Oracleはエラーを戻します。 -
データベース文字列、ユーザー名およびパスワードを使用した接続が成功した場合、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文INSERT
、UPDATE
、DELETE
、およびANALYZE
文では、パーティション名またはサブパーティション名をカッコで囲む必要があります。細かな違いですが、partition_extension_clause
に影響します。
partition_extension_clause::=
partition_extended_name
、subpartition_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
TABLE
のINTERVAL句を参照してください。
拡張名の制限事項
現在、拡張パーティション表名および拡張サブパーティション表名の使用には、次の制限があります。
-
リモート表は使用できません。拡張パーティション表名または拡張サブパーティション表名には、データベース・リンク(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