为什么在 Oracle SQL 中选择指定列以及所有列都是错误的?

发布于 2024-08-22 12:18:40 字数 514 浏览 4 评论 0原文

假设我有一个 select 语句,

select * from animals

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

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

select is_parent, * from animals

这将返回ORA-00936:缺少表达式

同样的语句在 Sybase 中也可以正常工作,并且我知道您需要向 animals 表添加一个表别名才能使其正常工作(select is_parent, a.* from Animals ani< /code>),但是为什么 Oracle 必须需要一个表别名才能计算出选择?

Say I have a select statement that goes..

select * from animals

That gives a a query result of all the columns in the table.

Now, if the 42nd column of the table animals is is_parent, and I want to return that in my results, just after gender, so I can see it more easily. But I also want all the other columns.

select is_parent, * from animals

This returns ORA-00936: missing expression.

The same statement will work fine in Sybase, and I know that you need to add a table alias to the animals table to get it to work ( select is_parent, a.* from animals ani), but why must Oracle need a table alias to be able to work out the select?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

镜花水月 2024-08-29 12:18:40

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

select is_parent, animals.* from animals;

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

Actually, it's easy to solve the original problem. You just have to qualify the *.

select is_parent, animals.* from animals;

should work just fine. Aliases for the table names also work.

逆蝶 2024-08-29 12:18:40

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

至于即席查询,请为自己准备一个 IDE - SQL Developer、TOAD、PL/SQL Developer 等 - 它允许我们操作查询和结果集,而无需 SQL 扩展。

There is no merit in doing this in production code. We should explicitly name the columns we want rather than using the SELECT * construct.

As for ad hoc querying, get yourself an IDE - SQL Developer, TOAD, PL/SQL Developer, etc - which allows us to manipulate queries and result sets without needing extensions to SQL.

酒绊 2024-08-29 12:18:40

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

类似的问题是:

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;

Good question, I've often wondered this myself but have then accepted it as one of those things...

Similar problem is this:

sql>select geometrie.SDO_GTYPE from ngg_basiscomponent

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

where geometrie is a column of type mdsys.sdo_geometry.

Add an alias and the thing works.

sql>select a.geometrie.SDO_GTYPE from ngg_basiscomponent a;
浅笑依然 2024-08-29 12:18:40

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

另一个是“为什么买!!!”存储桶,以及 为什么不能按别名

Lots of good answers so far on why select * shouldn't be used and they're all perfectly correct. However, don't think any of them answer the original question on why the particular syntax fails.

Sadly, I think the reason is... "because it doesn't".

I don't think it's anything to do with single-table vs. multi-table queries:

This works fine:

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

But this fails:

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

While this works:

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

It might be some historical compatibility thing with 20-year old legacy code.

Another for the "buy why!!!" bucket, along with why can't you group by an alias?

匿名的好友 2024-08-29 12:18:40

alias.* 格式的用例如下:

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

即,选择联接中一个表中的所有列,以及(可选)其他表中的一个或多个列。

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

The use case for the alias.* format is as follows

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

That is, selecting all the columns from one table in a join, plus (optionally) one or more columns from other tables.

The fact that you can use it to select the same column twice is just a side-effect. There is no real point to selecting the same column twice and I don't think laziness is a real justification.

别靠近我心 2024-08-29 12:18:40

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

Select * in the real world is only dangerous when referring to columns by index number after retrieval rather than by name, the bigger problem is inefficiency when not all columns are required in the resultset (network traffic, cpu and memory load).
Of course if you're adding columns from other tables (as is the case in this example it can be dangerous as these tables may over time have columns with matching names, select *, x in that case would fail if a column x is added to the table that previously didn't have it.

长伴 2024-08-29 12:18:40

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

Teradata 是否需要相同的表别名。由于两者都相当古老(也许更好地称其为“成熟”:-) DBMS,这可能是历史原因。

我通常的解释是:不合格的 * 意味着所有内容/所有列,而解析器/优化器只是感到困惑,因为您请求的比所有内容都多

why must Oracle need a table alias to be able to work out the select

Teradata is requiring the same. As both are quite old (maybe better call it mature :-) DBMSes this might be historical reasons.

My usual explanation is: an unqualified * means everything/all columns and the parser/optimizer is simply confused because you request more than everything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文