Home » SQL & PL/SQL » SQL & PL/SQL » How to use minus, union for CLOB datatype column in Oracle? (Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi)
How to use minus, union for CLOB datatype column in Oracle? [message #646926] |
Thu, 14 January 2016 17:17  |
|
Hi,
I have two tables which has similar columns with same datatypes. There is a CLOB column for holding data more than 4000 varchar.
I need to use minus, union on these tables for executing DMLs. But it is not successful, because of ORA-00932: inconsistent datatypes: expected - got CLOB. I tried using NOT EXISTS but ended in same error. What the alternate options to resolve?
Note : CLOB datatype needs to remained and data is expected to be more than 4000 VARCHAR2.
create table table_test_1 (col_1 varchar2(4000), col_2 clob);
create table table_test_2 (col_1 varchar2(4000), col_2 clob);
insert into table_test_1 values ('1','10');
insert into table_test_1 values ('2','20');
insert into table_test_1 values ('3','30');
insert into table_test_1 values ('4','40');
insert into table_test_2 values ('1','10');
insert into table_test_2 values ('2','20');
commit;
Case 1
---------
select col_2 from table_test_1
minus
select col_2 from table_test_2;
Case 2
---------
select col_1,col_2 from table_test_1 p1 where not exists (
select col_1,col_2 from table_test_2 p2 where p2.col_1 = p1.col_1 and p2.col_2 = p1.col_2);
Case 3
---------
select * from table_test_1
union
select * from table_test_2;
|
|
|
|
|
Re: How to use minus, union for CLOB datatype column in Oracle? [message #646966 is a reply to message #646964] |
Fri, 15 January 2016 11:40   |
Solomon Yakobson
Messages: 3305 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
SQL> select *
2 from table_test_1
3 /
COL_1 COL_2
---------- ----------
1 10
2 20
3 30
4 40
SQL> select *
2 from table_test_2
3 /
COL_1 COL_2
---------- ----------
1 10
2 20
SQL> with t1 as (
2 select table_test_1.*,
3 rownum rn
4 from table_test_1
5 ),
6 t2 as (
7 select rn
8 from t1,
9 table_test_2
10 where dbms_lob.compare(t1.col_2,table_test_2.col_2) = 0
11 ),
12 t3 as (
13 select *
14 from t1
15 where rn not in (select rn from t2)
16 ),
17 t4 as (
18 select col_1,
19 col_2,
20 rownum rn
21 from t3
22 ),
23 t5 as (
24 select t41.rn
25 from t4 t41,
26 t4 t42
27 where dbms_lob.compare(t41.col_2,t42.col_2) = 0
28 and t41.rn != t42.rn
29 )
30 select col_1,
31 col_2
32 from t4
33 where rn not in (select rn from t5)
34 /
COL_1 COL_2
---------- ----------
3 30
4 40
SQL>
SY.
|
|
|
|
|
Re: How to use minus, union for CLOB datatype column in Oracle? [message #646973 is a reply to message #646969] |
Fri, 15 January 2016 15:15   |
 |
Barbara Boehmer
Messages: 9105 Registered: November 2002 Location: California, USA
|
Senior Member |
|
|
I don't know what you have against the WITH clause. It can be done with inline views, as shown below, but it is very hard to read and follow.
SCOTT@orcl> column col_1 format a30
SCOTT@orcl> column col_2 format a30
SCOTT@orcl> select * from table_test_1
2 /
COL_1 COL_2
------------------------------ ------------------------------
1 10
2 20
3 30
4 40
4 rows selected.
SCOTT@orcl> select * from table_test_2
2 /
COL_1 COL_2
------------------------------ ------------------------------
1 10
2 20
2 rows selected.
SCOTT@orcl> select col_1, col_2
2 from (select col_1, col_2, rownum rn
3 from (select *
4 from (select table_test_1.*, rownum rn
5 from table_test_1) t1
6 where rn not in
7 (select rn
8 from (select rn
9 from (select table_test_1.*, rownum rn
10 from table_test_1) t1,
11 table_test_2
12 where dbms_lob.compare(t1.col_2,table_test_2.col_2) = 0))))
13 where rn not in
14 (select rn
15 from (select t41.rn
16 from (select col_1, col_2, rownum rn
17 from (select *
18 from (select table_test_1.*, rownum rn
19 from table_test_1) t1
20 where rn not in
21 (select rn
22 from (select rn
23 from (select table_test_1.*, rownum rn
24 from table_test_1) t1,
25 table_test_2
26 where dbms_lob.compare(t1.col_2,table_test_2.col_2) = 0)))) t41,
27 (select col_1, col_2, rownum rn
28 from (select *
29 from (select table_test_1.*, rownum rn
30 from table_test_1) t1
31 where rn not in
32 (select rn
33 from (select rn
34 from (select table_test_1.*, rownum rn
35 from table_test_1) t1,
36 table_test_2
37 where dbms_lob.compare(t1.col_2,table_test_2.col_2) = 0)))) t42
38 where dbms_lob.compare(t41.col_2,t42.col_2) = 0
39 and t41.rn != t42.rn))
40 /
COL_1 COL_2
------------------------------ ------------------------------
3 30
4 40
2 rows selected.
|
|
|
Re: How to use minus, union for CLOB datatype column in Oracle? [message #646974 is a reply to message #646969] |
Fri, 15 January 2016 15:46   |
Solomon Yakobson
Messages: 3305 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
Another possibility is create object type with order method. But we still need WITH clause or in-line view:
CREATE OR REPLACE
TYPE clob_obj IS OBJECT(
c CLOB,
ORDER MEMBER FUNCTION equals(
p_c clob_obj
)
RETURN NUMBER
)
/
CREATE OR REPLACE
TYPE BODY clob_obj
IS
ORDER MEMBER FUNCTION equals(
p_c clob_obj
)
RETURN NUMBER
IS
BEGIN
RETURN CASE
WHEN SELF.c IS NULL AND p_c.c IS NULL THEN 0
ELSE NVL(dbms_lob.compare(SELF.c,p_c.c),1)
END;
END;
END;
/
with t as (
select col_1,
clob_obj(col_2) col_2
from table_test_1
minus
select col_1,
clob_obj(col_2)
from table_test_2
)
select col_1,
t.col_2.c col_2
from t t
/
COL_1 COL_2
---------- ----------
3 30
4 40
select col_1,
t.col_2.c col_2
from (
select col_1,
clob_obj(col_2) col_2
from table_test_1
minus
select col_1,
clob_obj(col_2)
from table_test_2
) t
/
COL_1 COL_2
---------- ----------
3 30
4 40
SQL>
SY.
|
|
|
Re: How to use minus, union for CLOB datatype column in Oracle? [message #646975 is a reply to message #646974] |
Fri, 15 January 2016 17:17   |
 |
Barbara Boehmer
Messages: 9105 Registered: November 2002 Location: California, USA
|
Senior Member |
|
|
I just discovered that the following works in 12c. I don't have other versions to test on.
SCOTT@orcl> select banner from v$version
2 /
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
CORE 12.1.0.2.0 Production
TNS for 64-bit Windows: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production
5 rows selected.
SCOTT@orcl> column col_1 format a30
SCOTT@orcl> column col_2 format a30
SCOTT@orcl> select * from table_test_1
2 /
COL_1 COL_2
------------------------------ ------------------------------
1 10
2 20
3 30
4 40
4 rows selected.
SCOTT@orcl> select * from table_test_2
2 /
COL_1 COL_2
------------------------------ ------------------------------
1 10
2 20
2 rows selected.
SCOTT@orcl> select table_test_1.*
2 from table_test_1
3 where not exists
4 (select *
5 from table_test_2
6 where table_test_2.col_1 = table_test_1.col_1
7 and dbms_lob.compare (table_test_1.col_2, table_test_2.col_2) = 0)
8 /
COL_1 COL_2
------------------------------ ------------------------------
3 30
4 40
2 rows selected.
[Updated on: Fri, 15 January 2016 17:19] Report message to a moderator
|
|
|
|
Re: How to use minus, union for CLOB datatype column in Oracle? [message #646977 is a reply to message #646976] |
Fri, 15 January 2016 20:15   |
Solomon Yakobson
Messages: 3305 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
It is not equivalent to MINUS. Look what happens when table_test_1 has duplicates:
SQL> insert
2 into table_test_1
3 select *
4 from table_test_1
5 /
4 rows created.
SQL> select *
2 from table_test_1
3 /
COL_1 COL_2
---------- ----------
1 10
2 20
3 30
4 40
1 10
2 20
3 30
4 40
8 rows selected.
SQL> select table_test_1.*
2 from table_test_1
3 where not exists
4 (select *
5 from table_test_2
6 where table_test_2.col_1 = table_test_1.col_1
7 and dbms_lob.compare (table_test_1.col_2, table_test_2.col_2) = 0)
8 /
COL_1 COL_2
---------- ----------
3 30
4 40
3 30
4 40
SQL> with t as (
2 select col_1,
3 clob_obj(col_2) col_2
4 from table_test_1
5 minus
6 select col_1,
7 clob_obj(col_2)
8 from table_test_2
9 )
10 select col_1,
11 t.col_2.c col_2
12 from t t
13 /
COL_1 COL_2
---------- ----------
3 30
4 40
SQL>
Also, MINUS (same as other SET operators) considers two NULLs equal, so query would have to use OR (table_test_2.col_X IS NULL AND table_test_1.col_X is NULL) for each column.
SY.
|
|
|
|
|
Goto Forum:
Current Time: Wed May 28 10:15:48 CDT 2025
|