You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL3中两次CREATE TYPE person的差异解析及基于person类型创建Employee表并插入数据的技术咨询

嘿,我来帮你拆解这段Oracle对象类型的代码,还有后续的表创建和插入操作~

一、两次CREATE TYPE person的区别

这两次声明其实是Oracle对象类型里的前向声明+实际定义的组合,目的是解决类型之间的循环引用问题:

  • 第一次Create Type person;:前向声明(Forward Declaration)
    这只是告诉Oracle:“我后面会定义一个叫person的对象类型,你先记着它存在就行”。因为紧接着要创建的child类型是Table Of Ref person——也就是存储指向person对象的引用集合,这时候如果不提前声明person类型,Oracle会报错说找不到这个类型,就像你写代码时要先声明函数再调用一样。

  • 第二次Create Type person AS Object (...):实际类型定义
    这才是真正给person类型“填肉”,定义了它的具体属性:

    • name varchar(10):存储人名的字符串字段
    • father ref person:指向另一个person对象的引用(用来表示父子关系)
    • children child:前面定义的child类型,也就是一个person对象引用的集合(用来记录当前对象的所有子女)
二、基于person类型创建Employee表并插入数据

我们可以用两种方式创建表:一种是直接把表定义为存储person对象的对象表,另一种是在普通关系表里加一个person类型的列。

方式1:创建Employee对象表(直接存储person对象)

对象表的每一行就是一个完整的person对象,适合完全用对象模型来管理数据。

创建表的SQL:

CREATE TABLE Employee OF person;

插入数据的示例:

因为涉及到对象引用(ref),我们得先插入父级对象,再获取它的引用来关联子级对象:

  1. 先插入一个父级员工(比如父亲John):
INSERT INTO Employee VALUES ('John', NULL, child());

这里child()表示初始化一个空的子女集合,暂时没有子女。

  1. 获取John的对象引用,插入他的儿子Mike:
DECLARE
  john_ref REF person;
BEGIN
  -- 查询John的对象引用并存储到变量里
  SELECT REF(e) INTO john_ref FROM Employee e WHERE e.name = 'John';
  -- 插入Mike,关联John的引用,同时初始化空子女集合
  INSERT INTO Employee VALUES ('Mike', john_ref, child());
END;
/

方式2:创建包含person类型列的关系表

如果需要混合关系型和对象型数据,可以创建普通表,其中一列是person类型:

创建表的SQL:

CREATE TABLE Employee (
  emp_id NUMBER PRIMARY KEY, -- 普通主键列
  emp_info person -- 存储person对象的列
);

插入数据的示例:

同样先处理父级对象,再关联引用:

  1. 插入父级员工John:
INSERT INTO Employee VALUES (1, person('John', NULL, child()));
  1. 获取John的对象引用,插入他的儿子Mike:
DECLARE
  john_ref REF person;
BEGIN
  SELECT REF(e.emp_info) INTO john_ref FROM Employee e WHERE e.emp_id = 1;
  INSERT INTO Employee VALUES (2, person('Mike', john_ref, child()));
END;
/

内容的提问来源于stack exchange,提问作者user9517769

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 03:44:06