Calculated column in wrong position when using `SELECT *`

旧城冷巷雨未停 提交于 2019-12-23 02:16:08

问题


Consider this query that uses SELECT * and 'appends' a calculated column:

SELECT *, 
       IIF(TRUE, 1, 0) AS calculated_col
  FROM Orders;

I would expect calculated_col to be the rightmost column in the resultset. However, it is in fact the leftmost column. It is the rightmost when executing the equivalent query in SQL Server, for example.

Now, because this is Access (ACE, Jet, whatever), the SQL Standards don't apply and the Access Help will not specify the expected result because it is not detailed enough (to put it politely). So my questions are:

Does Access always behaved this way or is it a 'feature' of my environment (ADO, OLE DB provider, etc)?

Has Access always behaved this way in the given environment? (i.e. Why haven't I noticed this before?)

P.S. I know of course that SELECT * is widely derided and that if the order of columns is important to me then I should write them all out explicitly. However, I was genuinely suprised at the actual behaviour encountered and am interested in any answers to my questions.

Here's some VBA to reproduce the behaviour: just copy+paste into any VBA module, no references need to be set and Access need not be installed e.g. use Excel's VBA editor:

Sub ColumnOrderWrong()

  On Error Resume Next
  Kill Environ$("temp") & "\DropMe.mdb"
  On Error GoTo 0

  Dim cat
  Set cat = CreateObject("ADOX.Catalog")
  With cat
    .Create _
        "Provider=Microsoft.Jet.OLEDB.4.0;" & _
        "Data Source=" & _
        Environ$("temp") & "\DropMe.mdb"
    With .ActiveConnection

      Dim Sql As String
      Sql = _
      "CREATE TABLE Orders" & vbCr & _
      "(" & vbCr & " ID INTEGER, " & vbCr & _
      " customer_id" & _
      " INTEGER" & vbCr & _
      ");"
      .Execute Sql

      Sql = _
      "INSERT INTO Orders (ID, customer_id) VALUES" & _
      " (1, 2);"
      .Execute Sql

      Sql = _
      "SELECT *, " & vbCr & _
      "       IIF(TRUE, 55, -99) AS calculated_col" & vbCr & _
      "  FROM Orders;"
      Dim rs
      Set rs = .Execute(Sql)

      MsgBox _
      "Fields(0).Name = " & rs.Fields(0).Name & vbCr & _
      "Fields(1).Name = " & rs.Fields(1).Name & vbCr & _
      "Fields(2).Name = " & rs.Fields(2).Name

    End With
    Set .ActiveConnection = Nothing
  End With
End Sub

回答1:


From the investigations you've already done, it looks like you're stuffed.

You may have to reference the record set's column's by name rather than position.




回答2:


Change your select statement to:

  Sql = _
       "SELECT Orders.*, " & vbCr & _
       "       IIF(TRUE, 55, -99) AS calculated_col" & vbCr & _
       "  FROM Orders;" 

By declaring the table name, I think it prevents having to determine what is the default table.




回答3:


The SQL code in the question is proscribed by the SQL standard: when * is used without dot-qualification (and disregarding the special case COUNT(*)) then no other columns may appear.

This gives a clue to the solution: dot-qualify the * !!

e.g. this works as expected, with calculated_column appearing as the rightmost column in the result:

SELECT Orders.*, 
       IIF(TRUE, 1, 0) AS calculated_col
  FROM Orders;


来源:https://stackoverflow.com/questions/6623207/calculated-column-in-wrong-position-when-using-select

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!