Verifica se un elemento di raccolta esiste in Oracle
-
20-09-2019 - |
Domanda
creo un tipo semplice:
create or replace TYPE SIMPLE_TYPE AS OBJECT (ID NUMBER(38), NAME VARCHAR2(20));
Test Semplice:
DECLARE
TYPE ObjectList IS TABLE OF SIMPLE_TYPE;
tmp SIMPLE_TYPE := SIMPLE_TYPE(1, 'a');
o ObjectList := new ObjectList(SIMPLE_TYPE(2, 'a'), SIMPLE_TYPE(3, 'a'));
BEGIN
IF tmp.EXISTS(tmp) THEN
dbms_output.put_line('OK, exists.');
END IF;
END;
ottengo un'eccezione: PLS-00302: componente 'esiste' deve essere dichiarato
Ma questo esempio di lavoro:
DECLARE
TYPE NumList IS TABLE OF INTEGER;
n NumList := NumList(1,3,5,7);
BEGIN
n.DELETE(2);
IF n.EXISTS(1) THEN
dbms_output.put_line('OK, element #1 exists.');
END IF;
IF n.EXISTS(3) = FALSE THEN
dbms_output.put_line('OK, element #2 has been deleted.');
END IF;
IF n.EXISTS(99) = FALSE THEN
dbms_output.put_line('OK, element #99 does not exist at all.');
END IF;
END;
E 'possibile implementare il metodo esiste in tipo SIMPLE_TYPE?
Soluzione
tmp SIMPLE_TYPEE := SIMPLE_TYPE(1, 'a');
…
IF tmp.EXISTS(tmp) THEN
Si dichiara tmp
come SIMPLE_TYPE
, non ObjectList
.
SIMPLE_TYPE
è di tipo scalare, non un insieme.
Probabilmente si voleva controllare o.EXISTS
invece (che è un ObjectList
)?
Aggiornamento:
EXISTS
quando applicata a un insieme richiede un indice intero come argomento e controlla se l'elemento con questo indice esiste (non il suo valore).
Per verificare che esista SIMPLE_TYPE(1, 'a')
nella tabella, si dovrebbe quindi la seguente:
Crea ObjectList
in un dizionario:
CREATE TYPE ObjectList IS TABLE OF SIMPLE_TYPE;
Emettere la query SELECT
:
DECLARE
tmp SIMPLE_TYPE := SIMPLE_TYPE(1, 'a');
o ObjectList := new ObjectList(SIMPLE_TYPE(2, 'a'), SIMPLE_TYPE(3, 'a'));
myid INT;
BEGIN
SELECT 1
INTO myid
FROM TABLE(o) q
WHERE SIMPLE_TYPE(q.id, q.name) = tmp
AND rownum = 1;
IF (myid = 1) THEN
dbms_output.put_line('OK, exists.');
END IF;
END;
Altri suggerimenti
Come la stati di documentazione , EXISTS(
) test per l'esistenza di una voce numerata in una collezione. Cioè, array.exists(3)
afferma che il terzo elemento di array
è popolato.
Quello che si sta cercando di fare nel tuo primo esempio è verificare se la tmp
istanza corrisponde a un elemento in ObjectList
. Da 10g in poi siamo in grado di farlo usando la sintassi MEMBER OF
. Purtroppo, al fine di fare quel lavoro che dobbiamo dichiarare un metodo MAP
, che è piuttosto goffo e otterrebbe piuttosto fastidioso se l'oggetto ha un sacco di attributi.
SQL> create or replace type simple_type as object
2 ( id number
3 , name varchar2(30)
4 , map member function compare return varchar2);
5 /
Type created.
SQL>
SQL> create or replace type body simple_type as
2 map member function compare return varchar2
3 is
4 return_value integer;
5 begin
6 return to_char(id, '0000000')||name;
7 end compare;
8 end;
9 /
Type body created.
SQL>
L'esecuzione l'esempio ...
SQL> set serveroutput on size unlimited
SQL>
SQL> declare
2 type objectlist is table of simple_type;
3 tmp simple_type := simple_type(1, 'a');
4 o objectlist := new objectlist(simple_type(2, 'a'), simple_type(3, 'a'));
5 begin
6 if tmp MEMBER OF o then
7 dbms_output.put_line('ok, exists.');
8 else
9 dbms_output.put_line('search me');
10 end if;
11 end;
12 /
search me
PL/SQL procedure successfully completed.
SQL>