tests d'égalité Straightforward travaillent avec des tables imbriquées:
SQL> declare
2 type nt is table of number;
3 nt1 nt;
4 nt2 nt;
5 nt3 nt;
6 begin
7 nt1 := nt(1,2,3);
8 nt2 := nt(1,2,3);
9 if nt1 = nt2 then
10 dbms_output.put_line('NT2 is the same nested table as NT1');
11 else
12 dbms_output.put_line('NT2 is a different nested table from NT1');
13 end if;
14 nt2 := nt(1,2,3,4);
15 if nt1 = nt3 then
16 dbms_output.put_line('NT3 is the same nested table as NT1');
17 else
18 dbms_output.put_line('E3 is a different nested table from NT1');
19 end if;
20 end;
21/
NT2 is the same nested table as NT1
E3 is a different nested table from NT1
PL/SQL procedure successfully completed.
SQL>
Cependant, le même est pas le cas de plein sur les objets:
SQL> create or replace type new_emp as object (
2 ename varchar2(10)
3 , sal number
4 , deptno number
5 , job varchar2(10))
6/
Type created.
SQL> declare
2 e1 new_emp;
3 e2 new_emp;
4 begin
5 e1 := new_emp('KESTELYN', 3700, 30, 'MARKETING');
6 e2 := new_emp('KESTELYN', 3700, 30, 'MARKETING');
7 if e1 = e2 then
8 dbms_output.put_line('E2 is the same as E1');
9 else
10 dbms_output.put_line('E2 is different from E1');
11 end if;
12 end;
13/
if e1 = e2 then
*
ERROR at line 7:
ORA-06550: line 7, column 11:
PLS-00526: A MAP or ORDER function is required for comparing objects in PL/SQL.
SQL>
Nous devons définir explicitement une fonction de membre pour l'exécution des comparaisons. Donc, voici le même objet avec une fonction MAP. L'implémentation de l'exemple génère une chaîne de hachage, ce qui est utile si nous voulons stocker la valeur pour une comparaison ultérieure, mais cela pourrait juste renvoyer la chaîne concaténée (d'autant plus que EXECUTE sur DBMS_CRYPTO n'est pas accordé par défaut). Les fonctions NVL() sont nécessaires pour éviter (null, value) et (value, null) étant évaluées comme égales. Il y a toujours un risque lors de l'utilisation de valeurs magiques, nous devons donc les choisir avec soin.
SQL> create or replace type new_emp as object (
2 ename varchar2(10)
3 , sal number
4 , deptno number
5 , job varchar2(10)
6 , map member function equals return raw)
7/
Type created.
SQL> create or replace type body new_emp as
2 map member function equals return raw
3 is
4 begin
5 return dbms_crypto.hash(
6 utl_raw.cast_to_raw(nvl(self.ename,'***')||
7 nvl(self.sal,-99)||
8 nvl(self.deptno,-99)||
9 nvl(self.job,'***')
10 )
11 , 1);
12 end equals;
13 end;
14/
Type body created.
SQL>
Maintenant, nous avons une base pour comparer les cas de nos objets:
SQL> declare
2 e1 new_emp;
3 e2 new_emp;
4 begin
5 e1 := new_emp('KESTELYN', 3700, 30, 'MARKETING');
6 e2 := new_emp('KESTELYN', 3700, 30, 'MARKETING');
7 if e1 = e2 then
8 dbms_output.put_line('E2 is the same as E1');
9 else
10 dbms_output.put_line('E2 is different from E1');
11 end if;
12 end;
13/
E2 is the same as E1
PL/SQL procedure successfully completed.
SQL>
Vous pourriez vous demander pourquoi Oracle ne le fait pas par défaut. Eh bien, l'implémentation de TYPE ne permet qu'une seule méthode de comparaison (si nous avons une fonction MAP, nous ne pouvons pas avoir de fonction ORDER), nous devons donc avoir la possibilité de choisir notre propre définition de l'égalité. Par exemple, un type appelé rectangle
peut avoir une fonction MAP appelée area()
qui renvoie self.width * self.length
.