Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用“选择”时计算列的位置错误*`_Sql_Ms Access_Vba_Oledb_Ado - Fatal编程技术网

Sql 使用“选择”时计算列的位置错误*`

Sql 使用“选择”时计算列的位置错误*`,sql,ms-access,vba,oledb,ado,Sql,Ms Access,Vba,Oledb,Ado,考虑使用SELECT*并“附加”计算列的查询: SELECT *, IIF(TRUE, 1, 0) AS calculated_col FROM Orders; 我希望computed\u col是结果集中最右边的列。但是,它实际上是最左边的列。例如,在SQL Server中执行等效查询时,它是最右边的 现在,因为这是Access(ACE、Jet等),SQL标准不适用,Access帮助也不会指定预期结果,因为它不够详细(礼貌地说)。因此,我的问题是: Access是否总是以

考虑使用
SELECT*
并“附加”计算列的查询:

SELECT *, 
       IIF(TRUE, 1, 0) AS calculated_col
  FROM Orders;
我希望
computed\u col
是结果集中最右边的列。但是,它实际上是最左边的列。例如,在SQL Server中执行等效查询时,它是最右边的

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

Access是否总是以这种方式运行,或者它是我的环境(ADO、OLE DB提供程序等)的一个“功能”

在给定的环境中,访问是否总是以这种方式进行?(即,为什么我以前没有注意到这一点?)

另外,我当然知道,
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

从你已经做过的调查来看,你好像饱了


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

将select语句更改为:

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

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

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

这为解决方案提供了线索:点限定
*

e、 g.这与预期一样有效,
计算列
显示为结果中最右边的列:

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

我所想到的用法是在另一个SQL结构中使用查询结构,对于这个SQL结构,列顺序很重要,例如逻辑表的
UNION
。记录集只是我用来查看结果的工具。为什么不使用表名而使用*呢?如果你写的是错误的SQL,你会得到不可靠的结果,所以不要写错误的(即不明确的)SQL。在标准SQL中,结果是可预测的、明确的。在Access中,结果甚至没有定义,因此Access IMO是这里的“坏SQL”。如果
FROM
子句中只有一个表,为什么添加表名会对结果产生影响?SQL标准中是否实际定义了列顺序?或者只是除了Jet/ACE之外的所有人都习惯性地使用SELECT的顺序来显示字段?我当然能看出这是多么合乎逻辑,但除非SQL标准定义了它应该如何呈现,否则我认为你在这里站不住脚。@David-W-Fenton:我相信SQL-92规范第7.9节(语法规则3和4)和第7.4节(一般规则案例1b)已经涵盖了它,但我承认我不是100%确定。@David-W-Fenton:试试看。