Почему в Oracle SQL неправильно выбирать указанные столбцы и все такое?
-
22-09-2019 - |
Вопрос
Скажем, у меня есть оператор выбора, который выглядит...
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.
Хороший вопрос, я сам часто задавался этим вопросом, но потом принял это как одну из тех вещей...
Аналогичная проблема заключается в следующем:
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 *
не следует использовать, и все они совершенно верны.Однако не думайте, что кто-то из них ответит на первоначальный вопрос о том, почему конкретный синтаксис не работает.
К сожалению, я думаю, что причина в...«потому что это не так».
Я не думаю, что это как-то связано с игрой за одним столом или игрой за одним столом.многотабличные запросы:
Это отлично работает:
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-летней давности.
Другой для "Купить почему !!!" ведро, вместе с почему нельзя группировать по псевдониму?
Вариант использования формата alias.* следующий:
select parent.*, child.col
from parent join child on parent.parent_id = child.parent_id
То есть выбор всех столбцов из одной таблицы в объединении плюс (необязательно) один или несколько столбцов из других таблиц.
Тот факт, что вы можете использовать его для выбора одного и того же столбца дважды, является всего лишь побочным эффектом.Нет никакого смысла выбирать один и тот же столбец дважды, и я не думаю, что лень является реальным оправданием.
Select *
в реальном мире опасно только при обращении к столбцам по номеру индекса после извлечения, а не по имени. Более серьезной проблемой является неэффективность, когда в наборе результатов требуются не все столбцы (сетевой трафик, загрузка процессора и памяти).Конечно, если вы добавляете столбцы из других таблиц (как в этом примере, это может быть опасно, поскольку со временем в этих таблицах могут появиться столбцы с совпадающими именами). select *, x
в этом случае произойдет сбой, если столбец x будет добавлен в таблицу, в которой его раньше не было.
почему Должен ли Oracle нуждаться в псевдониме таблицы, чтобы иметь возможность обрабатывать выбор
Teradata требует того же.Поскольку оба они довольно старые (может быть, лучше назвать это зрелый :-) СУБД, возможно, это исторические причины.
Мое обычное объяснение:неквалифицированный *
означает все/все столбцы а парсер/оптимизатор просто запутался, потому что вы запрашиваете больше чем все.