12

我正在使用 ORM (sqlalchemy) 从 PG 数据库中获取数据。我想避免在我手工制作的 SQL 语句中指定所有表列名称*。

到目前为止,我的假设是返回的列按照用于创建数据库表的 DDL 语句的顺序排列。到目前为止,这是可行的——但我想知道这是否只是运气,或者它是否在(ANSI)SQL 规范中得到了具体解决。

即ANSI SQL(因此可能是数据库)是否保证SELECT *语句中返回的列的顺序?

我使用 PostgreSQL 8.4 作为我的后端数据库

  • 是的,我知道将手工制作的 SQL 语句与 ORM 一起使用会破坏 ORM 的目的,但需要必须...
4

1 回答 1

18

7.9 <query specification>让我们考虑这里指定的 SQL 标准部分:

http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

<query specification> ::=
          SELECT [ <set quantifier> ] <select list> <table expression>
[...]
<select list> ::=
            <asterisk>
          | <select sublist> [ { <comma> <select sublist> }... ]

[...]
Syntax Rules
1) Let T be the result of the <table expression>.
3) Case:
       a) [...]
       b) Otherwise, the <select list> "*" is equivalent to a <value
          expression> sequence in which each <value expression> is a
          <column reference> that references a column of T and each
          column of T is referenced exactly once. The columns are ref-
          erenced in the ascending sequence of their ordinal position
          within T.

因此,换句话说,是的,SQL 标准指定要根据它们在T. 请注意,当您<table expression>包含多个涉及JOIN .. USINGorNATURAL JOIN子句的表时,事情会变得有些棘手。但是,当从一个简单的表中进行选择时,假设顺序符合预期,您可能没问题。

ordinal position within T为了完整起见, for 表的含义在下面进一步解释11.4 <column definition>

General Rules
     5) [...] The ordinal position included
        in the column descriptor is equal to the degree of T. [...]

然后在11.11 <add column definition>(for ALTER TABLEstatements)

General Rules
     4) [...] In particular, the degree of T
        is increased by 1 and the ordinal position of that column is
        equal to the new degree of T as specified in the General Rules
        of Subclause 11.4, "<column definition>".

还有相当多的其他 SQL 语句和子句依赖于ordinal positionswithin的正式规范<table expressions>。一些例子:

13.8 <insert statement> 
     (when omitting the `<insert column list>`)
20.2 <direct select statement: multiple rows>
     (when `<sort specification>` contains an `<unsigned integer>`)

尤其是 Postgres,它非常符合标准,所以如果你真的想要SELECT *,请继续!

于 2012-07-31T09:48:11.007 回答