4

私はこの問題を抱えています。誰かが答えを知っていることを願っています。顧客 ID を受け取り、すべての顧客の注文を ref_cursor に返す Oracle ストアド プロシージャがあります。それを単純化しすぎて、これは私が持っているものです:

Orders
- orderId
- siteID

Customers
- siteID
- Name

GetOrder(siteID, outCursor) /* returns all orders for a customer */

ここで、顧客名を受け取り、LIKE クエリを実行してすべての custId を取得する別のプロシージャを作成する必要があります。次に、GetOrder メソッドを再利用して、見つかった custId のすべての注文を返す必要があります。次のようになります。

   PROCEDURE GetOrderbyCustName(
      p_name       IN        VARCHAR2,
      curReturn    OUT       sys_refcursor
   )
   IS
      siteid    number;
   BEGIN
      FOR rec in SELECT site_id FROM customers WHERE name LIKE p_name
      LOOP 
      -- This will replace curReturn in each iteration
      -- how do I append instead?
        GetOrder(rec.site_id,
                   curReturn
                  );
      END LOOP;
   END GetOrderbyCustName;

私の質問は、各反復で GetOrder の戻り値を curReturn に追加するにはどうすればよいですか? 現在書かれているように、ループの各サイクルで上書きされます。ありがとう!!

4

2 に答える 2

7

そのようにすることはできません-カーソルを追加またはマージすることはできません。代わりにこれを行うだけです:

PROCEDURE GetOrderbyCustName(
   p_name       IN        VARCHAR2,
   curReturn    OUT       sys_refcursor
)
IS
BEGIN
   OPEN curReturn FOR 
      SELECT o.orderID, o.siteID
      FROM Orders o
      JOIN Customers c ON c.siteID = o.siteID
      WHERE c.name LIKE p_name;
END GetOrderbyCustName;
于 2009-01-06T18:10:29.427 に答える
5

クエリが単純な場合は、Tony の回答を使用します。これは単純であるだけでなく、サイト ID ごとに 1 つのクエリを実行するよりもパフォーマンスが向上する可能性があります。

かなり複雑な場合は、GetOrder プロシージャを再利用して、クエリを 1 つだけ維持する必要があるため、追加の作業を行う価値があります。

これを行うには、ループの反復ごとに refcursor から実際にデータをフェッチし、それを他のデータ構造に入れる必要があります。

インタフェースにとって意味がある場合の 1 つのオプションは、GetOrderbyCustName を変更して、refcursor の代わりに PL/SQL インデックス付きテーブルを出力パラメータとして持つことです。ループの各反復でそのテーブルに追加します。

本当に refcursor を返す必要がある場合は、代わりにネストされたテーブル型を使用して、そのネストされたテーブルを照会するカーソルを返すことができます。このようなもの(テストされていないコード):

CREATE TYPE number_table_type AS TABLE OF NUMBER;

PROCEDURE GetOrderbyCustName(
      p_name       IN        VARCHAR2,
      curReturn    OUT       sys_refcursor
   )
   IS
      cursor_source_table  number_table_type := number_table_type();
      single_site_cursor  sys_refcursor;
      orderID  NUMBER;
   BEGIN
      FOR rec in SELECT site_id FROM customers WHERE name LIKE p_name
      LOOP 
      -- This will replace curReturn in each iteration
      -- how do I append instead?
        GetOrder(rec.site_id,
                   single_site_cursor
                  );

        -- Fetch all rows from the refcursor and append them to the nested table in memory
        LOOP
          FETCH single_site_cursor INTO orderID;
          EXIT WHEN single_site_cursor%NOTFOUND;
          cursor_source_table.extend();
          cursor_source_table( cursor_source_table.COUNT+1) := orderID;
        END LOOP;
      END LOOP;

      OPEN curReturn FOR
        SELECT * FROM TABLE( cursor_source_table );

   END GetOrderbyCustName;
于 2009-01-07T16:14:14.933 に答える