В чем разница в выборе с псевдонимом и без - oracle 11g - PullRequest
6 голосов
/ 28 января 2020

У меня есть таблица, назовем ее table1.

Таблица состоит из множества столбцов, и один из столбцов является объектом, состоящим из 3 подколонок, назовем их value1, value2, value3.

Скажем, объект типа назван 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

Это работает.

Я также нашел другое решение, которое работает также (с использованием лечения function):

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 объекта:

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

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Вы должны это сделать, потому что это , что говорят документы ;)

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 есть столбец объекта 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

Обратите внимание, что в этом правиле есть уточнение:

Использование псевдонима таблицы необязательно при прямой ссылке на атрибуты верхнего уровня таблицы объектов без использования точечной нотации. Например, следующие операторы определяют две таблицы, которые содержат тип объекта person_typ. person_obj_table - это таблица объектов для объектов типа person_typ, а contacts - это реляционная таблица, которая содержит столбец объекта person_typ.

При создании таблицы объектов атрибуты равны столбцы. Так что неясности выше go прочь.

0 голосов
/ 28 января 2020

Вы не должны ссылаться на таблицу с обеих сторон вашего запроса. Если вы выбираете данные из таблицы A, не выбирайте AB C. Просто выберите B. C из A

...