27

假设我有一个 select 语句。

select * from animals

这给出了表中所有列的查询结果。

现在,如果表的第 42 列animalsis_parent,并且我想在结果中返回它,就在 之后gender,这样我可以更容易地看到它。但我也想要所有其他列。

select is_parent, * from animals

这返回ORA-00936: missing expression

相同的语句在 Sybase 中也可以正常工作,而且我知道您需要向表添加表别名才能animals使其正常工作 ( select is_parent, a.* from animals ani),但为什么Oracle 必须需要表别名才能进行选择?

4

7 回答 7

30

其实很容易解决原来的问题。你只需要限定 *.

select is_parent, animals.* from animals;

应该可以正常工作。表名的别名也有效。

于 2010-02-23T16:09:11.907 回答
2

在生产代码中这样做没有任何好处。我们应该明确命名我们想要的列,而不是使用 SELECT * 构造。

至于临时查询,为自己准备一个 IDE——SQL Developer、TOAD、PL/SQL Developer 等——它允许我们在不需要扩展 SQL 的情况下操作查询和结果集。

于 2010-02-23T04:07:06.077 回答
2

到目前为止,关于为什么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 年前的遗留代码的一些历史兼容性。

另一个为“买为什么!!!” 桶,以及为什么不能按别名分组

于 2010-02-23T14:20:51.187 回答
2

好问题,我自己经常想知道这一点,但后来接受了它作为其中之一......

类似的问题是这样的:

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;
于 2010-02-23T14:25:16.450 回答
1

alias.* 格式的用例如下

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

也就是说,从一个连接中的一个表中选择所有列,以及(可选地)从其他表中选择一个或多个列。

您可以使用它两次选择同一列的事实只是一个副作用。两次选择同一列没有实际意义,我不认为懒惰是一个真正的理由。

于 2010-02-23T03:13:51.947 回答
1

Select *在现实世界中,只有在检索后通过索引号而不是名称来引用列时才危险,更大的问题是当结果集中并不需要所有列(网络流量、cpu 和内存负载)时效率低下。当然,如果您要从其他表中添加列(如本例中的情况,这可能很危险,因为这些表可能会随着时间的推移具有匹配名称的列,select *, x在这种情况下,如果将列 x 添加到以前没有。

于 2010-02-23T08:11:51.587 回答
1

为什么Oracle 必须需要一个表别名才能计算出选择

Teradata 也有同样的要求。由于两者都很老(也许更好地称之为成熟:-) DBMS,这可能是历史原因。

我通常的解释是:不合格的*意思是一切/所有列,解析器/优化器只是因为您要求的不仅仅是一切而感到困惑。

于 2016-04-06T07:30:25.223 回答