2

私は、Oracle がどのように処理するかという問題に対処しようとしてきましROWNUMSELECT ... FOR UPDATE SKIP LOCKEDが、ロックされていないいくつかの行を返そうとしています。私は次のいくつかの解決策を試しました: Oracle に SKIP LOCKED を使用して TOP N 行を返すように強制する、およびその質問で見つかったものと非常によく似た他のいくつかの例。Oracle AQ がおそらくこれに対する最善の解決策であることはわかっていますが、データベースをほとんど制御できず、このアイデアに対するかなりの抵抗に遭遇しました。

私が直面している問題は、JDBC を使用して結果を Java に戻そうとすることです。を試しsetFetchSize(20)ましたが、上位 20 行のみがクライアントに配布されるという問題が発生しました。通常、1 つの処理エージェントが 20 行すべてを取得するか、いくつかのプロセッサがいくつかの行を取得し、すべての行を合計すると 20 になりROWNUMますSELECT ... FOR UPDATE SKIP LOCKED

私が試した最も有望な解決策は、次の機能です。

create type IND_ID as object
(
   ID varchar2(200)
);

create type IND_ID_TABLE as table of IND_ID;

create or replace function SELECTIDS return IND_ID_TABLE
   pipelined is

   ST_CURSOR SYS_REFCURSOR;
   ID_REC IND_ID := IND_ID(null);

begin
   open ST_CURSOR for
      select ID
        from TABLE
    /* where clause */
         for update SKIP LOCKED;   
   loop
      fetch ST_CURSOR
         into ID_REC.ID;
      exit when ST_CURSOR%rowcount > 20 or ST_CURSOR%notfound;
      pipe row(ID_REC);
   end loop;
   close ST_CURSOR;
   return;
end;

ただし、次のように呼び出してみると:

select * from table(SELECTIDS)

エラーが発生しましたORA-14551: cannot perform a DML operation inside a queryが、これはトランザクションの問題であることがわかりました。ロックを解除すると、関数は行を返します。

ロックを保持しながら、この関数から複数の行を JDBC に取得するにはどうすればよいですか?

4

1 に答える 1

-1

これはうまくいきません。select ステートメントの一部として pl/sql 関数を呼び出し、その関数でトランザクションを開始しようとしています。エラーはかなり明確だと思います。

于 2012-06-22T00:41:24.617 に答える