Skip to Main Content
  • Questions
  • HOW TO DEFINE THE LENGTH OF A COLUMN OF A VIEW?

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question.

Asked: November 23, 2005 - 8:49 pm UTC

Last updated: November 24, 2005 - 5:17 pm UTC

Version: 10.1.0.2

Viewed 1000+ times

You Asked

Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
With the Partitioning, OLAP and Data Mining options

DROP TABLE R;

create table r (
Rtype varchar2(20),
name varchar2(20),
child varchar2(20)
);

--AREA 1 AND 2,EACH HAVE TWO PROVINCES
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('AREA','SOUTH','PROVINCE1');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('AREA','SOUTH','PROVINCE2');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('AREA','NORTH','PROVINCE3');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('AREA','NORTH','PROVINCE4');
--PROVINCE 1-4,EACH HAVE TWO COMPANIES
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('PROVINCE','PROVINCE1','COMPANY1');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('PROVINCE','PROVINCE1','COMPANY2');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('PROVINCE','PROVINCE2','COMPANY3');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('PROVINCE','PROVINCE2','COMPANY4');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('PROVINCE','PROVINCE3','COMPANY5');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('PROVINCE','PROVINCE3','COMPANY6');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('PROVINCE','PROVINCE4','COMPANY7');
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('PROVINCE','PROVINCE4','COMPANY8');
8 COMPANIES IS THE LEAF OF THE TREE
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('COMPANY','COMPANY1',NULL);
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('COMPANY','COMPANY2',NULL);
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('COMPANY','COMPANY3',NULL);
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('COMPANY','COMPANY4',NULL);
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('COMPANY','COMPANY5',NULL);
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('COMPANY','COMPANY6',NULL);
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('COMPANY','COMPANY7',NULL);
INSERT INTO R (RTYPE,NAME, CHILD) VALUES ('COMPANY','COMPANY8',NULL);

COMMIT;

SQL> column cname format a10
SQL> column rtype format a10
SQL> column prov format a10
SQL> column area format a10
SQL> column child format a10

SQL> SELECT * FROM R;

RTYPE NAME CHILD
---------- ---------- ----------
AREA SOUTH PROVINCE1
AREA SOUTH PROVINCE2
AREA NORTH PROVINCE3
AREA NORTH PROVINCE4
PROVINCE PROVINCE1 COMPANY1
PROVINCE PROVINCE1 COMPANY2
PROVINCE PROVINCE2 COMPANY3
PROVINCE PROVINCE2 COMPANY4
PROVINCE PROVINCE3 COMPANY5
PROVINCE PROVINCE3 COMPANY6
PROVINCE PROVINCE4 COMPANY7

RTYPE NAME CHILD
---------- ---------- ----------
PROVINCE PROVINCE4 COMPANY8
COMPANY COMPANY1
COMPANY COMPANY2
COMPANY COMPANY3
COMPANY COMPANY4
COMPANY COMPANY5
COMPANY COMPANY6
COMPANY COMPANY7
COMPANY COMPANY8

TO CHANGE R TO ANOTHER FORMAT ,I CREATE A VIEW CV AS

CREATE OR REPLACE VIEW CV AS
select A.pth CNAME,
max(decode(A.rtype,'PROVINCE',A.NAME,null)) PROV ,
max(decode(A.rtype,'AREA',A.NAME,null)) area from
(select R.*,
nvl(substr(SYS_CONNECT_BY_PATH(R.NAME, '.'),2,instr(SYS_CONNECT_BY_PATH(R.NAME, '.'),'.',1,2)-2),R.NAME) Pth
from r CONNECT BY prior R.NAME= R.CHILD start with R.CHILD is null) A group by A.pth ;

SQL> SELECT * FROM CV;

CNAME PROV AREA
---------- ---------- ----------
COMPANY1 PROVINCE1 SOUTH
COMPANY2 PROVINCE1 SOUTH
COMPANY3 PROVINCE2 SOUTH
COMPANY4 PROVINCE2 SOUTH
COMPANY5 PROVINCE3 NORTH
COMPANY6 PROVINCE3 NORTH
COMPANY7 PROVINCE4 NORTH
COMPANY8 PROVINCE4 NORTH

THE RESULTS ARE JUST WHAT I NEED.BUT ,

DESC CV
CNAME VARCHAR2(4000)
PROV VARCHAR2(20)
AREA VARCHAR2(20)

the length of cname make me upset,can i have a way to change it to the nomal length?(It should be varchar2(20))



and Tom said...

you can use substr or CAST in this case.


substr( a.pth, 1, 20 ) cname

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

thanks!

A reader, November 24, 2005 - 11:23 am UTC


Which would be preferable?

djb, November 24, 2005 - 1:46 pm UTC

We use

... CAST (whatever as VARCHAR2(30)) aliasname ...

It's a little more verbose, but it's clearer to me what we're trying to do, rather than using SUBSTR().

Is one any better performant (or otherwise better) than the other?


Tom Kyte
November 24, 2005 - 5:17 pm UTC

never benchmarked it -- when you did what did you see :)

cast is better :-)

Quadro, November 25, 2005 - 1:37 am UTC

select cast(rpad('*', level, '*') as VARCHAR2(30)) casted
from dual
connect by level<=100000

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 6668 0.22 0.25 0 0 0 100000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6670 0.23 0.25 0 0 0 100000

select substr(rpad('*', level, '*'), 1, 30) substred
from dual
connect by level<=100000

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 6668 0.33 0.33 0 0 0 100000
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6670 0.34 0.33 0 0 0 100000


More to Explore

VLDB

If you are new to partitioning, check out Connor McDonald's introduction series here.

VLDB

Documentation set on VLDB and Partitioning.