select 有别名和没有 oracle 11g 有什么区别
What is the difference in select with alias, and without- oracle 11g
我有一个table,我们把它命名为table1
。
table由很多列组成,其中一列是一个对象,由3个子列组成,我们称它们为value1
、value2
、value3
.
假设对象类型被命名为 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
对象列
manager
table有一列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 时,属性 是 列。所以上面的歧义消失了。
我有一个table,我们把它命名为table1
。
table由很多列组成,其中一列是一个对象,由3个子列组成,我们称它们为value1
、value2
、value3
.
假设对象类型被命名为 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
对象列manager
table有一列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 时,属性 是 列。所以上面的歧义消失了。