Poiché si utilizza Oracle, creerei le funzioni TABLE pipelined. La funzione accetta parametri e restituisce un oggetto (che devi creare) e quindi SELEZIONA * o anche colonne specifiche da esso utilizzando la funzione TABLE() e può utilizzarlo con una clausola WHERE o con JOINs. Se si desidera un'unità di riutilizzo (una funzione) non si è limitati a restituire solo valori (vale a dire una funzione scalare) è possibile scrivere una funzione che restituisce righe o recordset. qualcosa di simile:
FUNCTION RETURN_MY_ROWS(Param1 IN type...ParamX IN Type)
RETURN PARENT_OBJECT PIPELINED
IS
local_curs cursor_alias; --you need a cursor alias if this function is in a Package
out_rec ROW_RECORD_OF_CUSTOM_OBJECT:=ROW_RECORD_OF_CUSTOM_OBJECT(NULL, NULL,NULL) --one NULL for each field in the record sub-object
BEGIN
OPEN local_curs FOR
--the SELECT query that you're trying to encapsulate goes here
-- and it can be very detailed/complex and even have WITH() etc..
SELECT * FROM baseTable WHERE col1 = x;
-- now that you have captured the SELECT into a Cursor
-- here you put a LOOP to take what's in the cursor and put it in the
-- child object (that holds the individual records)
LOOP
FETCH local_curs --opening the ref-cursor
INTO out_rec.COL1,
out_rec.COL2,
out_rec.COL3;
EXIT WHEN local_curs%NOTFOUND;
PIPE ROW(out_rec); --piping out the Object
END LOOP;
CLOSE local_curs; -- always do this
RETURN; -- we're now done
END RETURN_MY_ROWS;
dopo aver fatto questo, è possibile utilizzarlo in questo modo
SELECT * FROM TABLE(RETURN_MY_ROWS(val1, val2));
è possibile inserire SELECT o addirittura CREATE TABLE fuori di esso, si può avere nei join .
altre due cose parlare:
--ROW_RECORD_OF_CUSTOM_OBJECT is something along these lines
CREATE or REPLACE TYPE ROW_RECORD_OF_CUSTOM_OBJECT AS OBJECT
(
col1 type;
col2 type;
...
colx type;
);
e PARENT_OBJECT è una tabella dell'altro oggetto (con le definizioni di campo) abbiamo appena fatto
create or replace TYPE PARENT_OBJECT IS TABLE OF ROW_RECORD_OF_CUSTOM_OBJECT;
quindi questa funzione necessita di due oggetti per supportare ma uno è un record, l'altro è una tabella di quel record (devi prima creare il record).
In breve, la funzione è facile da scrivere, è necessario un oggetto figlio (con campi) e un oggetto padre che ospiterà l'oggetto figlio di tipo TABLE dell'oggetto figlio e verrà aperto l'originale tabella di base che preleva SQL in un SYS_REFCURSOR (che potrebbe essere necessario per l'alias) se si è in un pacchetto e si legge da quel cursore da un loop ai singoli record. La funzione restituisce un tipo di PARENT_OBJECT ma al suo interno racchiude il sottooggetto record con i valori del cursore.
Spero che questo funziona per voi (ci possono essere problemi di permissioning con la DBA, se si desidera creare oggetti e funzioni tabella) */
Buono, ma vorrei gestire oggetti unici per horrible_query_1 diverso rispetto gestisco gli oggetti unici per ugly_query_2. È possibile dire con quale serie gli articoli sono unici con questa query? EDIT: le viste possono essere la soluzione migliore per SQL semplice. – Buttons840
Certo, avvolgi le tue operazioni con due set in query esterne con selezioni che includono colonne fisse chiamate Source, ad esempio 'SELECT 'horrible_query_1' AS Source, *' e 'SELECT 'ugly_query_2' AS Source, *'. In questo modo la tua UNION ti fornirà tutte le colonne della tua query più l'identificatore della fonte. – JamieSee
L'ultimo esempio, utilizzando le "clausole con" è stato molto utile nel corso degli anni da quando ho posto questa domanda in origine. Queste "clausole con" sono talvolta chiamate espressioni di tabella comuni (o CTE). Questi sono alcuni termini utili da sapere quando si cercano maggiori dettagli. Le clausole con-sono state aggiunte allo standard SQL nel 1999, quindi la maggior parte dei database dovrebbe supportarle, tranne MySQL che non ha ancora implementato questa parte dello standard ventennale. – Buttons840