oracle 引用 自定义列名,Oracle 自定义类型

一:Oracle中的类型有很多种,主要可以分为以下几类:

1、字符串类型。如:char、nchar、varchar2、nvarchar2。

2、数值类型。如:int、number(p,s)、integer、smallint。

3、日期类型。如:date、interval、timestamp。

4、PL/SQL类型。如:pls_integer、binary_integer、binary_double(10g)、

binary_float(10g)、boolean。plsql类型是不能在sql环境中使用的,比如建表时。

5、自定义类型:type / create type

二:type / create type 区别联系

相同:

可用用关键字create type 或者直接用type定义自定义类型,

区别:

create type 变量 as table of 类型

--

create type 变量 as object(

字段1 类型1,

字段2 类型2

);

--------------------------

与 type 变量 is table of 类型

--

type 变量 is record(

字段1 类型1,

字段2 类型2

);

区别是 用 create 后面用 as , 若直接用 type 后面用 is

create 是创 object , 而 type 是创 record .

另 type用在语句块中,而create 是的独立的.

​一般定义object的语法:

create type 自定义表类型A as table of 自定义Object类型A

create type 自定义Object类型A as object(

字段1 类型1,

字段2 类型2

);​

type 自定义表类型B is table of 类型

type 自定义Object类型B is record(

字段1 类型1,

字段2 类型2

);

自定义类型一般分为两中,object类型和table类型.object类似于一个recored,可以表示一个表的一行数据,

object的字段就相当与表的字段.

自定义的table类型需要用的已经定义好的object类型.

三、创建和使用object:​

1、普通类型

create or replace type typ_calendar as object(

varchar2(8),

varchar2(8),

星期日

varchar2(8),

星期一

varchar2(8),

星期二 varchar2(8),

星期三

varchar2(8),

星期四

varchar2(8),

星期五

varchar2(8),

星期六

varchar2(8),

本月最后一日

varchar2(2));

​这种类型可以在表结构定义的时候使用:

create table tcalendar of typ_calendar;

插入数据测试:

insert into tcalendar

select

typ_calendar('2010','05','1','2','3','4','5','6','7','31') from

dual

注意:插入的数据需要用typ_calendar进行转换。​

2、带成员函数的类型体(type body)

这种类型包含了对类型中数据的内部处理,调用该类型时,可将处理后的数据返回给调用方。

对上面的例子进行扩展。要求给当天加上特殊标识(【】)来突出显示。

首先,在typ_calendar中增加一个成员函数声明:

create or replace type typ_calendar as object(

varchar2(8),

varchar2(8),

星期日

varchar2(8),

星期一

varchar2(8),

星期二

varchar2(8),

星期三

varchar2(8),

星期四

varchar2(8),

星期五

varchar2(8),

星期六

varchar2(8),

本月最后一日

varchar2(2),

member function format(

curday

date

:= sysdate,

fmtlen pls_integer := 8

)return

typ_calendar

)

然后,创建一个type body,在type body中实现该成员函数:

create or replace type body typ_calendar as

member

function format(

curday

date

:= sysdate,

fmtlen pls_integer := 8

) return

typ_calendar as

v_return   typ_calendar :=

typ_calendar('','','','','','','','','','');

v_dd

varchar2(2)  := to_char(curday, 'dd');

function

fmt(

fmtstr varchar2

)return varchar2 as

begin

return lpad(fmtstr, fmtlen, ' ');

end fmt;

begin

v_return.年 := 年;

v_return.月 := 月;

v_return.星期日 := fmt(星期日);

v_return.星期一 := fmt(星期一);

v_return.星期二 := fmt(星期二);

v_return.星期三 := fmt(星期三);

v_return.星期四 := fmt(星期四);

v_return.星期五 := fmt(星期五);

v_return.星期六 := fmt(星期六);

v_return.本月最后一日 := 本月最后一日;

if (年 || lpad(月, 2, '0') = to_char(curday, 'yyyymm')) then

