select 有别名和没有 oracle 11g 有什么区别

What is the difference in select with alias, and without- oracle 11g

我有一个table,我们把它命名为table1

table由很多列组成,其中一列是一个对象,由3个子列组成,我们称它们为value1value2value3.

假设对象类型被命名为 object_type1.

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

Select typed_column.value1 
from table1

此投影不适用于 Oracle 11g,它表示 'invalid identifier'。

所以我尝试将 table 的名称添加到所选列:

Select table1.typed_column.value1 
from table1

也没用。

但是当我使用别名时:

Select tab1.typed_column.value1 
from table1 tab1

有效。

我还找到了另一个同样有效的解决方案(使用 treat 函数):

Select treat(typed_column as object_type1).value1 
from table1

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

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

我准备了一个table和类型,table的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 )

您不应在查询的两边都引用 table。如果您 select 从 table A 获取数据,请不要 select A.B.C。来自 A

的 select B.C

你必须这样做,因为那是 what the docs say ;)

2.1.8.1 When Table Aliases Are Required

Table aliases can be required to avoid problems resolving references.

Oracle Database requires you to use a table alias to qualify any dot-notational reference to subprograms or attributes of objects, to avoid inner capture and similar problems resolving references.

好的,那么为什么这条规则存在?

考虑这种情况:

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?
);

在这个例子中

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

那么 where manager.department_id 解决了什么?!

在没有别名的情况下,它可以是 table。当您存储对象时,可能有:

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

当您从 table 开始 adding/removing 列或从类型开始属性时,这会创建名称解析...惊喜。

因此,为避免此 Oracle 数据库强制要求您必须使用别名。

就像在查询中两次使用相同的 table 时需要使用别名一样:

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

请注意对规则进行了改进:

Use of a table alias is optional when referencing top-level attributes of an object table directly, without using the dot notation. For example, the following statements define two tables that contain the person_typ object type. person_obj_table is an object table for objects of type person_typ, and contacts is a relational table that contains a column of the object person_typ.

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