比较两种Oracle类型的每列中的值
我今天一直在玩,我想用它把一些现有的功能放到一个测试工具中 我有很多这种规格的函数比较两种Oracle类型的每列中的值,oracle,plsql,Oracle,Plsql,我今天一直在玩,我想用它把一些现有的功能放到一个测试工具中 我有很多这种规格的函数 FUNCTION DO_SOME_STUFF (pOldSchedule IN SCHEDULE_OBJ, pNewSchedule OUT SCHEDULE_OBJ, pLoggerContext IN OUT LOGGER_CONTE
FUNCTION DO_SOME_STUFF (pOldSchedule IN SCHEDULE_OBJ,
pNewSchedule OUT SCHEDULE_OBJ,
pLoggerContext IN OUT LOGGER_CONTEXT_OBJ)
RETURN NUMBER;
它接受pOldSchedule,对其执行一些操作,然后返回pNewSchedule。logger_上下文只做日志记录
作为测试的一部分,我希望能够比较类型的每个列中的值,而不必编写单独的IF语句
它需要返回布尔值来表示pOldSchedule和pNewSchedule是否匹配
有什么想法吗?简单的相等性测试可用于嵌套表:
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>
但是,完全打开对象的情况并非如此:
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>
我们需要显式定义一个成员函数来执行比较。这是同一个对象,有一个映射函数。示例实现生成了一个散列字符串,如果我们希望存储该值以供以后比较,这非常有用,但它可以只返回连接的字符串(特别是在默认情况下不授予在DBMS_CRYPTO上执行)。NVL()函数对于避免(null,value)和(value,null)被计算为相等是必需的。使用魔法值总是有风险的,所以我们需要仔细选择它们
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>
现在我们有了比较对象实例的基础:
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>
您可能想知道为什么Oracle在默认情况下不这样做。嗯,类型实现只允许一种比较方法(如果我们有一个MAP函数,我们就不能有ORDER函数),所以我们需要有能力选择我们自己的相等定义。例如,一个名为rectangle
的类型可能有一个名为area()
的映射函数,该函数返回self.width*self.length