Pergunta

Diga que tenho uma declaração selecionada que vai ..

select * from animals

Isso fornece resultado de consulta AA de todas as colunas da tabela.

Agora, se a 42ª coluna da tabela animals é is_parent, e eu quero devolver isso nos meus resultados, logo depois gender, para que eu possa ver isso mais facilmente. Mas eu também quero todas as outras colunas.

select is_parent, * from animals

Isso retorna ORA-00936: missing expression.

A mesma afirmação funcionará bem em Sybase, e eu sei que você precisa adicionar um alias de tabela ao animals Tabela para fazer funcionar ( select is_parent, a.* from animals ani), mas Por quê O Oracle deve precisar de um apelido de tabela para poder descobrir a seleção?

Foi útil?

Solução

Na verdade, é fácil resolver o problema original. Você só precisa qualificar o *.

select is_parent, animals.* from animals;

deve funcionar bem. Aliases para os nomes de tabela também funcionam.

Outras dicas

Não há mérito em fazer isso no código de produção. Deveríamos nomear explicitamente as colunas que queremos, em vez de usar o construto selecionado *.

Quanto à consulta ad hoc, obtenha um desenvolvedor IDE - SQL, Toad, PL/SQL Developer, etc - que nos permite manipular consultas e conjuntos de resultados sem precisar de extensões para o SQL.

Boa pergunta, eu sempre me perguntei isso, mas então aceitei como uma dessas coisas ...

Problema semelhante é o seguinte:

sql>select geometrie.SDO_GTYPE from ngg_basiscomponent

ORA-00904: "GEOMETRIE"."SDO_GTYPE": invalid identifier

onde geometrie é uma coluna do tipo mdsys.sdo_geometry.

Adicione um pseudônimo e a coisa funciona.

sql>select a.geometrie.SDO_GTYPE from ngg_basiscomponent a;

Muitas boas respostas até agora sobre o porquê select * Não deve ser usado e todos eles estão perfeitamente corretos. No entanto, não pense que nenhum deles responda à pergunta original sobre por que a sintaxe específica falha.

Infelizmente, acho que o motivo é ... "porque não".

Eu não acho que tenha nada a ver com consultas de mesa única vs. multi-tabela:

Isso funciona bem:

select *
from
    person p inner join user u on u.person_id = p.person_id

Mas isso falha:

select p.person_id, *
from
    person p inner join user u on u.person_id = p.person_id

Enquanto isso funciona:

select p.person_id, p.*, u.*
from
    person p inner join user u on u.person_id = p.person_id

Pode ser uma coisa de compatibilidade histórica com o código legado de 20 anos.

Outro para o "Compre por que !!!" balde, junto com Por que você não pode agrupar por um pseudônimo?

O caso de uso para o alias.* O formato é o seguinte

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

Ou seja, selecionando todas as colunas de uma tabela em uma junção, mais (opcionalmente) uma ou mais colunas de outras tabelas.

O fato de você poder usá-lo para selecionar a mesma coluna duas vezes é apenas um efeito colateral. Não há nenhum ponto real para selecionar a mesma coluna duas vezes e não acho que a preguiça seja uma justificativa real.

Select * No mundo real, só é perigoso quando se refere às colunas pelo número de índice após a recuperação, e não pelo nome, o maior problema é a ineficiência quando nem todas as colunas são necessárias no ResultSet (tráfego de rede, CPU e carga de memória). É claro que se você estiver adicionando colunas de outras tabelas (como é o caso neste exemplo, pode ser perigoso, pois essas tabelas podem ter colunas com nomes correspondentes, select *, x Nesse caso, falharia se uma coluna X fosse adicionada à tabela que anteriormente não a tinha.

Por quê O Oracle precisa de um alias de tabela para poder descobrir a seleção

Teradata está exigindo o mesmo. Como ambos são bastante antigos (talvez melhor chame maduro :-) DBMSES Isso pode ser razões históricas.

Minha explicação usual é: um não qualificado * significa tudo/todas as colunas e o analisador/otimizador está simplesmente confuso porque você solicita mais que tudo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top