使用`SELECT *`时计算列位置错误

时间:2011-07-08 10:31:03

标签: sql ms-access vba oledb ado

考虑使用SELECT *和'追加'计算列的此查询:

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

我希望calculated_col成为结果集中最右边的列。但是,它实际上是最左边的列。例如,在SQL Server中执行等效查询时,它是最右边的。

现在,因为这是Access(ACE,Jet,等等),SQL标准不适用,并且Access帮助不会指定预期的结果,因为它不够详细(礼貌地说)。所以我的问题是:

Access是否总是以这种方式运行,还是我的环境(ADO,OLE DB提供商等)的“功能”?

Access是否始终在给定环境中以这种方式运行? (也就是为什么我之前没有注意到这一点?)

P.S。我当然知道SELECT *被广泛嘲笑,如果列的顺序对我很重要,那么我应该明确地写出它们。但是,我对所遇到的实际行为感到非常惊讶,并对我的问题的任何答案感兴趣。

这里有一些重现行为的VBA:只需复制+粘贴到任何VBA模块,不需要设置引用,也不需要安装Access,例如使用Excel的VBA编辑器:

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

3 个答案:

答案 0 :(得分:2)

将您的select语句更改为:

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

通过声明表名,我认为它可以防止必须确定什么是默认表。

答案 1 :(得分:1)

问题中的SQL代码被SQL标准禁止:当使用*而没有点限定(并忽略特殊情况COUNT(*))时,则不会出现其他列。

这给出了解决方案的线索:点* !!

e.g。这可以按预期工作,calculated_column显示为结果中最右边的列:

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

答案 2 :(得分:0)

从你已经完成的调查中,看起来你已经塞满了。

您可能必须按名称而不是位置来引用记录集的列。