选择带别名和不带-oracle 11g 有什么区别

Bar*_*wik 6 sql oracle select alias user-defined-types

我有一张桌子,让我们给它起个名字吧table1

该表由许多列组成,其中一列是一个对象,它由 3 个子列组成,我们称它们为value1, value2, value3

假设对象类型名为object_type1

我准备了一个投影查询,如下所示:

Select typed_column.value1 
from table1
Run Code Online (Sandbox Code Playgroud)

此投影不适用于 Oracle 11g,它显示“无效标识符”。

所以我尝试将表名添加到所选列:

Select table1.typed_column.value1 
from table1
Run Code Online (Sandbox Code Playgroud)

它也没有奏效。

但是当我使用别名时:

Select tab1.typed_column.value1 
from table1 tab1
Run Code Online (Sandbox Code Playgroud)

它正在工作。

我还发现了另一个同样有效的解决方案(使用treat 功能):

Select treat(typed_column as object_type1).value1 
from table1
Run Code Online (Sandbox Code Playgroud)

我的问题是:别名有什么作用,数据库实际上知道如何映射对象类型列?

为什么我的前两个查询不能正常工作?

我准备了一个表和类型,表的 DDL 看起来像:

CREATE TABLE table1 ( --....lot of other columns before typed_column OBJECT_TYPE_1 )

和对象的DDL:

CREATE OR REPLACE TYPE "MY_SCHEMA"."OBJECT_TYPE_1" is object ( value1 varchar2(100), value2 date, value3 date )

Chr*_*xon 3

你必须这样做,因为文档就是这么说的;)

2.1.8.1 当需要表别名时

可能需要表别名以避免解析引用时出现问题。

Oracle 数据库要求您使用表别名来限定对子程序或对象属性的任何点符号引用,以避免内部捕获和解析引用时出现类似问题。

好的,那么为什么会有这个规则呢?

考虑这种情况:

create type emp_obj as object (
  employee_id   integer,
  employee_name varchar2(100),
  department_id integer
);
/

create table departments (
  department_id integer,
  manager       emp_obj
);
/

create table manager (
  employee_id   integer,
  employee_name varchar2(100),
  department_id integer
);

select * from departments d
where  exists ( 
  select * from manager
  where  manager.department_id = d.department_id --which manager.department_id?
);
Run Code Online (Sandbox Code Playgroud)

在这个例子中

  • departments表有一个带有属性的manager对象列department_id
  • manager表有一列department_id

那么where manager.department_id决心做什么?

如果没有别名,它可以是任一表。当您存储对象时,可能会:

<table_name>.<column_name><object_column_name>.<attribute_name>与同一查询中的另一个表相同!

当您开始从表中添加/删除列或从类型中添加/删除属性时,这会创建名称解析......令人惊讶。

因此,为了避免这种情况,Oracle 数据库强制您必须使用别名。

就像在查询中两次使用同一个表时需要使用别名一样:

create table t (
  c1 int, c2 int
);

select * from t, t
where  c1 = 1;

ORA-00918: column ambiguously defined

select * from t t1, t t2
where  t1.c1 = 1;

no rows selected
Run Code Online (Sandbox Code Playgroud)

请注意,该规则有一个细化:

当直接引用对象表的顶级属性而不使用点符号时,表别名的使用是可选的。例如,以下语句定义两个包含 person_typ 对象类型的表。person_obj_table 是 person_typ 类型的对象的对象表,contacts 是包含对象 person_typ 的列的关系表。

创建对象表时,属性就是列。所以上面的歧义就消失了。