Tornando Oracle rif cursore e l’aggiunta di più risultati

Ho questo problema sto sperando che qualcuno conosca la risposta. Ho una stored procedure di oracle che prende un id cliente e restituisce tutti gli ordini del cliente in un ref_cursor. Banalizzando, questo è quello che ho:

Orders
- orderId
- siteID

Customers
- siteID
- Name

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

Ora, ho bisogno di scrivere un’altra procedura che prende il nome di un cliente e non un COME query per ottenere tutte custIds, quindi ho bisogno di riutilizzare il metodo GetOrder a restituire tutti gli ordini per il custIds trovato, qualcosa di simile a questo:

   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;

La mia domanda è, come faccio ad aggiungere il ritorno di GetOrder per curReturn in ogni iterazione? Come è scritto adesso sovrascrive in ogni ciclo del loop.
Grazie!!

Minori stile punto: Se si restituisce ordini multipli, quindi GetOrder dovrebbe essere rinominato GetOrders per fini di chiarezza.

OriginaleL’autore Ricardo Villamil | 2009-01-06

2 Replies
  1. 5

    Se la query è semplice, direi di andare con Tony risposta. Questo non è solo semplice, ma probabilmente anche di più a fare meglio l’esecuzione di una query per ogni siteID.

    Se è abbastanza complesso, quindi potrebbe essere la pena di qualche sforzo in più per riutilizzare il GetOrder procedura in modo da avere solo per mantenere una query.

    Per fare questo, è necessario effettivamente recuperare i dati dal refcursor a ogni iterazione del ciclo, e di mettere in qualche altra struttura di dati.

    Un’opzione, se ha senso per l’interfaccia, è quello di cambiare GetOrderbyCustName per avere una PL/SQL indice-da tabella come parametro di output, invece di un refcursor. Aggiungere alla tabella a ogni iterazione del ciclo.

    Se si ha realmente bisogno di restituire un refcursor, è possibile utilizzare una tabella nidificata tipo, invece, e quindi restituire un cursore query nidificate tabella. Qualcosa di simile a questo (non testato), del codice):

    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;
    Si noti che questo richiede la creazione di un nuovo tipo (tabella) nello schema che non è sempre il benvenuto.

    OriginaleL’autore Dave Costa

  2. 6

    Che non si può fare come che – cursori non possono essere aggiunti o unite. Basta fare invece:

    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;

    OriginaleL’autore Tony Andrews

Lascia un commento