Почему выбор является указанными столбцами и всеми, неправильно в Oracle SQL?

Скажите, что у меня есть избранный оператор, который идет..

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 должен быть нужен псевдоним таблицы, чтобы смочь разработать выбор?

23
задан OMG Ponies 10 November 2010 в 03:13
поделиться

6 ответов

На самом деле исходную проблему легко решить. Вам просто нужно получить сертификат *.

select is_parent, animals.* from animals;

должно работать нормально. Псевдонимы для имен таблиц также работают.

24
ответ дан 29 November 2019 в 02:27
поделиться

Нет смысла делать это в производственном коде. Мы должны явно назвать нужные столбцы, а не использовать конструкцию SELECT *.

Что касается специальных запросов, возьмите себе IDE - SQL Developer, TOAD, PL / SQL Developer и т. Д., Которая позволяет нам манипулировать запросами и наборами результатов без необходимости расширения SQL.

2
ответ дан 29 November 2019 в 02:27
поделиться

Хороший вопрос, я и сам часто задавался этим вопросом, но потом принял его как один из тех...

Похожая проблема:

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;
2
ответ дан 29 November 2019 в 02:27
поделиться

Пример использования формата псевдонима. * Следующий

select parent.*, child.col
from parent join child on parent.parent_id = child.parent_id

То есть выбор всех столбцов из одной таблицы в объединении плюс (необязательно ) один или несколько столбцов из других таблиц.

Тот факт, что вы можете использовать его для выбора одного и того же столбца дважды, является лишь побочным эффектом. Нет никакого смысла выбирать один и тот же столбец дважды, и я не думаю, что лень является настоящим оправданием.

1
ответ дан 29 November 2019 в 02:27
поделиться

Выбор * в реальном мире опасен только при обращении к столбцам по номеру индекса после извлечения, а не по имени, более серьезной проблемой является неэффективность, когда не все столбцы требуются в наборе результатов (сетевой трафик, загрузка процессора и памяти). Конечно, если вы добавляете столбцы из других таблиц (как в этом примере, это может быть опасно, поскольку эти таблицы могут со временем появляются столбцы с совпадающими именами, select *, x в этом случае завершится ошибкой, если столбец x будет добавлен в таблицу, в которой раньше его не было.

1
ответ дан 29 November 2019 в 02:27
поделиться

Короткий ответ заключается в том, что необходимо буферизировать данные в модели данных и обновлять таблицу новыми данными только в том случае, если таблица не прокручивается. Это необходимо сделать в модели данных, поскольку делегат источника данных понятия не имеет, что находится внутри модели данных или что изменилось.

Однако с точки зрения проектировать пользовательского интерфейса наличие таблицы, активно обновляемой во время прокрутки, дезориентирует пользователя. Пользователь думает, что они находятся в верхней/средней/нижней части таблицы, затем внезапно оказываются в нижней/верхней/средней части. Пользователь будет думать, что он просмотрел все данные в одном разделе таблицы, но на самом деле таблица добавит то, что ему нужно было увидеть. Например, если таблица представляет собой список алфавитных имен, пользователь проверяет все имена, начинающиеся с «U», видит, что их нет, и затем отправляется на проверку в другое место таблицы. При этом таблица незаметно обновляет раздел «U» новыми именами, пока пользователь ищет другое место. Даже если пользователь понимает, что таблица динамически обновляется (чего нет в большинстве случаев), ему придется постоянно прокручивать проверку фактически всей таблицы, чтобы увидеть, что изменилось.

Лучший дизайн пользовательского интерфейса - предоставить пользователю возможность обновления. Установите кнопку «Update» или «New Data Available» на панели, а затем установите ее для отображения при поступлении новых данных. Нажав кнопку, зафиксируйте таблицу, обновите и только затем разрешите пользователю возобновить взаимодействие. Было бы также хорошо визуально пометить добавленные строки.

Это сделает пользовательский интерфейс более понятным для пользователя и одновременно решит вашу аварийную проблему.

Edit01:

Если вы не используете Core Data, для реализации оперативного и невидимого обновления таблицы. необходимо зафиксировать в вызовах - taureView: numberOfRowsInSection или - numberOfSingInTaureView: до вызова - taureView: cellForwAtIndexPath: .

Поскольку сначала вызывается - taureView: numberOfRowsInSection , я бы отправил туда вызов, чтобы сначала обновить, а затем заморозить вашу модель данных. Таким образом, модель данных возвращает необходимое количество разделов и строк.

Я предполагаю, что вам придется разделить вашу модель данных на два раздела, один из которых будет буферизировать входящие данные, а другой - упорядочивать данные для дисплея. Метод обновления должен переместить все завершенные буферизованные данные в раздел отображаемых данных.

Кроме того, вероятно, потребуется установить таймер, если пользователь не перемещает таблицу. Таймер должен вызвать метод обновления, если таблица не обрабатывается активно, и затем принудительно выполнить обновление.

При использовании Core Data можно использовать NSFetingResultController , и его методы делегирования сообщат вам об изменении модели данных. Он должен возвращать соответствующие сведения о разделе и строке, обновленные в реальном времени. В этом пути легко управлять обновленной таблицей. Однакоэто не позволит решить проблему ввода данных в модель так быстро, что модель изменится между вызовами метода. Вам все равно придется заморозить и/или затормозить модель. Однако таймер вам не нужен.

Core Data является вашим лучшим вариантом, но даже в этом случае его будет трудно реализовать, потому что вы пытаетесь что-то сделать против зерна пользовательского интерфейса, и поэтому API не легко его поддерживает.

Обновление:

Оглядываясь на этот ответ, я вижу, что я забыл упомянуть [UITableView beginUpdates] , который заморозит конфигурацию таблицы при добавлении или удалении строк. Для включения изменений в пользовательский интерфейс он объединяется с [UITableView endUpdates] .

-121--1539120-

Я на самом деле удивлен, что никто еще не сказал этого. Я считаю, что на самом деле очень плохо, что все приводят стандарты именования переменных, когда мы говорим о ключах массива, а не переменных.

Функционально, у вас не возникнет проблем с использованием дефисов, подчеркиваний, camelCase в ключах массива. При необходимости можно использовать даже места, новые строки или пустые байты! Это не повлияет на функциональность кода ^.

Ключи массива: int или последовательностей . При использовании в качестве ключа последовательностей он рассматривается как любой другой последовательности в коде.

При построении стандартизированной структуры данных лучше использовать тот же стандарт, который используется для имен переменных.


^ Если не планируется набрать (stdClass) или использовать extract () , в этом случае следует использовать ключи, которые преобразуются в допустимые имена переменных, чтобы избежать использования - > {«Мой ключ»} вместо - > myKeyIs . В этом случае убедитесь, что ключи соответствуют [a-zA-Z _\x7f-\xff] [a-zA-Z0-9 _\x7f-\xff] * .

-121--4561273-

До сих пор много хороших ответов на вопрос, почему 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-летним унаследованным кодом.

Другой для «купить почему!!!», вместе с почему вы не можете группировать по псевдониму ?

2
ответ дан 29 November 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: