【问题标题】:What is the difference in select with alias, and without- oracle 11g带别名和不带别名的选择有什么区别 - oracle 11g
【发布时间】:2020-01-28 11:04:10
【问题描述】:

我有一张桌子,我们把它命名为table1

表格由许多列组成,其中一列是一个对象,由3个子列组成,我们称它们为value1value2value3

假设对象类型名为object_type1

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

Select typed_column.value1 
from table1

此投影在 Oracle 11g 上不起作用,它显示“标识符无效”。

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

Select table1.typed_column.value1 
from table1

它也没有工作。

但是当我使用别名时:

Select tab1.typed_column.value1 
from table1 tab1

它正在工作。

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

Select treat(typed_column as object_type1).value1 
from table1

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

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

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

【问题讨论】:

  • 您能分享您的表格 DDL 以便我们试用您的用例吗?
  • 因为它可能导致内部捕获。文档:link1link2 显示的示例与您的类似。
  • 这个查询:Select table1.typed_column.value1 from table1怎么可能发生内部捕获呢?您的评论很有价值,但它不是问题的答案。我仍然不知道在这种特定情况下 alias 做了什么来使它工作..
  • @thatjeffsmith DDL 现在可用

标签: sql oracle select alias user-defined-types


【解决方案1】:

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

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

在这个例子中

  • departments 表有一个带有department_id 属性的manager 对象列
  • 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

注意对规则进行了改进:

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

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

【讨论】:

    【解决方案2】:

    您不应在查询的两侧引用该表。如果您从表 A 中选择数据,请不要选择 A.B.C。只需从 A 中选择 B.C

    【讨论】:

    • 这就是我在第一个查询中所做的:Select typed_column.value1 from table1 ?还是你的意思是别的?
    猜你喜欢
    • 2012-04-26
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    • 2020-06-13
    • 1970-01-01
    相关资源
    最近更新 更多