在关系插入查询中引用嵌套表

发布于 2024-10-30 14:28:15 字数 1146 浏览 0 评论 0原文

以下是我拥有的对象类型。基本上我有一个人员表和一个子表作为人员表的嵌套表。

我有一个 School 表,与子表(嵌套)具有 M:N 关系。所以我正在创建一个中间表来插入 child_school 数据。

在此处输入图像描述

如何创建中间表并插入数据?

create type school_t as object(
    sid number(5,2),
    name varchar(20))
/

create type child_t as object(
    cid number(5,2),
    name varchar(20))
/

create type childtable_t as table of child_t
/

create type person_t as object(
    pid number(5,2),
    name varchar(20),
    child childtable_t)
/

create table person_tab of person_t(
    pid primary key
)nested table child store as child_table
/

create table school_tab of school_t
/

--有一些问题。下面不行。

create type school_child_t as object(
    cid ref person_t,
    sid ref school_t)
/

create table school_child_tab of school_child_t(
    cid references person_tab,
    sid references school_tab
)
/

--这是我想要做的

create table school_child_tab(
    cid number(5,2) references childtable_t,
    sid number(5,2) references school_tab
)
/

cid 引用应该是嵌套表中的 cid。问题是指它。

Below are the object types I have. Basically I have a person table and a child table as a nested table of person table.

I have a School table with a M:N Relationship with child table (nested). So I'm creating a intermediate table to insert child_school data.

enter image description here

How can I create that intermediate table and insert data?

create type school_t as object(
    sid number(5,2),
    name varchar(20))
/

create type child_t as object(
    cid number(5,2),
    name varchar(20))
/

create type childtable_t as table of child_t
/

create type person_t as object(
    pid number(5,2),
    name varchar(20),
    child childtable_t)
/

create table person_tab of person_t(
    pid primary key
)nested table child store as child_table
/

create table school_tab of school_t
/

--there's some problem. Below does not work.

create type school_child_t as object(
    cid ref person_t,
    sid ref school_t)
/

create table school_child_tab of school_child_t(
    cid references person_tab,
    sid references school_tab
)
/

--Here's what I want to do

create table school_child_tab(
    cid number(5,2) references childtable_t,
    sid number(5,2) references school_tab
)
/

cid reference should be the cid in nested table. The problem is referring it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

同展鸳鸯锦 2024-11-06 14:28:15

我看到了您的编辑,我正要告诉您不可能从外部引用嵌套表。

嵌套表在物理上创建为一个不同的表,与父表分开保存数据:

SQL> SELECT object_name, object_type
  2    FROM all_objects
  3   WHERE created > trunc(sysdate)
  4     AND object_type = 'TABLE';

OBJECT_NAME                    OBJECT_TYPE
------------------------------ -------------------
SCHOOL_TAB                     TABLE
CHILD_TABLE                    TABLE
PERSON_TAB                     TABLE

在这里您可以看到 Oracle 创建了一个 CHILD_TABLE 表,但是它对我们隐藏,只能由 Oracle 内部工作:

SQL> select * from child_table;

ORA-22812: cannot reference nested table column's storage table

在这种情况下,我非常确定您无法以任何方式引用子表,但令我惊讶的是,这似乎有效(我们无法从 CHILD_TABLE 中选择,但我们可以引用它):

SQL> alter table child_table add constraint pk_child_table primary key (cid);

Table altered

SQL> CREATE TABLE school_child_tab (
  2     cid REFERENCES child_table,
  3     sid REFERENCES school_tab
  4  );

Table created

您可以像这样构建插入(我不太喜欢存储 将数据存储为对象,但在这里):

SQL> insert into school_tab values (school_t(1, 'school A'));

1 row inserted

SQL> insert into person_tab values (
  2      person_t(1, 'person A', childtable_t(child_t(1, 'child A'))));

1 row inserted

SQL> insert into school_child_tab values (1, 1);

1 row inserted

I saw your edit, and I was about to tell you it is impossible to reference a nested table externally.

The nested table is physically created as a distinct table that holds data separately from the parent table:

SQL> SELECT object_name, object_type
  2    FROM all_objects
  3   WHERE created > trunc(sysdate)
  4     AND object_type = 'TABLE';

OBJECT_NAME                    OBJECT_TYPE
------------------------------ -------------------
SCHOOL_TAB                     TABLE
CHILD_TABLE                    TABLE
PERSON_TAB                     TABLE

Here you can see that Oracle has created a CHILD_TABLE table, however it is hidden from us and can only be worked internally by Oracle:

SQL> select * from child_table;

ORA-22812: cannot reference nested table column's storage table

In this case I was pretty sure that you couldn't reference the child table in any way, however to my surprise this seems to work (we can't select from CHILD_TABLE, however we can reference to it):

SQL> alter table child_table add constraint pk_child_table primary key (cid);

Table altered

SQL> CREATE TABLE school_child_tab (
  2     cid REFERENCES child_table,
  3     sid REFERENCES school_tab
  4  );

Table created

