取得
宣言または定義が、別の有効範囲における参照の正常な解決の妨げになる場合、その宣言または定義が参照を「取得する」と呼びます。通常、取得は移行またはスキーマのアップグレードの結果として行われます。
ここでのトピック
外部取得
外部取得が発生するのは、内部有効範囲内の項目に解決されていた内部有効範囲内の名前が、外部有効範囲内の項目に解決される場合です。PL/SQLとSQLは両方とも、外部取得を防止する設計になっているので、外部取得の回避に慎重になる必要はありません。
同一有効範囲の取得
同一有効範囲の取得が発生するのは、結合に使用される2つの表のどちらかに列が追加され、この新しい列の名前が他の表の列名と同じである場合です。その名前の列が1つの表にのみ存在する場合は、名前が未修飾で結合に現れる可能性があります。同一有効範囲の取得を回避するには、その列名が結合に現れるすべての場所で、列名を適切な表名で修飾する必要があります。
内部取得
内部取得が発生するのは、外部有効範囲内の項目に解決されていた内部有効範囲内の名前が、内部有効範囲内の項目に解決される場合か解決できない場合のいずれかです。最初のケースでは結果が変わる可能性があります。2番目のケースではエラーが発生します。
例B-6では、新しい列は、同じ名前の古い列の参照を取得します。col2
は、新しい列col2
が表tab2
に追加される前はtab1.col2
に解決され、追加された後はtab2.col2
に解決されます。
内部取得を防止するには、「SELECT文およびDML文の内部取得の回避」のルールに従います。
例B-6 列の参照の内部取得
表tab1
にはcol2
という名前の列がありますが、表tab2
にはありません。
DROP TABLE tab1; CREATE TABLE tab1 (col1 NUMBER, col2 NUMBER); INSERT INTO tab1 (col1, col2) VALUES (100, 10); DROP TABLE tab2; CREATE TABLE tab2 (col1 NUMBER); INSERT INTO tab2 (col1) VALUES (100);
そのため、内側のSELECT
文では、col2
への参照が列tab1.col2
に解決されます。
CREATE OR REPLACE PROCEDURE proc AUTHID DEFINER AS
CURSOR c1 IS
SELECT * FROM tab1
WHERE EXISTS (SELECT * FROM tab2 WHERE col2 = 10);
BEGIN
OPEN c1;
CLOSE c1;
END;
/
表tab2
への列col2
の追加:
ALTER TABLE tab2 ADD (col2 NUMBER);
これでプロシージャproc
は無効になりました。次に起動する際に、このプロシージャはデータベースによって自動的に再コンパイルされ、内側のSELECT
文におけるcol2
への参照は、列tab2.col2
に解決されます。