case v_dd

when 星期日 then

v_return.星期日 := fmt('【' || 星期日 || '】');

when 星期一 then

v_return.星期一 := fmt('【' || 星期一 || '】');

when 星期二 then

v_return.星期二 := fmt('【' || 星期二 || '】');

when 星期三 then

v_return.星期三 := fmt('【' || 星期三 || '】');

when 星期四 then

v_return.星期四 := fmt('【' || 星期四 || '】');

when 星期五 then

v_return.星期五 := fmt('【' || 星期五 || '】');

when 星期六 then

v_return.星期六 := fmt('【' || 星期六 || '】');

else null;

end case;

end if;

return v_return;

end

format;

end;

​插入测试数据:

insert into

tcalendar

select

typ_calendar('2010','05','1','2','3','4','5','6','7','31') from

dual

insert into tcalendar

select

typ_calendar('2010','05','1','2','3','4','5','6','7','31').format()

from dual

insert into tcalendar

select

typ_calendar('2010','05','11','12','13','14','15','16','17','31').format()

from dual

在这里type 中的成员函数(member function)和静态函数(static function)的区别:

成员函数有隐含参数self,即自身类型,可以在执行的时候引用当前的数据并对数据进行操作。它的调用可以如下:object_expr.method()

静态函数没有该隐含参数。它的调用如下:type_name.method();

创建一个带静态函数声明的类型头​

create or replace type typ_col as object(

col_name varchar2(30),

tab_name varchar2(30),

static function to_upper return typ_col

)​

select typ_col.to_lower(x).tab_name,

typ_col.to_lower(x).col_name from tcol​

select typ_col(column_name, table_name).to_upper().tab_name,

typ_col(column_name, table_name).to_upper().col_name

from

user_tab_columns t

where

rownum <= 10;

静态函数主要是用于处理并返回外部数据的,而成员函数是用于处理并返回内部数据的。

create or replace function show_calendar(

v_yermonth varchar2  := to_char(sysdate,

'yyyymm'))

return tbl_calendar as

v_cal

tbl_calendar;

v_seg

pls_integer := 6;

v_len

pls_integer := 8;

v_yer

varchar2(4) := substr(v_yermonth, 1, 4);

v_mon

varchar2(2) := lpad(substr(v_yermonth, 5, 2), 2, '0');

v_ini

date := to_date(v_yermonth || '01', 'yyyymmdd');

begin

select

typ_calendar(v_yer, v_mon,

case when rn >= wkn - 1 and rn - wkn + 2

<= mxdays

then  rn - wkn + 2 end,

case when rn >= wkn - 2 and rn - wkn + 3

<= mxdays

then  rn - wkn + 3 end,

case when rn >= wkn - 3 and rn - wkn + 4

<= mxdays

then  rn - wkn + 4 end,

case when rn >= wkn - 4 and rn - wkn + 5

<= mxdays

then  rn - wkn + 5 end,

case when rn >= wkn - 5 and rn - wkn + 6

<= mxdays

then  rn - wkn + 6 end,

case when rn >= wkn - 6 and rn - wkn + 7

<= mxdays

then  rn - wkn + 7 end,

case when rn >= wkn - 7 and rn - wkn + 8

<= mxdays

then  rn - wkn + v_len end,

mxdays).format()

bulk collect into v_cal

from (select (rownum - 1)*7 rn,

to_number(to_char(trunc(v_ini, 'mm'), 'd')) wkn,

to_number(to_char(last_day(v_ini), 'dd')) mxdays

from dual

connect by rownum <= v_seg) b

where rn - wkn + 2 <= mxdays; --过滤空行

return

v_cal;

end show_calendar;

​获得当前月的日历:​

select * from table(show_calendar);​

获取指定月份的日历:

select * from

table(show_calendar('201001'));

显示多个月的日历:

select b.*

from (select

to_char(add_months(date'1998-01-01', rownum-1), 'yyyymm') c

from dual connect by rownum <=

10)

