问题描述
如果必须从Excel运行Oracle12C查询,则无法像在Access中那样编写它了。但是将其写入Excel是有意义的,因为我可以直接从VBA模块启动它,而不必在文件之间复制粘贴。
解决方法
查询基本保持不变,部分修改如下:
- 访问使用 collection_table.column 表示法。将其更改为 collection.table.column
- 访问名称别名
table as tbl
:将其删除(或放置table "tbl"
) - Access使用方括号:将其删除(如果名称中有空格,请双引号)
- Access接受日期,例如
#11/22/2020#
。将其更改为TO_DATE('11/22/2020','mm/dd/yyyy')
- 访问权限为
IIf(condition1,true,IIf(condition2,...
。使用CASE WHEN condition1 THEN true WHEN...
下面的代码示例: (复制到新模块中,进入工具,参考... 并选中 Microsoft ActiveX Data Object 6.1 。您需要具有DSN在ODBC连接中定义:其名称,用户名和密码在此处标记为XXXX)
Dim Conn As New ADODB.Connection
Dim recset As New ADODB.Recordset
Dim sqlQry As String
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Data")
sqlQry = "SELECT CASE WHEN CLL1.TBL1.CNY_CD IN ('CH','DE') THEN 'GERMANY' WHEN CLL1.TBL1.CNY_CD IN ('BE','FR') THEN 'WEST' END," _
& "CLL2.TBL2.WND_DATE,ROUND(AVG(ELEM1 + ELEM2),0) " _
& "FROM CLL2.TBL3 INNER JOIN (CLL2.TBL2 INNER JOIN CLL1.TBL1 ON CLL2.TBL2.CTR_NR = CLL1.TBL1.OGZ_NR) ON CLL3.TBL3.OGZ_NR = CLL1.TBL1.OGZ_NR " _
& "WHERE ((CLL3.TBL3 = PLN_DATE - 364) AND (ELEM3 = '0')) " _
& "GROUP BY CASE WHEN CLL1.TBL1.CNY_CD IN ('CH',CLL2.TBL2.WND_DATE " _
& "HAVING ((CLL1.TBL1.CNY_CD In ('BE','CH','DE','FR')) AND (CLL2.TBL2.WND_DATE Between TO_DATE('10/3/2020','mm/dd/yyyy') AND TO_DATE('1/2/2021','mm/dd/yyyy')))"
Conn.ConnectionString = "DSN=XXXX;UID=XXXX;PWD=XXXX;": Conn.CommandTimeout = 0
Conn.Open
recset.Open sqlQry,Conn
ws.Range(ws.Cells(2,1),ws.Cells(ws.Cells(2,1).End(xlDown).Row,9)).ClearContents 'delete previous data
ws.Cells(2,1).CopyFromRecordset recset 'copy data starting from cell A2
recset.Close: Conn.Close
在这种情况下,TRIM,ROUND,AVG和MAX函数在Access和Oracle中具有相同的语法。