You could build your inserts like this (I don't really like to store to store data as objects, but here you go):

SQL> insert into school_tab values (school_t(1, 'school A'));

1 row inserted

SQL> insert into person_tab values (
  2      person_t(1, 'person A', childtable_t(child_t(1, 'child A'))));

1 row inserted

SQL> insert into school_child_tab values (1, 1);

1 row inserted
隐诗 2024-11-06 14:28:15

我稍微改变了您的数据模型:

SQL> create type school_t as object(
  2      sid number(5,2),
  3      name varchar(20))
  4  /

Type created.

SQL> create type child_t as object(
  2      cid number(5,2),
  3      name varchar(20))
  4  /

Type created.

SQL> create table school_tab of school_t
  2  /

Table created.

SQL> create table child_tab  of child_t
  2  /

Table created.

SQL>

让我们填充嵌套表:

SQL> insert into child_tab
  2      values (111, 'Fred')
  3  /

1 row created.

SQL> insert into child_tab
  2      values (112, 'Ayesha')
  3  /

1 row created.

SQL> insert into child_tab
  2      values (113, 'Aadil')
  3  /

1 row created.

SQL> insert into school_tab
  2      values (222, 'Bash Street')
  3  /

1 row created.

SQL> insert into school_tab
  2      values (223, 'Greyfriars')
  3  /

1 row created.

SQL> 

这是一个嵌套表:

SQL> create type school_child_t as object(
  2      cid ref child_t,
  3      sid ref school_t)
  4  /

Type created.

SQL> create table school_child_tab of school_child_t
  2  /

Table created.

SQL>

我们像这样填充交集表:

SQL> insert into school_child_tab
  2        select cid, sid
  3        from
  4          ( select ref(c) as cid from child_tab c where c.cid = 111 )
  5          , ( select ref(s) as sid from school_tab s where s.sid = 222 )
  6  /

1 row created.

SQL> insert into school_child_tab
  2        select cid, sid
  3        from
  4          ( select ref(c) as cid from child_tab c where c.cid = 112 )
  5          , ( select ref(s) as sid from school_tab s where s.sid = 222 )
  6  /

1 row created.

SQL> insert into school_child_tab
  2        select cid, sid
  3        from
  4          ( select ref(c) as cid from child_tab c where c.cid = 113 )
  5          , ( select ref(s) as sid from school_tab s where s.sid = 222 )
  6  /

1 row created.

SQL> insert into school_child_tab
  2        select cid, sid
  3        from
  4          ( select ref(c) as cid from child_tab c where c.cid = 113 )
  5          , ( select ref(s) as sid from school_tab s where s.sid = 223 )
  6  /

1 row created.

SQL>

查询结果

SQL> select c.name as child_name
  2         , s.name as school_name
  3  from     school_child_tab sc
  4              join child_tab c
  5                  on ( ref(c) = sc.cid )
  6              join school_tab s
  7                  on ( ref(s) = sc.sid )
  8  /

CHILD_NAME           SCHOOL_NAME
-------------------- --------------------
Fred                 Bash Street
Ayesha               Bash Street
Aadil                Greyfriars
Aadil                Bash Street

SQL>

当然,这提出了一个问题:如果您要使用对象的 REF您需要 ID 列吗?当然,我认为对于 CHILD_T 类型有一个名为 CID 的 NUMBER 类型的属性和对于 SCHOOL_CHILD_T 类型具有相同名称但数据类型为 REF 的属性是有误导性的。

I have slightly altered your data model:

SQL> create type school_t as object(
  2      sid number(5,2),
  3      name varchar(20))
  4  /

Type created.

SQL> create type child_t as object(
  2      cid number(5,2),
  3      name varchar(20))
  4  /

Type created.

SQL> create table school_tab of school_t
  2  /

Table created.

SQL> create table child_tab  of child_t
  2  /

Table created.

SQL>

Let's populate the nested tables:

SQL> insert into child_tab
  2      values (111, 'Fred')
  3  /

1 row created.

SQL> insert into child_tab
  2      values (112, 'Ayesha')
  3  /

1 row created.

SQL> insert into child_tab
  2      values (113, 'Aadil')
  3  /

1 row created.

SQL> insert into school_tab
  2      values (222, 'Bash Street')
  3  /

1 row created.

SQL> insert into school_tab
  2      values (223, 'Greyfriars')
  3  /

1 row created.

SQL> 

Here is a nested table:

SQL> create type school_child_t as object(
  2      cid ref child_t,
  3      sid ref school_t)
  4  /

Type created.

SQL> create table school_child_tab of school_child_t
  2  /

Table created.

SQL>

We populate the intersection table like this:

SQL> insert into school_child_tab
  2        select cid, sid
  3        from
  4          ( select ref(c) as cid from child_tab c where c.cid = 111 )
  5          , ( select ref(s) as sid from school_tab s where s.sid = 222 )
  6  /

1 row created.

SQL> insert into school_child_tab
  2        select cid, sid
  3        from
  4          ( select ref(c) as cid from child_tab c where c.cid = 112 )
  5          , ( select ref(s) as sid from school_tab s where s.sid = 222 )
  6  /

1 row created.

SQL> insert into school_child_tab
  2        select cid, sid
  3        from
  4          ( select ref(c) as cid from child_tab c where c.cid = 113 )
  5          , ( select ref(s) as sid from school_tab s where s.sid = 222 )
  6  /

1 row created.

SQL> insert into school_child_tab
  2        select cid, sid
  3        from
  4          ( select ref(c) as cid from child_tab c where c.cid = 113 )
  5          , ( select ref(s) as sid from school_tab s where s.sid = 223 )
  6  /

1 row created.

SQL>

Query back the results

SQL> select c.name as child_name
  2         , s.name as school_name
  3  from     school_child_tab sc
  4              join child_tab c
  5                  on ( ref(c) = sc.cid )
  6              join school_tab s
  7                  on ( ref(s) = sc.sid )
  8  /

CHILD_NAME           SCHOOL_NAME
-------------------- --------------------
Fred                 Bash Street
Ayesha               Bash Street
Aadil                Greyfriars
Aadil                Bash Street

SQL>

Of course, that raises a question: if you're going to use the object's REF do you need the ID column? Certainly I think it is misleading to have a attribute called CID of type NUMBER for the CHILD_T type and an attribute with the same name but a datatype of REF for the SCHOOL_CHILD_T type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文