a,  table(show_calendar(to_char(a.c)))

b

​自定义type的一个限制是不能使用rowid类型​

特殊使用:自定义聚集函数。​

with tmp as (

select '1' c from dual

union all

select '2' c from dual

union all

select '3' c from dual

union all

select '4' c from dual)

select * from tmp

1,2,3,4要合并为1->2->3->4,该如何实现?

一个办法是用层级查询来实现(用sys_connect_by_path即可)。

另外,10g下,还可以用wm_sys.wm_concat函数来实现。

还有就是自定义聚集函数了。自定义聚集函数首先要定义一个类型,在类型中调用了Oracle内部实现的几个接口函数:

​CREATE OR REPLACE TYPE "TYP_STRCAT" as

object

(

strsum

varchar2(4000),

strcnt

number,

strdelimit varchar2(10),

static

function ODCIAggregateInitialize(

actx in out typ_strcat)

return

number,

member

function ODCIAggregateIterate(

self in out typ_strcat,

val  in varchar2)

return

number,

member

function ODCIAggregateTerminate(

self

in typ_strcat,

returnvalue out varchar2,

flags

in number)

return

number,

member

function ODCIAggregateMerge(

self in out typ_strcat,

ctx2 typ_strcat)

return

number)

CREATE OR REPLACE TYPE BODY "TYP_STRCAT" as

static

function ODCIAggregateInitialize(actx in out typ_strcat)

return number as

begin

actx := typ_strcat(null, 1, ',');

return ODCICONST.Success;

end;

member

function ODCIAggregateIterate(self in out

typ_strcat,

val  in varchar2) return number as

begin

self.strsum := self.strsum || strdelimit || val;

self.strcnt := self.strcnt + 1;

return ODCICONST.Success;

end;

member

function

ODCIAggregateTerminate(self

in typ_strcat,

returnvalue out varchar2,

flags

in number) return number as

begin

returnvalue := ltrim(self.strsum, strdelimit);

return Odciconst.Success;

end;

member

function ODCIAggregateMerge(self in out typ_strcat,

ctx2 in typ_strcat) return number as

begin

self.strsum := ctx2.strsum || self.strsum;

return Odciconst.Success;

end;

end;

然后创建函数:

CREATE OR REPLACE FUNCTION "SSUM" (p_str varchar2)return

varchar2​

aggregate using typ_strcat;

然后,就可以使用字符串相加的功能了:

with tmp as (

select

'1' c from dual union all

select

'2' c from dual union all

select

'3' c from dual union all

select '4' c from dual)

select replace(ssum(c),

',', '->') from tmp

REPLACE(SSUM(C),',','->')

3、表类型

这种类型类似于一个数组类型,可以申明一维或多维。

比如说,创建一个元素长度为4000的字符串数组,则有:

create or replace type tbl_varchar2 as table of

varchar2(4000)

然后可以如下使用该类型:

select * from

table(tbl_varchar2('1','1','3','4','5','6'));

如果要获取多字段的,

select *

from table(tbl_calendar(

typ_calendar('2008','2','3','4','5','6','7','8','9','28'),

typ_calendar('2009','12','13','4','5','6','7','8','9','31'),

typ_calendar('2010','12','13','4','5','6','7','8','9','31')));

以上使用的类型都基于schema级别,如果是定义在包、函数、过程等这些结构里是不能给table函数使用的。

这种类型可以使用在管道函数中(pipelined

function)。也可以存放中间处理的数据,类似于临时表的作用,但是是存放在内存中的。

四:type record用法概述

type 自定义Object类型B is record(

字段1 类型1,

字段2 类型2

);

3.1:什么是记录(Record)?

由单行多列的标量构成的复合结构。可以看做是一种用户自定义数据类型。组成类似于多维数组。

​将一个或多个标量封装成一个对象进行操作。是一种临时复合对象类型。

