Ответ 1
На самом деле, легко решить исходную проблему. Вам просто нужно квалифицировать *.
select is_parent, animals.* from animals;
должен работать нормально. Псевдонимы для имен таблиц также работают.
Скажем, у меня есть оператор select, который идет.
select * from animals
Это дает результат запроса всех столбцов в таблице.
Теперь, если 42-й столбец таблицы animals
равен is_parent
, и я хочу вернуть это в моих результатах сразу после gender
, поэтому я могу увидеть его более легко. Но я также хочу, чтобы все остальные столбцы.
select is_parent, * from animals
Это возвращает ORA-00936: missing expression
.
Тот же оператор отлично работает в Sybase, и я знаю, что вам нужно добавить псевдоним таблицы в таблицу animals
, чтобы заставить его работать (select is_parent, a.* from animals ani
), но почему Oracle должен иметь псевдоним таблицы умеет выработать выбор?
На самом деле, легко решить исходную проблему. Вам просто нужно квалифицировать *.
select is_parent, animals.* from animals;
должен работать нормально. Псевдонимы для имен таблиц также работают.
В производственном коде нет никакой пользы. Мы должны явно указывать нужные столбцы, а не использовать конструкцию SELECT *.
Как для специальных запросов, получите себе IDE-SQL Developer, TOAD, PL/SQL Developer и т.д., что позволяет нам манипулировать запросами и наборами результатов без необходимости расширения SQL.
До сих пор много хороших ответов на вопрос о том, почему select *
не следует использовать, и все они совершенно правильны. Однако не думайте, что кто-либо из них отвечает на исходный вопрос о том, почему этот синтаксис терпит неудачу.
К сожалению, я думаю, что причина... ", потому что это не так.
Я не думаю, что это связано с односетевыми и многозадачными запросами:
Это отлично работает:
select *
from
person p inner join user u on u.person_id = p.person_id
Но это не удается:
select p.person_id, *
from
person p inner join user u on u.person_id = p.person_id
Пока это работает:
select p.person_id, p.*, u.*
from
person p inner join user u on u.person_id = p.person_id
Это может быть какая-то историческая совместимость с 20-летним старым кодом.
Другой для "купить почему!!!" bucket вместе с почему вы не можете группировать псевдоним?
Хороший вопрос, я часто задавался этим вопросом, но потом принял его как одну из тех вещей...
Аналогичная проблема заключается в следующем:
sql>select geometrie.SDO_GTYPE from ngg_basiscomponent
ORA-00904: "GEOMETRIE"."SDO_GTYPE": invalid identifier
где geometrie - столбец типа mdsys.sdo_geometry.
Добавьте псевдоним, и все будет работать.
sql>select a.geometrie.SDO_GTYPE from ngg_basiscomponent a;
Вариант использования для формата псевдонима. * выглядит следующим образом
select parent.*, child.col
from parent join child on parent.parent_id = child.parent_id
То есть, выбирая все столбцы из одной таблицы в объединении, плюс (необязательно) один или несколько столбцов из других таблиц.
Тот факт, что вы можете использовать его для выбора одного и того же столбца дважды, является лишь побочным эффектом. Нет смысла выбирать один и тот же столбец дважды, и я не думаю, что лень является реальным оправданием.
Select *
в реальном мире опасно только при обращении к столбцам по номеру индекса после извлечения, а не по имени, большая проблема - неэффективность, когда не требуются не все столбцы в наборе результатов (сетевой трафик, загрузка процессора и памяти),
Конечно, если вы добавляете столбцы из других таблиц (как в случае с этим примером, это может быть опасно, поскольку со временем эти таблицы могут иметь столбцы с соответствующими именами, select *, x
в этом случае завершится с ошибкой, если столбец x будет добавлен в таблицу, которая ранее не имела его.
почему должен Oracle нуждаться в псевдониме таблицы, чтобы иметь возможность выработать выбор
Teradata требует того же. Поскольку оба довольно старые (возможно, лучше назвать их зрелыми:-) СУБД, это может быть историческими причинами.
Мое обычное объяснение: безоговорочный *
означает все/все столбцы, а парсер/оптимизатор просто путают, потому что вы запрашиваете больше всего.