`

第十章 PL/SQL对象类型 ( 2 )

阅读更多

七、声明并初始化对象

只要对象类型在模式中定义了,我们就可以在任何PL/SQL块、子程序或包中引用它来声明对象。例如,我们可以使用对象类型作为属性、字段、变量、绑定变量、记录的域、表元的素、形式参数或函数返回值的数据类型。在运行时,对象类型的实例会被创建,也就是对象实例被初始化。

1、定义对象

我们可以在使用内置类型(如CHAR或NUMBER)的地方使用对象类型。在下面的块中,我们声明了Rational类型的对象r。然后调用构造函数初始化对象,把值6和8分别赋给属性num和den。

DECLARE
  r   rational;
BEGIN
  r    := rational(6, 8);
  DBMS_OUTPUT.put_line(r.num);   -- prints 6
END;

我们还可以把对象作为函数和过程的形式参数。那样就能把对象从一个子程序传递到另一个子程序了。在下面的例子中,我们使用对象类型Account作为形式参数:

DECLARE
  ...
  PROCEDURE open_acct (new_acct IN OUT Account) IS ...

下面,我们把Accout作为函数的返回类型来使用:

DECLARE
  ...
  FUNCTION get_acct (acct_id IN INTEGERRETURN Account IS ...

2、初始化对象

如果不调用构造函数初始化对象,那它会被自动赋上空值。也就是说对象本身为空,不单单指它的属性。如下例:

DECLARE
  r   rational;   -- r becomes atomically null
BEGIN
  r    := rational(2, 3);   -- r becomes 2/3
END;

一个空对象总不能等于另一个对象。实际上,拿一个空对象与另一个对象比较结果总是NULL.同样,如果把一个空对象或NULL赋给另一个对象,那么被赋值的对象也为空,示例如下:

DECLARE
  r   rational;
BEGIN
  r    := rational(1, 2);   -- r becomes 1/2
  r    := NULL;   -- r becomes atomically null
  IF r IS NULL THEN ...   -- condition yields TRUE

一个好的编程习惯就是在声明的时候就为对象初始化,例如:

DECLARE
  r Rational := Rational(2,3);   -- r becomes 2/3

3、PL/SQL如何对待未初始化对象

在表达式中,未初始化的对象属性值为NULL。如果为一个未初始化的对象属性赋值,就会引起预定义异常ACCESS_INTO_NULL。当对未初始化的对象或是它的属性使用IS NULL做比较时,结果总为TRUE。

下面的例子就演示了空对象和含有空属性的对象之间的差异:

DECLARE
  r   rational;   -- r is atomically null
BEGIN
  IF r IS NULL THEN ...   -- yields TRUE
  IF r.num IS NULL THEN ...   -- yields TRUE
  r        := rational(NULLNULL);   -- initializes r
  r.num    := 4;   -- succeeds because r is no longer atomically null
  -- even though all its attributes are null
  r        := NULL;   -- r becomes atomically null again
  r.num    := 4;   -- raises ACCESS_INTO_NULL
EXCEPTION
  WHEN ACCESS_INTO_NULL THEN
    ...;
END;

调用一个未初始化对象的方法会引起预定义异常NULL_SELF_DISPATCH。如果把未初始化对象的属性作为IN模式参数进行传递时,就跟传递一个NULL参数一样;如果把它作为OUT或IN OUT模式参数传递,并且尝试为其赋值,就会引起异常。

八、访问属性

我们只能按名称来引用属性,不可以使用它的位置来进行引用。在下面的例子中,我们先把属性den赋给变量denominator,然后把变量numerator的值赋给属性num。

DECLARE
  r             rational := rational(NULLNULL);
  numerator     INTEGER;
  denominator   INTEGER;
BEGIN
  ...
  denominator    := r.den;
  r.num          := numerator;
END;

下面再看一个稍微复杂一点的对象嵌套例子:

CREATE TYPE address AS OBJECT(
  street     VARCHAR2(30),
  city       VARCHAR2(20),
  state      CHAR(2),
  zip_code   VARCHAR2(5)
);

CREATE TYPE student AS OBJECT(
  NAME           VARCHAR2(20),
  home_address   address,
  phone_number   VARCHAR2(10),
  status         varcahr2(10),
  advisor_name   VARCHAR2(20),
  ...
);

这里要注意的是,zip_code是对象类型Address的一个属性,而Address又是对象Student的属性home_address的数据类型。如果s是Student的对象的话,我们就可以像下面这样访问它的zip_code属性:

s.home_address.zip_code

九、定义构造函数

默认情况下,我们不需要为对象类型定义构造函数,因为系统会提供一个接受与每个属性相对应的参数的构造函数。

我们也许想定义自己的构造函数:

  1. 为某些属性提供默认值,这样就能确保属性值的正确性而不必依赖于调用者所提供的每一个属性值。
  2. 避免许多特殊用途的过程只初始化对象的不同部分。
  3. 当新的属性加到对象类型中时,避免更改调用构造函数的应用程序中的代码。构造函数也许需要一些新的代码,例如把属性设置为空,但我们还需要保持方法签名不变,这样可以使已存在的构造函数调用继续工作。
CREATE OR REPLACE TYPE rectangle AS OBJECT(
  -- The type has 3 attributes.
  LENGTH   NUMBER,
  width    NUMBER,
  area     NUMBER,
  -- Define a constructor that has only 2 parameters.
  CONSTRUCTOR FUNCTION rectangle(LENGTH NUMBER, width NUMBER)
    RETURN SELF AS RESULT
);
/

CREATE OR REPLACE TYPE BODY rectangle AS
  CONSTRUCTOR FUNCTION rectangle(LENGTH NUMBER, width NUMBER)
    RETURN SELF AS RESULT AS
  BEGIN
    SELF.LENGTH    := LENGTH;
    SELF.width     := width;
    -- We compute the area rather than accepting it as a parameter.
    SELF.area      := LENGTH * width;
    RETURN;
  END;
END;
/

DECLARE
  r1   rectangle;
  r2   rectangle;
BEGIN
  -- We can still call the default constructor, with all 3 parameters.
  r1    := NEW rectangle(10, 20, 200);
  -- But it is more robust to call our constructor, which computes
  -- the AREA attribute. This guarantees that the initial value is OK.
  r2    := NEW rectangle(10, 20);
END;
/

十、调用构造函数

只要是能够调用普通函数的地方,我们就可以调用构造函数。跟所有的函数一样,构造函数也可以作为表达式的一部分而被调用,如下例所示:

DECLARE
  r1   rational := rational(2, 3);

  FUNCTION average(x rational, y rational)
    RETURN rational IS
  BEGIN
    ...
  END;
BEGIN
  r1    := average(rational(3, 4), rational(7, 11));

  IF (rational(5, 8) > r1) THEN
    ...
  END IF;
END;

当我们为构造函数传递参数的时候,调用会把对象中需要初始化的属性赋上初始值。如果是调用默认的构造函数,我们就需要为每个属性指定一个初始值;跟常量和变量不同,属性是不可以有默认值的。下例中,第n个参数为第n个属性赋值:

DECLARE
  r   rational;
BEGIN
  r    := rational(5, 6);   -- assign 5 to num, 6 to den
  -- now r is 5/6

十一、调用方法

跟打包子程序一样,方法也是使用点标志来调用的。示例如下:

DECLARE
  r   rational;
BEGIN
  r    := rational(6, 8);
  r.normalize;
  DBMS_OUTPUT.put_line(r.num);   -- prints 3
END;

如下例所示,我们可以连续调用方法。执行顺序从左到右。首先,成员函数reciprocal()会被调用,然后成员过程normalize()被调用。

DECLARE
  r   rational := rational(6, 8);
BEGIN
  r.reciprocal().normalize;
  DBMS_OUTPUT.put_line(r.num);   -- prints 4
END;

在SQL语句中,调用无参数的方法需要使用一个空的参数列表。在过程化语句中,空的参数列表是可选的,除非我们使用链式调用,这时除了最后一个调用之外其他的都需要空的参数列表。

我们不能把过程作为连续调用的一部分,因为过程是作为语句使用而不是表达式。所以,像下面这样的语句是不允许的:

r.normalize().reciprocal;   -- not allowed

同样,如果连续调用两个函数,第一个函数必须返回一个能传入第二个函数的对象。对于静态方法,我们使用下面的语法:

type_name.method_name

这种调用是不需要对象实例的。从子类实例中调用方法时,实际执行的方法是由类的继承关系决定的。如果子类覆盖了基类的方法,子类的方法就会被调用;否则的话,基类的方法会被调用。这种情况称为动态方法分派。

十二、通过REF修饰符共享对象

在真实世界中的大多数对象都要比有理数类型庞大而且复杂。如果对象比较大的话,把对象副本从一个子程序传递到另一个子程序时效率就可能会很低。这时如果使用对象共享就很有意义了,我们可以使用一个指向对象的引用来引用所需要的对象。

共享有两个重要的好处。首先,避免了不必要的数据重复。其次,在共享的对象内容更新时,任何引用所指向的内容也会被立即更新。如下面的例子:

CREATE TYPE home AS OBJECT(
  address      VARCHAR2(35),
  owner        VARCHAR2(25),
  age          INTEGER,
  style        VARCHAR(15),
  floor_plan   BLOB,
  price        REAL(9, 2),
  ...
);
/

CREATE   TABLE homes OF home;

修改一下Person,我们就能建立家庭的模型,几个人共享一个家。我们可以使用修饰符REF来声明引用:

CREATE TYPE person AS OBJECT(
  first_name     VARCHAR2(10),
  last_name      VARCHAR2(15),
  birthday       DATE,
  home_address   REF home,   -- can be shared by family
  phone_number   VARCHAR2(15),
  ss_number      INTEGER,
  mother         REF person,   -- family members refer to each other
  father         REF person,
  ...
);

我们可以把变量、参数、字段或属性声明为引用。而且,我们还可以在SQL数据操作语句中把引用当作输入或输出变量使用。但是,我们不可以通过引用调用对象的内容。比如表达式x.attribute,其中x是一个引用,PL/SQL无法找到存放对象的数据表。例如,下面的赋值语句就是不允许的:

DECLARE
  p_ref      REF person;
  phone_no   VARCHAR2(15);
BEGIN
  phone_no    := p_ref.phone_number;   -- not allowed
END;

解决办法就是用函数DEREF或调用包UTL_REF来访问对象。

1、向前类型定义

我们只能引用已经存在的模式对象。下例中,第一个CREATE TYPE语句是不允许的,因为它引用的Department并不存在:

CREATE TYPE employee AS OBJECT(
  NAME   VARCHAR2(20),
  dept   REF department,   -- not allowed
  ...
);

CREATE TYPE department AS OBJECT(
  "number"   INTEGER,
  manager    employee,
  ...
);

把上面两个CREATE TYPE语句调换位置也不会起作用,因为这两个对象类型是互相依赖的。对象类型Employee有着一个Department类型的属性,而 Department又同样有着一个Employee类型的属性。为了解决这个问题,我们应该使用特殊的CREATE TYPE语句,我称它为向前类型定义,这样我们就可以互相引用两个独立的对象类型。现在使用下面的语句:

要调试上面的例子,我们只要把下面的语句提前即可:

CREATE TYPE Department;   -- forward type definition
-- at this point, Department is an incomplete object type

向前类型定义创建的对象类型被称为不完全对象类型(incomplete object type),因为它没有属性和方法。一个不纯的不完全对象类型有属性,但编译时会发生错误,因为它引用了一个未确定的类型。例如,下面的CREATE TYPE语句就会因对象类型Address未确定而出错:

CREATE TYPE Customer AS OBJECT (
  id     NUMBER,
  name   VARCHAR2(20),
  addr   Address,   -- not yet defined
  phone  VARCHAR2(15)
);

如果使用了向前声明,我们就可以推迟对象类型Address的定义,并且,不完全类型Customer也可以被其他应用程序的开发者引用。

十三、操作对象

我们可以在CREATE TABLE语句中把某个字段指定为对象类型。一旦表被建立,我们就可以用SQL语句把对象插入表中,选取它的属性,调用它的方法更新它的状态。

注意:访问远程的或分布式对象都是不允许的。

在下面SQL*Plus脚本中,INSERT语句调用对象类型Rational的构造函数,然后插入resulting对象。SELECT语句检索属性num的值。UPDATE语句调用成员方法reciprocal(),在交换属性num和den之后,返回Retional的值。要注意的是,在引用属性或方法时,表别名是必须的。

CREATE TABLE numbers (rn Rational, ...)
/
INSERT INTO numbers (rn) VALUES (Rational(3, 62))   -- inserts 3/62
/
SELECT n.rn.num INTO my_num FROM numbers n ...   -- returns 3
/
UPDATE numbers n SET n.rn = n.rn.reciprocal() ... --   yields 62/3

用这种方法初始化对象时,对象在数据库表之外是没有标识的。但是,对象类型是独立于表而存在的,可以用其他方式创建对象。

下例中,我们创建一个存放对象类型Retional的表。这样包含对象类型的表称为对象表。一行中的每一列都与对象的属性对应。行与行间的列值是不同的。

CREATE TABLE rational_nums OF Rational;

对象表中每行都有一个对象标识,能够唯一辨识一个存放在数据库中的对象。

1、查询对象

假定我们要在SQL*Plus中运行下面的脚本,创建一个对象类型Person和一个对象表persons,并且我们为该表填充一些数据:

CREATE TYPE person AS OBJECT(
  first_name     VARCHAR2(15),
  last_name      VARCHAR2(15),
  birthday       DATE,
  home_address   address,
  phone_number   VARCHAR2(15)
)
/

CREATE TABLE persons OF person
/

下面子查询能产生一个只包含Person对象属性的结果集:

BEGIN
  INSERT INTO employees   -- another object table of type Person
    SELECT *
      FROM persons p
     WHERE p.last_name LIKE '%Smith';

要返回对象结果集,我们就必须使用VALUE函数。

  • 使用VALUE函数

跟我们所期望的一样,函数VALUE能返回对象值。VALUE会把一个相关的变量作为它的参数。(在这里,相关变量就是行变量或与对象表中的一行相关联的表别名)。例如,要返回Person对象的结果集,要向下面这样使用VALUE:

BEGIN
  INSERT INTO employees
    SELECT VALUE(p)
      FROM persons p
     WHERE p.last_name LIKE '%Smith';

在下面的例子中,我们可以使用VALUE来返回一个特定的Person对象:

DECLARE
  p1   person;
  p2   person;
  ...
BEGIN
  SELECT VALUE(p)
    INTO p1
    FROM persons p
   WHERE p.last_name = 'Kroll';

  p2    := p1;
  ...
END;

p1是一个本地的Person对象,它是名为"Kroll"的存储对象的一个副本,而p2是另一个本地Person对象,它是p1的副本。如下例所示,我们可以使用这些变量来访问和更新它们所引用的对象:

BEGIN
  p1.last_name    := p1.last_name || ' Jr';
END;

现在,本地的Person对象p1的名字为"Kroll Jr"。

  • 使用REF函数

我们可以用函数REF来检索引用,同VALUE一样,它也把一个相关的变量作为它的参数。下例中,我们检索一个或多个指向Person对象的引用,然后把引用插入表person_refs中:

BEGIN
  INSERT INTO person_refs
    SELECT REF(p)
      FROM persons p
     WHERE p.last_name LIKE '%Smith';
END;

下面的例子我们同时检索一个引用和一个属性:

DECLARE
  p_ref         REF person;
  taxpayer_id   VARCHAR2(9);
BEGIN
  SELECT REF(p), p.ss_number
    INTO p_ref, taxpayer_id
    FROM persons p
   WHERE p.last_name = 'Parker';   -- must return one row
  ...
END;

在最后一个例子中,我们更新一个Person对象的属性:

DECLARE
  p_ref          REF person;
  my_last_name   VARCHAR2(15);
BEGIN
  SELECT REF(p)
    INTO p_ref
    FROM persons p
   WHERE p.last_name = my_last_name;

  UPDATE persons p
     SET p = person('Jill''Anders''11-NOV-67', ...)
   WHERE REF(p) = p_ref;
END;
  • 测试dangling引用

如果一个引用所指向的对象被删除了,那么它就会指向一个不存在的对象,我们称这样的引用为dangling引用。要测试这种情况,我们应该使用 SQL的IS DANGLING语句。假设关系表department的manager字段引用了对象表中的Employee对象。我们就可以使用下面的UPDATE语句来把"dangling"引用转为空值:

UPDATE department
   SET manager = NULL
 WHERE manager IS DANGLING;
  • 使用DEREF函数

我们不可以在PL/SQL过程语句中。(DEREF是dereference的缩写。当我们反引用一个指针时,我们就能获取它所指向的值。) DEREF把对象的引用作为它的参数值,然后返回这个引用所指向的对象。如果引用是"dangling"的,DEREF就会返回一个空对象。

在下面的例子中,我们可以反引用一个指向Person对象的引用。要注意的是,我们是从dummy表dual中取得引用值的。我们不需要指定对象表和检索条件,因为每个存放于对象表的对象都有唯一的互斥的对象标识,它是每一个指向对象的引用的一部分。

DECLARE
  p1      person;
  p_ref   REF person;
  NAME    VARCHAR2(15);
BEGIN
  ...
  /* Assume that p_ref holds a valid reference
  to an object stored in an object table. */

  SELECT DEREF(p_ref)
    INTO p1
    FROM DUAL;

  NAME    := p1.last_name;
END;

我们可以在后续的SQL语句中用DEREF进行反引用操作,如下例所示:

CREATE TYPE personref AS OBJECT(
  p_ref   REF person
)
/

DECLARE
  NAME     VARCHAR2(15);
  pr_ref   REF personref;
  pr       personref;
  p        person;
BEGIN
  ...
  /* Assume pr_ref holds a valid reference. */
  SELECT DEREF(pr_ref)
    INTO pr
    FROM DUAL;

  SELECT DEREF(pr.p_ref)
    INTO p
    FROM DUAL;
  ...
END;
/

下面是一个我们不能在过程语句中使用DEREF函数的例子:

BEGIN
  ...
  p1 := DEREF(p_ref);   -- not allowed

在SQL语句中,我们可以使用点标志通过一个对象字段来引用它的属性,也可以通过一个对象字段的属性引用另一个属性。如果使用了表别名,那么就还能通过引用字段来访问属性。例如,下面的语法就是有效的:

table_alias.object_column.ref_attribute
table_alias.object_column.ref_attribute.attribute
table_alias.ref_column.attribute

假设我们在SQL*Plus中运行下面的脚本来创建对象类型Address和Person,对象表persons:

CREATE TYPE address AS OBJECT(
  street     VARCHAR2(35),
  city       VARCHAR2(15),
  state      CHAR(2),
  zip_code   INTEGER
)
/

CREATE TYPE person AS OBJECT(
  first_name     VARCHAR2(15),
  last_name      VARCHAR2(15),
  birthday       DATE,
  home_address   REF address,   -- shared with other Person objects
  phone_number   VARCHAR2(15)
)
/

CREATE   TABLE persons OF person
/

引用属性home_address对应对象表persons中的一个引用,该引用指向存放在其他表中的Address对象的字段。填充数据表之后,我们就可以像下面这样反引用它的引用来得到特定的address:

DECLARE
  addr1 Address;
  addr2 Address;
  ...
BEGIN
  SELECT DEREF(home_address)
    INTO addr1
    FROM persons p
   WHERE p.last_name = 'Derringer';
END;

在下面的例子中,我们可以通过引用字段home_address来找到属性street。这种情况下,我们必须要使用表别名。

DECLARE
  my_street   VARCHAR2(25);
  ...
BEGIN
  SELECT p.home_address.street
    INTO my_street
    FROM persons p
   WHERE p.last_name = 'Lucas';
END;

2、插入对象

我们可以使用insert语句为对象表添加一条记录。下例中,我们向对象表persons插入一个Person对象:

BEGIN
  INSERT INTO persons
       VALUES ('Jenifer''Lapidus', ...);
END;

另外,我们还可以使用对象类型Person的构造函数来插入记录:

BEGIN
  INSERT INTO persons
       VALUES (person('Albert''Brooker', ...));
END;

下例中,我们可以使用RETURNING子句把对象Person的引用保存在本地变量中。注意一下这个子句是如何模拟SELECT语句的。我们也可以在UPDATE和DELETE语句中使用RETURNING子句。

DECLARE
  p1_ref   REF person;
  p2_ref   REF person;
BEGIN
  INSERT INTO persons p
       VALUES (Person('Paul''Chang', ...))
    RETURNING REF(p)
         INTO p1_ref;

  INSERT INTO persons p
       VALUES (Person('Ana''Thorne', ...))
    RETURNING REF(p)
         INTO p2_ref;
END;

要往对象表中插入对象,我们还可以利用返回同样对象类型的子查询来进行操作。示例如下:

BEGIN
  INSERT INTO persons2
    SELECT VALUE(p)
      FROM persons p
     WHERE p.last_name LIKE '%Jones';
END;

拷贝到对象表person2的行被赋予新的对象标识。对象标识是不会从对象表persons中拷贝出来的。

下面的脚本创建一个名为department的关系表,其中有一个类型为Person的字段,然后向表中插入一条记录。注意如何使用构造函数Person()为字段manager提供值。

CREATE TABLE department (
  dept_name VARCHAR2(20),
  manager person,
  LOCATION VARCHAR2(20))
/
INSERT INTO department
     VALUES ('Payroll', Person('Alan''Tsai', ...), 'Los Angeles')
/

存放到字段manager中的新Person对象是不能被引用的,因为它是被存放在字段中(不是行中)的,也就没有对象标识。

3、更新对象

如果要修改对象表中的对象属性,我们可以像下面这样使用UPDATE语句:

BEGIN
  UPDATE persons p
     SET p.home_address = '341 Oakdene Ave'
   WHERE p.last_name = 'Brody';

  UPDATE persons p
     SET p = person('Beth''Steinberg', ...)
   WHERE p.last_name = 'steinway';
END;

4、删除对象

我们可以用DELETE语句从对象表中删除对象。要有选择的删除对象,我们就得在WHERE子句中进行指定:

BEGIN
  DELETE FROM persons p
        WHERE p.home_address = '108 Palm Dr';
END;

分享到:
评论

相关推荐

    PL/SQL 用户指南与参考

    PL/SQL 用户指南与参考 第一章 PL/SQL一览 第二章 PL/SQL基础 第三章 PL/SQL数据类型 第四章 PL/SQL的控制结构 ...第十章 PL/SQL对象类型 第十一章 本地动态SQL 第十二章 PL/SQL应用程序性能调优

    PL/SQL经典介绍

    第一章 PL-SQL一览 第二章 PL-SQL基础 第三章 PL-SQL数据类型 第四章 PL-SQL的控制结构 第五章 PL-SQL集合与记录(1) ...第十一章 PL-SQL对象类型 第十二章 本地动态SQL 第十三章 PL-SQL应用程序性能调优

    PL-SQL用户指南与参考

    · 第十章 PL/SQL对象类型 2008-04-08 · 第九章 PL/SQL包 2008-04-08 · 第八章 PL/SQL子程序 2008-04-08 · 第七章 控制PL/SQL错误 2008-04-08 · 第六章 PL/SQL与Oracle间交互 2008-04-08 · 第五...

    PLSQL用户指南与参考.pdf

    目 录 第一章 PL/SQL 一览 第二章 PL/SQL 基础 第三章 PL/SQL 数据类型 第四章 PL/SQL 的控制结构 第五章 PL/SQL 集合与记录 ...第十章 PL/SQL 对象类型 第十一章 本地动态 SQL 第十二章 PL/SQL 应用程序性能调优

    数据库基础

    第十二章PL/SQL 块结构和组成元素 235 §12.1 PL/SQL结构 235 §12.2 PL/SQL块 236 §12.3 标识符 236 §12.4 PL/SQL 变量类型 237 §12.4.1 变量类型 237 §12.4.2 复合类型(记录和表) 238 §12.4.3 使用%ROWTYPE...

    Oracle9i开发文档

    Oracle9i的开发学习资料,PDF中文版,非扫描版,13章全,附带8个章节使用的SQL...第十章 系统开发 VB+Oracle9i 第十一章 存储管理 深入Oracle9i核心 第十二章 数据安全 备份与恢复实战 第十三章 性能优化 通向OCP之路

    PLSQL高级编程资料

    第十章 过程通信 10.1 报警(DBMS_ALERT 程序包) 10.1.1 建立报警的次序 10.1.2 函数应用和说明 10.1.3 应用举例 10.2 DBMS_PIPE 程序包 10.2.1 公有管道和私有管道 10.2.2 使用管道 10.2.3 DBMS_PIPE 包的函数 ...

    Oracle8i_9i数据库基础

    第十二章PL/SQL 块结构和组成元素 235 §12.1 PL/SQL结构 235 §12.2 PL/SQL块 236 §12.3 标识符 236 §12.4 PL/SQL 变量类型 237 §12.4.1 变量类型 237 §12.4.2 复合类型(记录和表) 238 §12.4.3 使用%ROWTYPE...

    北大青鸟Oracle教程集

    PPT目录: 第一章 Oracle入门; 第二章 查询和SQL函数; 第三章 锁和表分区; 第四章 数据库对象; 第五章 Oracle 中的 OOP 概念; 第六章 PL/SQL 简介; 第七章 异常和游标管理;...第十章 集合和成员函数。

    Java/JavaEE 学习笔记

    Java/JavaEE 学习笔记 作者在杰普学习时的学习笔记,是J2ee初学者必备手册,是大家学习J2EE开发的...第十章 动态PL/SQL........................383 ant学习笔记...................387 Web Service学习笔记.....388

    J2EE学习笔记(J2ee初学者必备手册)

    内容目录 .......................1 Java/JavaEE.....1 2008年11月1日...............1 ...第十章 动态PL/SQL........................383 ant学习笔记...................387 Web Service学习笔记.....388

    Oracle实际操作应用

    oracle的一些简单应用! 第一章 走进Oracle 1 第二章 SQL数据操作和查询 第三章 常用函数、事务和锁 第四章 表空间、数据库对象 第五章 数据库设计 ...第十章 数据库管理 附录 数据库导入导出

    Oracle超详细教程

    第十章 Oracle数据类型 第十一章 Oracle体系结构(DBA) 第十二章 DDL(改变表结构) 第十三章 DML(改变数据结构) 第十四章 约束 第十五章 视图 第十六章 索引 第十七章 序列、同义词 第十八章 PL SQL 第十九...

    Oracle详细教程

    第十章 Oracle 数据类型 第十一章 Oracle 体系结构(DBA) 第十二章 DDL(改变表结构) 第十三章 DML(改变数据结构 第十四章 约束 第十五章 视图 第十六章 索引 第十七章 序列、同义词 第十八章 PL SQL. 第十九章 ...

    Oracle教程 超详细

    第十章 Oracle数据类型 第十一章 Oracle体系结构(DBA) 第十二章 DDL(改变表结构) 第十三章 DML(改变数据结构) 第十四章 约束 第十五章 视图 第十六章 索引 第十七章 序列、同义词 第十八章 PL SQL 第十九章 游标、...

    详细orale教程

    第十章 Oracle 数据类型 第十一章 Oracle 体系结构(DBA) 第十二章 DDL(改变表结构) 第十三章 DML(改变数据结构) 第十四章 约束 第十五章 视图 第十六章 索引 第十七章 序列、同义词 第十八章 PL ...

    ORACLE详细教程

    第十章 Oracle 数据类型 第十一章 Oracle 体系结构(DBA) 第十二章 DDL(改变表结构) 第十三章 DML(改变数据结构 第十四章 约束 第十五章 视图 第十六章 索引 第十七章 序列、同义词 第十八章 PL SQL. 第十九章 游标...

    信永国际 中文超详细Oracle教程

    第十章 Oracle数据类型 第十一章 Oracle体系结构(DBA) 第十二章 DDL(改变表结构) 第十三章 DML(改变数据结构) 第十四章 约束 第十五章 视图 第十六章 索引 第十七章 序列、同义词 第十八章 PL SQL 第十九...

    超详细ORACLE培训实例

    第十章 Oracle 数据类型 44 第十一章 Oracle 体系结构(DBA) .................... 45 第十二章 DDL(改变表结构) ............................ 46 第十三章 DML(改变数据结构) ..................... 48 第十四章 ...

    详细的Oracle教程-Louis-pdf

    第十章 Oracle 数据类型......................44 第十一章 Oracle 体系结构(DBA) .......45 第十二章 DDL(改变表结构) ...............46 第十三章 DML(改变数据结构)........48 第十四章 约束.............49...

Global site tag (gtag.js) - Google Analytics