记录可以直接赋值。RECORD1 :=RECORD2;

记录不可以整体比较.​

记录不可以整体判断为空。

3.2:%ROWTYPE和记录(Record)?​

请区别%ROWTYPE和记录(Record)类型。%ROWTYPE可以说是Record的升级简化版。

区别在与前者结构为表结构,后者为自定义结构。二者在使用上没有很大区别。前者方便,后者灵活。在实际中根据情况来具体决定使用。​

Record + PL/SQL表可以进行数据的多行多列存储。

3.3:如何创建和使用记录?

①创建记录类型

语法:

TYPE  记录名

IS RECORD

(

filed1 type1

[NOT NULL]

[:=eXPr1],

....... ,

filedN typen [NOT

NULL] [:=exprn]

)

​其中,filed1是标量的名字。

​②声明记录类型变量:

记录类型变量名 记录类型

③填充记录。

​④访问记录成员

记录类型变量名.filed1    .........

记录类型变量名.filedN

注意:

表字段类型修改后,还需要修改记录字段类型,有时候可能会忘记,从而出现错误。

对于记录内每个字段(filed1.。。。),可以指定也可以使用%TYPE和%ROWTYPE动态指定记录字段类型。

好处是表字段发生变化,记录字段自动改变。但是,由于每次执行前,遇到%TYPR或%ROWTYPE,数据库系统都会去查看对应表字段类型,会造成一定的数据库开销,如果系统中大量使用记录类型,则对性能会有一定影响。另外如果删除了某一字段,而自定义记录中使用了该字段,也会有可能忘记删除该字段。对数据库负荷偏低的系统,性能问题一般可以不重点关注,但是对于高负荷数据库服务器,各个环节都要考虑性能问题,每处节省一点出来,性能整体就有很大提高。

TYPE  记录名

IS RECORD

(

filed1 table.Filed%Type

[NOT NULL] [:=eXPr1]

,

filed2 table.Filed%Type

[NOT NULL] [:=eXPr1]

,

....... ,

filedn

table.Filed%Type [NOT

NULL] [:=exprn]

);

例子:记录可以整体赋值

Declare

Type EmpType is Record(

EMPNO number(4),

ENAME  varchar2(10),

JOB varchar2(15),

SAL number(7,2),

DEPTNO number(2)

);

EmpRec1  EmpType;

EmpRec2  EmpType;

Begin

EmpRec1.Empno:=7369;

EmpRec1.Ename:='SMITH';

EmpRec1.Job:='CLERK';

EmpRec1.Sal:=800;

EmpRec1.Deptno:=10;

EmpRec2

:= EmpRec1;

DBMS_output.put_line(EmpRec2.empno);

End;

例子:记录不可以整体比较,只可以比较记录字段

Declare

Type EmpType is Record(

EMPNO number(4),

ENAME  varchar2(10),

JOB varchar2(15),

SAL number(7,2),

DEPTNO number(2)

);

EmpRec1  EmpType;

EmpRec2  EmpType;

Begin

EmpRec1.Empno:=7369;

EmpRec1.Ename:='SMITH';

EmpRec1.Job:='CLERK';

EmpRec1.Sal:=800;

EmpRec1.Deptno:=10;

if

EmpRec1.sal < EmpRec2.sal

then

