Di seguito un esempio di come introdurre la paginazione all'interno di un REST, questo può essere utile se il numero di record è elevato e si vuole restituire un risultato il prima possibile in modo da fare vedere prima i primi 1000 record e così via.
Supponiamo di richiamare un pl-sql nel nostro handler:
Vediamo prima la struttura del pl-sql e poi dell'handler. Di seguito la struttura della procedura pl-sql richiamata in un package.
PROCEDURE getElement (
user_id in varchar2,
element_type_cd in varchar2 default null,
---- Parametri impaginazione
page in number default 1,
numrows in number default 1000,
---- Fine Parametri impaginazione
OUT_COUNT OUT NUMBER,
OUT_ELEMENT_TYPES OUT SYS_REFCURSOR)
AS
--- <dichiarazioni di variabili >
...
---------------------------------------------
---- calcolo paginazione
---------------------------------------------
l_page number := (page * numrows) - numrows;
l_rows number := numrows;
BEGIN
------------------------------
--- count
--------------------------------------------------------
SELECT COUNT(1) INTO out_count
FROM ....
IF OUT_COUNT = 0 THEN
RAISE NO_DATA_FOUND;
END IF;
------------------------------
--- sys_refcursor
------------------------------
OPEN OUT_ELEMENT_TYPES FOR
WITH
js AS (SELECT ... )
)
SELECT js.*, jt.*
FROM js , jt
offset l_page rows fetch next l_rows rows only;
END getElement;
A questo punto vediamo la definizione della get:
BEGIN
GETELEMENT(
USER_ID => :USER_ID,
ELEMENT_TYPE_CD => :ELEMENT_TYPE_CD,
PAGE => nvl(:pag,1),
NUMROWS => nvl(:numrows,1000),
OUT_COUNT => :OUT_COUNT,
OUT_ELEMENT_TYPES => :OUT_ELEMENT_TYPES
);
END;
A questo punto occorre definire le variabili di input ed output del REST.
A questo punto basta effettuare una chiamata REST con SOAP_UI o POSTMAN fornendo in input le varibile difinite dal package, se PAGE o NUMROWS non saranno valorizzate in automatico passiamo 1 e 1000, per andare avanti nella paginazione effettuare una seconda chiamata e passare un nuovo numero di pagina o di righe da ritornare.
Finito.
giovedì 14 maggio 2020
mercoledì 13 maggio 2020
RDBMS ORACLE - SPLIT TEXT with Function
Altro modo per ottenere lo split di una stringa è l'utilizzo di una funzione creata appositamente per ritornare i singoli componenti della stringa divisi da un delimitatore:
-- ----------------------------------------------------------------------------
FUNCTION split_text (p_text IN CLOB,
p_delimeter IN VARCHAR2 DEFAULT '§')
RETURN t_split_array IS
-- ----------------------------------------------------------------------------
l_array t_split_array := t_split_array();
l_text CLOB := p_text;
l_idx NUMBER;
BEGIN
l_array.delete;
IF l_text IS NULL THEN
RAISE_APPLICATION_ERROR(-20000, 'P_TEXT parameter cannot be NULL');
END IF;
WHILE l_text IS NOT NULL LOOP
l_idx := INSTR(l_text, p_delimeter);
l_array.extend;
IF l_idx > 0 THEN
l_array(l_array.last) := SUBSTR(l_text, 1, l_idx - 1);
l_text := SUBSTR(l_text, l_idx + 1);
ELSE
l_array(l_array.last) := l_text;
l_text := NULL;
END IF;
END LOOP;
RETURN l_array;
END split_text;
-- ----------------------------------------------------------------------------
Questa funzione può essere richiamata all'interno di uno statement pl-sql nel seguente modo:
PROCEDURA PL-SQL
....
str_1 t_split_array;
BEGIN
...
str_1 := split_text (v_resourceid1,v_delimeter) ;
for i in 1..str_1.count
loop
dbms_output.put_line(str_1(i));
end loop;
....
END;
Questo se occorre processare un singolo elemento distinto della stringa.
-- ----------------------------------------------------------------------------
FUNCTION split_text (p_text IN CLOB,
p_delimeter IN VARCHAR2 DEFAULT '§')
RETURN t_split_array IS
-- ----------------------------------------------------------------------------
l_array t_split_array := t_split_array();
l_text CLOB := p_text;
l_idx NUMBER;
BEGIN
l_array.delete;
IF l_text IS NULL THEN
RAISE_APPLICATION_ERROR(-20000, 'P_TEXT parameter cannot be NULL');
END IF;
WHILE l_text IS NOT NULL LOOP
l_idx := INSTR(l_text, p_delimeter);
l_array.extend;
IF l_idx > 0 THEN
l_array(l_array.last) := SUBSTR(l_text, 1, l_idx - 1);
l_text := SUBSTR(l_text, l_idx + 1);
ELSE
l_array(l_array.last) := l_text;
l_text := NULL;
END IF;
END LOOP;
RETURN l_array;
END split_text;
-- ----------------------------------------------------------------------------
Questa funzione può essere richiamata all'interno di uno statement pl-sql nel seguente modo:
PROCEDURA PL-SQL
....
str_1 t_split_array;
BEGIN
...
str_1 := split_text (v_resourceid1,v_delimeter) ;
for i in 1..str_1.count
loop
dbms_output.put_line(str_1(i));
end loop;
....
END;
Questo se occorre processare un singolo elemento distinto della stringa.
RDBMS ORACLE - SPLIT TEXT with REGEXP
Di seguito un semplice esempio per effettuare lo split di una string utilizzando una regexp.
Supponiamo di avere la seguente stringa:
'COSENZA,MILANO,ROMA,TORINO,NAPOLI'
quello che vogliamo ottenere è una lista :
COSENZA
MILANO
ROMA
TORINO
NAPOLI
Per ottenere questo basta effettuare la seguente query:
SELECT
regexp_substr('COSENZA,MILANO,ROMA,TORINO,NAPOLI', '[^,]+', 1, level)
FROM
dual
CONNECT BY
regexp_substr('COSENZA,MILANO,ROMA,TORINO,NAPOLI', '[^,]+', 1, level) IS NOT NULL;
Il risultato ottenuto sarà il seguente:
REGEXP_SUBSTR('COSENZA,MILANO,ROM
---------------------------------
COSENZA
MILANO
ROMA
TORINO
NAPOLI
Se lo si vuole usare come input in una IN basta riscrivere la query nel seguente modo:
SELECT * FROM CITTA WHERE NAME IN
(SELECT regexp_substr('COSENZA,MILANO,ROMA,TORINO,NAPOLI', '[^,]+', 1, level)
FROM dual
CONNECT BY regexp_substr('COSENZA,MILANO,ROMA,TORINO,NAPOLI', '[^,]+', 1, level) IS NOT NULL);
Supponiamo di avere la seguente stringa:
'COSENZA,MILANO,ROMA,TORINO,NAPOLI'
quello che vogliamo ottenere è una lista :
COSENZA
MILANO
ROMA
TORINO
NAPOLI
Per ottenere questo basta effettuare la seguente query:
SELECT
regexp_substr('COSENZA,MILANO,ROMA,TORINO,NAPOLI', '[^,]+', 1, level)
FROM
dual
CONNECT BY
regexp_substr('COSENZA,MILANO,ROMA,TORINO,NAPOLI', '[^,]+', 1, level) IS NOT NULL;
Il risultato ottenuto sarà il seguente:
REGEXP_SUBSTR('COSENZA,MILANO,ROM
---------------------------------
COSENZA
MILANO
ROMA
TORINO
NAPOLI
Se lo si vuole usare come input in una IN basta riscrivere la query nel seguente modo:
SELECT * FROM CITTA WHERE NAME IN
(SELECT regexp_substr('COSENZA,MILANO,ROMA,TORINO,NAPOLI', '[^,]+', 1, level)
FROM dual
CONNECT BY regexp_substr('COSENZA,MILANO,ROMA,TORINO,NAPOLI', '[^,]+', 1, level) IS NOT NULL);
lunedì 6 aprile 2020
ORDS - Restituzione di un tracciato record json con array_json
Di seguito un esempio di come creare una procedura pl-sql da richiamare in ORDS che generi un particolare tracciato record json. In questo caso il tracciato record è il seguente:
{
"count": "1",
"operation": [ {
"operation_id": "202003020301301",
...
"end_date": null
}],
"flows_requested": [ {
"rownum": 1,
...
"end_date": null,
"missing_items": [ {
"column_name": "COL_01",
"column_value": "12"
}]
}]
}
Il seguente json è composto da tre pezzi separati:
Per ottenere una strutura di questo tipo occorre creare una procedura pl-sql contenente tre cursori, di seguito l'esempio del pl-sql che genera il tracciato json sopra indicato.
PROCEDURE get (
[parametri di input...]
OUT_OPERATION OUT SYS_REFCURSOR,
OUT_COUNT OUT NUMBER,
OUT_FLOWS_REQUESTED OUT SYS_REFCURSOR
)
AS
[dichiarazioni di variabili...]
BEGIN
------------------------------
--- count
------------------------------
SELECT
COUNT(1) INTO OUT_COUNT
FROM( [tabella o sottoquery su cui effettuare la count...] );
[gestione dello stato nel caso ritorni 0 record...]
------------------------------
--- sys_refcursor
------------------------------
OPEN OUT_OPERATION FOR
SELECT DISTINCT
req.OPERATION_ID operation_id
[...]
, req.odi_end_date
FROM [...] ;
------------------------------
--- sys_refcursor
------------------------------
OPEN OUT_FLOWS_REQUESTED FOR
SELECT rownum,
flow_id,
[...],
end_date,
cursor (select miss.column_name, miss.column_value
from [...]
where [...]) missing_items
FROM [...]
WHERE [...];
END get;
A questo punto occorre creare l'Handler di ORDS che richiama questa procedura pl-sql ed otterremo il tracciato indicato sopra.
{
"count": "1",
"operation": [ {
"operation_id": "202003020301301",
...
"end_date": null
}],
"flows_requested": [ {
"rownum": 1,
...
"end_date": null,
"missing_items": [ {
"column_name": "COL_01",
"column_value": "12"
}]
}]
}
Il seguente json è composto da tre pezzi separati:
- Il primo record rappresenta una count
- Il secondo pezzo rappresenta un array contenente l'estrazione di una serie di informazioni presenti in una determinata tabella.
- Nel terso pezzo abbiamo un cursore innestato con un altro cursore.
Per ottenere una strutura di questo tipo occorre creare una procedura pl-sql contenente tre cursori, di seguito l'esempio del pl-sql che genera il tracciato json sopra indicato.
PROCEDURE get (
[parametri di input...]
OUT_OPERATION OUT SYS_REFCURSOR,
OUT_COUNT OUT NUMBER,
OUT_FLOWS_REQUESTED OUT SYS_REFCURSOR
)
AS
[dichiarazioni di variabili...]
BEGIN
------------------------------
--- count
------------------------------
SELECT
COUNT(1) INTO OUT_COUNT
FROM( [tabella o sottoquery su cui effettuare la count...] );
[gestione dello stato nel caso ritorni 0 record...]
------------------------------
--- sys_refcursor
------------------------------
OPEN OUT_OPERATION FOR
SELECT DISTINCT
req.OPERATION_ID operation_id
[...]
, req.odi_end_date
FROM [...] ;
------------------------------
--- sys_refcursor
------------------------------
OPEN OUT_FLOWS_REQUESTED FOR
SELECT rownum,
flow_id,
[...],
end_date,
cursor (select miss.column_name, miss.column_value
from [...]
where [...]) missing_items
FROM [...]
WHERE [...];
END get;
A questo punto occorre creare l'Handler di ORDS che richiama questa procedura pl-sql ed otterremo il tracciato indicato sopra.
martedì 5 novembre 2019
ODI 12c - Begin/End Mapping Command
Se si vuole utilizzare un pre o post mapping in ODI occorre configurare quanto presente sulle Physical Properties indicando le operazioni che devono essere eseguite.
Di seguito un semplice esempio.
Come primo passo occorre posizionarsi sulla parte bianca del physical e selezionare le proprietà.
Inserire i comandi da effettuare come pre e post mapping in corrispondenza di Begin/End Mapping Command:
Effettuare poi la scelta della tecnologia e della Location su cui deve essere eseguito il comando.
A questo punto avremo:
Come si vede ho inserito dei semplici comandi, il primo di BEGIN verrà eseguito correttamente il secondo di END ho inserito volutamente un errore e quindi in fase di esecuzione a causa dell'END COMMAND il mapping andrà in errore:
Di seguito un semplice esempio.
Come primo passo occorre posizionarsi sulla parte bianca del physical e selezionare le proprietà.
Inserire i comandi da effettuare come pre e post mapping in corrispondenza di Begin/End Mapping Command:
Effettuare poi la scelta della tecnologia e della Location su cui deve essere eseguito il comando.
A questo punto avremo:
Come si vede ho inserito dei semplici comandi, il primo di BEGIN verrà eseguito correttamente il secondo di END ho inserito volutamente un errore e quindi in fase di esecuzione a causa dell'END COMMAND il mapping andrà in errore:
Iscriviti a:
Post (Atom)