0

2 つのテーブルの完全結合でカーソルを実行しようとしていますが、カーソル内の列へのアクセスに問題があります。

CREATE  TABLE APPLE(
    MY_ID           VARCHAR(2) NOT NULL,
    A_TIMESTAMP     TIMESTAMP,
    A_NAME          VARCHAR(10)
);

CREATE  TABLE BANANA(
    MY_ID           VARCHAR(2) NOT NULL,
    B_TIMESTAMP     TIMESTAMP,
    B_NAME          VARCHAR(10)
);

2 つのタイムスタンプのいずれかが未来であるテーブル A と B から関連するすべての行を返す完全結合を作成しました。つまり、テーブル APPLE の行に未来のタイムスタンプがある場合、MY_ID の BANANA の行と結合された APPLE から行をフェッチします。私のために働きます。

select * from APPLE a full join BANANA b on  a.MY_ID = b.MY_ID where 
    (
      a.A_TIMESTAMP > current_timestamp
      or b.B_TIMESTAMP > current_timestamp 
    );

ここで、結合された各レコードを反復処理して、何らかの処理を行いたいと考えています。1 つのテーブルにのみ存在する列にアクセスできますが、両方のテーブルで同じ列名にアクセスしようとするとエラーが発生します。たとえば。この場合の ID。

create or replace 
PROCEDURE testProc(someDate IN DATE)
AS
CURSOR c1 IS
    select * from APPLE a full join BANANA b on  a.MY_ID = b.MY_ID where 
    (
      a.A_TIMESTAMP > current_timestamp
      or b.B_TIMESTAMP > current_timestamp 
    );

BEGIN
    FOR rec IN c1
    LOOP    
        DBMS_OUTPUT.PUT_LINE(rec.A_NAME);
        DBMS_OUTPUT.PUT_LINE(rec.A_TIMESTAMP);
        DBMS_OUTPUT.PUT_LINE(rec.MY_ID);
    END LOOP;
END testProc;

上記のプロシージャをコンパイルすると、次のエラーが発生します。

エラー(16,28): PLS-00302: コンポーネント'MY_ID'を宣言する必要があります

MY_ID 要素にアクセスする方法がわかりません。私はそれがかなり簡単になると確信していますが、私はデータベースプログラミングに不慣れで、それを行う正しい方法を見つけることができませんでした. どんな助けでも大歓迎です。ありがとう

4

2 に答える 2

1

問題はMY_ID、両方のテーブルで定義されているため、*両方を取得することだと思います。次のクエリを使用してカーソルを定義してみてください。

select coalesce(A.MY_ID, B.MY_ID) as MY_ID,
       A_TIMESTAMP, A_NAME, B_TIMESTAMP, B_NAME
from APPLE a full join
     BANANA b
     on a.MY_ID = b.MY_ID
where a.A_TIMESTAMP > current_timestamp or b.B_TIMESTAMP > current_timestamp;

編集:

競合する列には 2 つの問題があります。これが単なる内部結合である場合は、次のことができます。

select A.*, B_TIMESTAMP, B_NAME

つまり、を使用して 1 つのテーブルから列を選択し*、残りを個別に選択できます。ただし、これは であるfull outer joinため、使用したい列のセットがありますcoalesce()

したがって、最良の答えは、すべての列をリストすることです。いずれにしても、これは適切なコーディング プラクティスであり、列がテーブルに追加されたり、テーブルから削除されたりするときに、コードを不注意によるミスから保護するのに役立ちます。

于 2013-07-21T19:14:33.250 に答える