Columna calculada en la position incorrecta al usar `SELECT *`

Considere esta consulta que utiliza SELECT * y 'añade' una columna calculada:

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

Esperaría que calculated_col fuera la columna más a la derecha en el set de resultados. Sin embargo, de hecho es la columna más a la izquierda. Es el más adecuado cuando se ejecuta la consulta equivalente en SQL Server, por ejemplo.

Ahora, como se trata de Access (ACE, Jet, lo que sea), los estándares SQL no se aplican y la Ayuda de Access no especificará el resultado esperado porque no es lo suficientemente detallado (por decirlo cortésmente). Entonces mis preguntas son:

¿Siempre se comportó Access de esta manera o es una 'característica' de mi entorno (ADO, proveedor OLE DB, etc.)?

¿El acceso siempre se ha comportado de esta manera en el entorno dado? (es decir, ¿por qué no me he dado count de esto antes?)

PD: Sé por supuesto que SELECT * es ampliamente ridiculizado y que si el order de las columnas es importante para mí, entonces debería escribirlas todas explícitamente. Sin embargo, estaba realmente sorprendido por el comportamiento real encontrado y estoy interesado en cualquier respuesta a mis preguntas.

Aquí hay algunos VBA para reproducir el comportamiento: simplemente copie y pegue en cualquier module de VBA, no es necesario establecer references y no es necesario instalar Access, por ejemplo, use el editor de VBA de Excel:

 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 

De las investigaciones que ya has hecho, parece que estás lleno.

Puede que tenga que hacer reference a las columnas del set de loggings por nombre en lugar de por position.

Cambie su statement de selección a:

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

Al declarar el nombre de la tabla, creo que evita tener que determinar cuál es la tabla pnetworkingeterminada.

El código SQL en la pregunta está proscrito por el estándar SQL: cuando * se usa sin calificación de punto (y sin tener en count el caso especial COUNT(*) ), entonces no pueden aparecer otras columnas.

Esto da una pista sobre la solución: dot-qualified the * !!

por ejemplo, esto funciona como se esperaba, con calculated_column aparece como la columna más a la derecha en el resultado:

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