restricciones - ¿Por qué es incorrecto seleccionar columnas especificadas, y todas, en Oracle SQL?
restriccion unique sql server (7)
Digamos que tengo una declaración de selección que va ...
select * from animals
Eso da un resultado de consulta de todas las columnas en la tabla.
Ahora, si la 42ª columna de la tabla de animals
es is_parent
, y quiero devolver eso en mis resultados, justo después del gender
, para poder verlo más fácilmente. Pero también quiero todas las demás columnas.
select is_parent, * from animals
Esto devuelve ORA-00936: missing expression
.
La misma declaración funcionará bien en Sybase, y sé que debe agregar un alias de tabla a la tabla de animals
para que funcione ( select is_parent, a.* from animals ani
), pero ¿por qué Oracle necesita un alias de tabla para ser capaz de trabajar en la selección?
¿Por qué Oracle necesita un alias de tabla para poder trabajar en la selección?
Teradata está requiriendo lo mismo. Como ambos son bastante viejos (quizás mejor llamémoslo maduro :-) DBMS, esto podría ser razones históricas.
Mi explicación habitual es: un no calificado *
significa todas / todas las columnas y el analizador / optimizador simplemente se confunde porque solicita más que todo .
Buena pregunta, a menudo me lo he preguntado pero luego lo he aceptado como una de esas cosas ...
Un problema similar es este:
sql>select geometrie.SDO_GTYPE from ngg_basiscomponent
ORA-00904: "GEOMETRIE"."SDO_GTYPE": invalid identifier
donde geometrie es una columna de tipo mdsys.sdo_geometry.
Agrega un alias y la cosa funciona.
sql>select a.geometrie.SDO_GTYPE from ngg_basiscomponent a;
El caso de uso para el formato alias. * Es el siguiente
select parent.*, child.col
from parent join child on parent.parent_id = child.parent_id
Es decir, seleccionando todas las columnas de una tabla en una combinación, más (opcionalmente) una o más columnas de otras tablas.
El hecho de que pueda usarlo para seleccionar la misma columna dos veces es solo un efecto secundario. No hay un punto real para seleccionar la misma columna dos veces y no creo que la pereza sea una justificación real.
En realidad, es fácil resolver el problema original. Solo tienes que calificar el *.
select is_parent, animals.* from animals;
debería funcionar bien Los alias para los nombres de tablas también funcionan.
Muchas buenas respuestas hasta ahora sobre por qué select *
no se debe usar y todas son perfectamente correctas. Sin embargo, no piense que ninguno de ellos responde la pregunta original sobre por qué falla la sintaxis en particular.
Lamentablemente, creo que la razón es ... "porque no lo hace".
No creo que tenga nada que ver con las consultas de tabla única frente a las tablas múltiples:
Esto funciona bien:
select *
from
person p inner join user u on u.person_id = p.person_id
Pero esto falla:
select p.person_id, *
from
person p inner join user u on u.person_id = p.person_id
Mientras esto funciona:
select p.person_id, p.*, u.*
from
person p inner join user u on u.person_id = p.person_id
Podría ser una cuestión de compatibilidad histórica con el código heredado de 20 años.
Otra para el "comprar por qué !!!" cubo, junto con ¿ por qué no puedes agrupar por un alias ?
No hay mérito en hacer esto en el código de producción. Deberíamos nombrar explícitamente las columnas que deseamos en lugar de usar la construcción SELECT *.
En cuanto a las consultas ad hoc, consiga un IDE - Desarrollador SQL, TOAD, Desarrollador PL / SQL, etc., que nos permita manipular consultas y conjuntos de resultados sin necesidad de extensiones a SQL.
Select *
en el mundo real solo es peligroso cuando se hace referencia a columnas por número de índice después de recuperación en lugar de por nombre, el problema más grande es la ineficiencia cuando no se requieren todas las columnas en el conjunto de resultados (tráfico de red, CPU y carga de memoria). Por supuesto, si está agregando columnas de otras tablas (como es el caso en este ejemplo, puede ser peligroso ya que estas tablas pueden tener columnas con nombres coincidentes con el tiempo, select *, x
en ese caso fallaría si se agrega una columna x A la mesa que anteriormente no la tenía.