DBMS_output.put_line('Xiao Xiao

Xiao');

end if;

End;

例子:记录不可以整体判断为空,只可以判断记录字段。

Declare

Type EmpType is Record(

EMPNO number(4),

ENAME  varchar2(10),

JOB varchar2(15),

SAL number(7,2),

DEPTNO number(2)

);

EmpRec  EmpType;

Begin

if

EmpRec.ename is null

then

DBMS_output.put_line('Kong Kong

Kong');

end if;

End;

例子:使用%TYPE和%ROWTYPE动态指定记录字段。

DECLARE

Type MyRecType Is

Record

(

RENO

EMPA.EMPNO%Type,

RENAME

EMPA.ENAME%Type,

RJOB

EMPA.JOB%Type

);

EmpRec  MyRecType;

Begin

Select

EMPNO, ENAME, JOB

InTo

EmpRec From

empa Where empa.EMPNO =

'7369';

If  EmpRec.RJOB

= 'CLERK'

Then

DBMS_OUTPUT.PUT_LINE('Name:

'||EmpRec.RENAME);

End If;

End;

例子:数据集中的记录和记录类型中的数据关系。

DECLARE

Type MyRecType

Is  Record

(

RENO  EMPA.EMPNO%Type,

RENAME

EMPA.ENAME%Type,

RJOB

EMPA.JOB%Type

);

EmpRec

MyRecType;

vJob

EMPA.JOB%Type;

Begin

Select

EMPNO, ENAME, JOB

InTo

EmpRec From

empa Where empa.EMPNO =

'7369';

DBMS_OUTPUT.PUT_LINE('MyRecType.RJOB:

'||EmpRec.RJOB);

EmpRec.RJOB  :=

'修改值后'  ;

DBMS_OUTPUT.PUT_LINE('MyRecType.RJOB:

'||EmpRec.RJOB);

Select

JOB InTo

vJob from

empa Where

empa.EMPNO = EmpRec.RENO;

DBMS_OUTPUT.PUT_LINE('EMPA.JOB:

'||vJob);

End;

使用记录向表中插入数据?

根据表结构合理安排记录字段。比如主外键。

如果用记录(RECORD)插入数据,那么只能使用记录成员;

如果用%ROWTYPE插入数据,可以直接使用%ROWTYPE​

例子:使用记录成员向表中插入数据​​

DECLARE

Type MyRecType Is

Record

(

RENO

EMPA.EMPNO%Type,

RENAME

VARCHAR2(10),

RJOB

EMPA.JOB%Type

);

EmpRec MyRecType;

Begin

Select

EMPNO, ENAME, JOB

InTo

EmpRec From

empa Where empa.EMPNO =

'7369';

DBMS_OUTPUT.PUT_LINE(EmpRec.RENO||'

'||EmpRec.RENAME||'

'||EmpRec.RJOB);

EmpRec.RENO  := 1001;

EmpRec.RENAME :=

'杰克';

EmpRec.RJOB  :=

'办事员';

Insert InTo

empa(EMPNO,ENAME,JOB)

Values(EmpRec.RENO,

EmpRec.RENAME,EmpRec.RJOB);

Select  EMPNO, ENAME,

JOB InTo

EmpRec From

empa Where empa.EMPNO =

'1001';

DBMS_OUTPUT.PUT_LINE(EmpRec.RENO||'

'||EmpRec.RENAME||'

'||EmpRec.RJOB);

End;

使用记录更新数据?

如果用记录(RECORD)更新数据,那么只能使用记录成员;

如果用%ROWTYPE更新数据,可以直接使用%ROWTYPE。

​ 例子:使用%ROWTYPE向表中插入数据

DECLARE

vEmp empa%RowType;

Begin

Select

*

InTo

vEmp From

empa Where empa.EMPNO =

'7369';

UpDate empa Set ROW

= vEmp Where EMPNO = 1001;

End;

使用记录删除数据?

删除记录时,只能在delete语句的where子句中使用记录成员

五:type

table用法

4.1:定义

type 变量 is table of 类型

TYPE orders_type IS TABLE OF

all_orders%ROWTYPE;

4.2:用法

1. TYPE tabletype IS

TABLE OF type

INDEX BY

BINARY_INTEGER;

定义:TYPE t_charTable IS

TABLE OF VARCHAR2(10)

INDEX BY

BINARY_INTEGER;

引用:tableName(index);

例子:​

declare

type

t_table is table of

varchar2(10) indexby

BINARY_integer;

MyTab   t_table;

begin

MyTab(1)

:= 'A';

MyTab(2)

:= 'B';

MyTab(3)

:= 'C';

DBMS_OUTPUT.PUT_LINE('First

index:'||'

'|| mytab(1)

||'

');

end;

--

DECLARE

TYPE t_StudentTable IS TABLE OF students%ROWTYPE INDEXBY

BINARY_INTEGER;

v_Students t_StudentTable;

BEGIN

SELECT * INTO

v_Students(1100)

FROM students

WHERE id=1100;

DBMS_OUTPUT.PUT_LINE(

v_Students(1100).OUUSRNM);

END;

--record

table综合使用​

--例子:

Declare

Type RecType Is

Record

(

rno

empa.empno%type,

rname

empa.ename%type,

rsal

empa.sal%type

);

Type TabType Is Table

Of

RecType Index

By Binary_Integer;

MyTab TabType;

vN Number;

Begin

--填充

vN := 1;

For varR In

(Select

* From

empa Order By

empno ASC)

Loop

MyTab(vN).rno  := varR.empno;

MyTab(vN).rname :=

varR.ename;

MyTab(vN).rsal :=

varR.sal;

vN := vN + 1;

End Loop;

--访问

vN := MyTab.First;

For varR In

vN..MyTab.count

Loop

DBMS_OUTPUT.PUT_LINE(vN

||'

'||MyTab(vN).rno||'

'||MyTab(vN).rname||'

'||MyTab(vN).rsal);

vN :=

MyTab.Next(vN);

End Loop;

End;

注意:

Oracle中index by binary_integer的作用

如语句:type  numbers  is

table of number index by binary_integer;其作用是,加了”index by

binary_integer

”后,numbers类型的下标就是自增长,numbers类型在插入元素时,不需要初始化,不需要每次extend增加一个空间。

而如果没有这句话“index by

binary_integer”,那就得要显示对初始化,且每插入一个元素到numbers类型的table中时,都需要先extend.

​示例:

没加“index by binary_integer”时:

declare

type numbers is table

of number;

n

numbers := numbers();

begin

n.extend;

n(1) := 2;

n.extend;

n(2) := 3;

for i in1 .. n.count

loop

dbms_output.put_line(n(i));

end loop;

end;

--输出:2,3

而如果加了“index by binary_integer”,代码如下写就可以达到上面的效果

declare

type numbers is table

of number index

by binary_integer;

n numbers;

begin

n(1) := 2;

n(2) := 3;

for i in1 .. n.count

loop

dbms_output.put_line(n(i));

end loop;

end;​

六:create type 用法

5.1:定义

概念

方法:是在对象类型说明中用关键字

MEMBER

声明的子程序

方法是作为对象类型定义组成部分的一个过程或函数

方法不能与对象类型或其任何属性同名

与数据包程序相似,大多数方法有两个部分

CREATE

[OR

REPLACE]

TYPE

AS   OBJECT

(attribute1

datatype,

:

attributeN

datatype

MEMBER

PROCEDURE

(parameter,

mode,   datatype),

MEMBER

FUNCTION

(parameter,

mode,   datatype)

RETURN

datatype,PRAGMA

RESTRICT_REFERENCES

(,WNDS/RNDS/WNPS/RNPS)

);

说明:PRAGMA

RESTRICT_REFERENCES指定MEMBER方法按以下模式之一

操作:

–WNDS

(不能写入数据库状态)

不能修改数据库

–RNDS

(不能读出数据库状态)

不能执行查询

–WNPS

(不能写入数据包状态)

不能更改数据包变量的值

–RNPS

(不能读出数据包状态)

不能引用数据包变量的值

例:​

create

or

replace

type

FLIGHT_SCH_TYPE

as

object

(FLIGHTNO

VARCHAR2(4) ,AIRBUSNO

VARCHAR2(5)   ,

ROUTE_CODE

VARCHAR2(7) ,DEPRT_TIME

VARCHAR2(10)   ,

JOURNEY_HURS

VARCHAR2(10) , FLIGHT_DAY1

NUMBER(1)   ,

FLIGHT_DAY2

NUMBER(1)

,​

Memberfunction  DAYS_FN(FLIGHT_DAY1

in

number)return

varchar2,

Pragma  restrict_references(DAYS_FN

,

WNDS))   ;

创建对象类型方法主体

CREATE

[OR

REPLACE]

TYPE

BODY

AS MEMBER

FUNCTION

(parameter

dataype)   RETURN

IS;MEMBER

PROCEDURE

(parameter

datatype);

END;

​例:​

create

or

replace

type

body

FLIGHT_SCH_TYPE

as

member

function

DAYS_FN(FLIGHT_DAY1

in

number)

return

varchar2

is

disp_day

varchar2(20)   ;

begin

if

flight_day1

=

1 then

disp_day

:=

'Sunday'

;

elsif

flight_day1

=

2 then

disp_day

:=

'Monday'

;

elsif

flight_day1

=

3

then

disp_day

:=

'Tuesday'

;

elsif

flight_day1

=

4

then

disp_day

:=

'Wednesday'

;

elsif

flight_day1

=

5

then

disp_day

:=

'Thursday'

;

elsif

flight_day1

=

6

then

disp_day

:=

'Friday

'

;

elsif

flight_day1

=

7 then

disp_day

:=

'Saturday'

;

end

if

;

return

disp_day   ;

end

;

end

;

A. 创建基于对象的表语法:

create

table

of

意义:此表具有该类型和member方法的所有属性,

我们不能通过DBA

STUDIO的表数据编辑器来编辑数据。

例:create

table

FLIGHT_SCH_TAB

of   FLIGHT_SCH_TYPE

insert

into

FLIGHT_SCH_TAB

values('SL36','AB02','SAN-LOU','5','13:30',3,6);

B.访问对象表中的MEMBER方法

SELECT

,

.FROM

;

例:select

flightno,route_code,f.days_fn(flight_day1) as

FLIGHTDAY from FLIGHT_SCH_TAB  f;

C.关系表中的字段为对象类型

create

table

FLIGHT_SCH_TABS(FLIGHT_DET

FLIGHT_SCH_TYPE

,

FLIGHT_DESC

varchar2(20))   ;

注:插入数据,对于对象类型的字段的值,需要通过构造函数来得到。对象类型名称(成员1,..成员n)

例:insert

into

FLIGHT_SCH_TABS

values(FLIGHT_SCH_TYPE('SL36','AB02','SAN-LOU','5','13:30',3,6),'DESC1');

D.访问关系表中的Member方法此处的关系表:指表中有字段为对象类型

SELECT

,

..FROM

;

例:select

f.flight_det.FLIGHTNO,f.flight_det.ROUTE_CODE,f.flight_det.DAYS_FN(f.flight_det.FLIGHT_DAY1)

FLIGHTDAY from flight_sch_tabs f;

1. 声明简单类型内容包括:

A   对象类型的创建

B.基于对象的表的创建插入与访问

C

关系对象表的创建插入与访问

2. 通过value运算符访问基于类型的表

select

value(

From

例:select

value(A)

FROM

FLIGHT_SCH_TAB

A

--返回的是对象区别

select

*

from

FLIGHT_SCH_TAB;--返回的是单个的值

3.

REF

运算符使您可以引用对象表中现有行的

OID

REF

运算符将表别名作为输入,并且为行对象返回

OID

语法:select

REF()

from

例:select

ref(a)

from

FLIGHT_SCH_TAB

a

;注:FLIGHT_SCH_TAB

是基于对象的表

4.声明复合类型

CREATE

TYPE   name_type

AS

OBJECT(name

VARCHAR2(20),

address

address_type);

5.定义对象之间的关系也是通过关键字REF,前面我们能过REF查询了基于对象的表中的对象的OID值,这里我们讲REF的另一个用途,即通过REF来定义对象之间的关系

称为引用的

REF

允许您创建行对象指针

它将创建对被引用对象位置的引用i该指针用于查询、更新或删除对象iREF

由目标对象的

OID、数据库标识符(列)和对象表构成iOID

用于创建使用

REF

DEREF

运算符的外键列的关系

iSQL

PL/SQL

语句必须使用

REF

函数来处理对象引用

可按如下步骤关联两个表

1.

创建对象类型,下面我们会创建另一个表,这个表的一个字段的类型为此类型

create

or

replace

type

type_class

as

object(

classid

varchar2(10)

,

classname

varchar2(10))/

2. 创建基于此类型的表

create

table

tbl_type_class

of

type_class

3.

创建具有外键列的关系表,有一个外键将引用1中定义的类型,并且该外键的值在2中已有的数据已经存在

create

table

tbl_student_ref(

stuid

varchar2(20)

,

stuname

varchar2(20)

,

age

number(10)

,

grade

ref

type_class

scope

is

tbl_type_class)

4. 将数据插入到对象表中

begin

insert

into

tbl_type_class

values('gid1'

,

'gname1')   ;

insert

into

tbl_type_class

values('gid2'

,

'gname2')

;

commit

;end

;/

5.将数据插入到关系对象表中,必须从上面创建的对象表中引用数据;

insert

into

tbl_student_ref

select

'stuid1',

'stuname1',20,ref(a)

from

tbl_type_class

a

where   classid='gid1'

注:下面的方法是不行的!

insert

into

tbl_student_ref

values(

'stuid2',

'stuname2',

20,

select

ref(a)

from

tbl_type_class

a

where

classid='gid1'

)/

6.服从值若要查看引用的值,则需要使用DEREF运算符i语法

SELECT

DEREF(.)FROM

;例:select

deref(grade)

from   tbl_student_ref

复杂用法:

一、抽象数据类型

1、创建类型

--地址类型

CREATE OR REPLACE TYPE AddressType AS OBJECT

(

Country varchar2(15),

City varchar2(20),

Street varchar2(30)

);

2、类型嵌套

--创建基于前一个类型的新的抽象数据类型:巨星类型

​CREATE

OR REPLACE TYPE

SuperStarType AS OBJECT

(

StarName varchar2(30),

Address AddressType

);

3、基于抽象类型创建关系表

CREATE TABLE

SuperStar

(

StarID varchar(10),

Star SuperStarType

);

4、基于抽象类型创建对象表​

CREATE TABLE SuperStarObj

of SuperStarType;

5、使用构造方法在表中插入记录

INSERT INTO SuperStar

VALUES(''001'',SuperStarType(''Zidane'',AddressType(''France'',''Paris'',''People

Street

NO.1'')));​

6、抽象数据类型的继承

(1)创建一个类型​

CREATE OR REPLACE

TYPE PersonType AS

OBJECT

(

PersonName

varchar(10),

PersonSex varchar(2),

PersonBirth date

) not

final;​

(2)派生一个类型

CREATE OR REPLACE

TYPE StudentType UNDER PersonType

(

StudentNO int,

StudentScore int

);

(3)查看数据字典​

DESC StudentType

StudentType extends SYS.PERSONTYPE

(4)创建对象表​

CREATE TABLE student

OF StudentType;

(5)向对象表中插入数据

INSERT INTO student

VALUES(''Rose'',''nv'',to_date(''1983-05-02'',''yyyy-mm-dd''),1001,98);

(6) 查询数据

SELECT*

FROM

student;​

子类型

这种类型最简单,类似类型的一个别名,主要是为了对常用的一些类型简单化,它基于原始的某个类型。

如:

有些应用会经常用到一些货币类型:number(16,2)。如果在全局范围各自定义这种类型,一旦需要修改该类型的精度,则需要一个个地修改。

那如何实现定义的全局化呢?于是就引出了子类型: subtype cc_num is number(16,2);

这样就很方便地解决了上述的麻烦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值