2010-04-09 5 views
3

J'ai joué avec le pluto-test-framework aujourd'hui, et j'aimerais intégrer certaines fonctions existantes dans un faisceau de test.Comparer les valeurs dans chaque colonne de deux types Oracle

J'ai beaucoup de fonctions avec ce type de spécification.

FUNCTION DO_SOME_STUFF (pOldSchedule  IN  SCHEDULE_OBJ, 
          pNewSchedule   OUT SCHEDULE_OBJ, 
          pLoggerContext  IN OUT LOGGER_CONTEXT_OBJ) 
    RETURN NUMBER; 

Il prend pOldSchedule, y ajoute des éléments, puis retourne pNewSchedule. Le logger_context ne fait que se connecter.

Dans le cadre d'un test, j'aimerais pouvoir comparer les valeurs dans chacune des colonnes du type, sans avoir à écrire des instructions IF individuelles.

Il faudra retourner booléen pour indiquer si oui ou non pOldSchedule et pNewSchedule correspondent.

Des idées?

Répondre

6

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.

Questions connexes