2016-08-23 69 views
2
select banner 
from v$version 
; 


BANNER 
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production 
PL/SQL Release 12.1.0.2.0 - Production 
"CORE 12.1.0.2.0 Production" 
TNS for Solaris: Version 12.1.0.2.0 - Production 
NLSRTL Version 12.1.0.2.0 - Production 

憑藉其12C的釋放工作,甲骨文已經直接在SQL語句的上部加入的功能,允許的PL/SQL函數的聲明(見https://oracle-base.com/articles/12c/with-clause-enhancements-12cr1甲骨文12C:在WITH子句中的函數不與ADODB

這可能是一個非常方便的功能,尤其是,在需要從數據庫中提取數據的項目中,用戶權限限於SELECT語句。

以下(明顯簡化)查詢Oracle SQL Developer中運行良好:

with 
    function add_string(p_string in varchar2) return varchar2 
    is 
    --Function to add a string 
    l_buffer varchar2(32767); 
    begin 
    l_buffer := p_string || ' works!'; 
    -- 
    return l_buffer; 
    -- 
    end ; 
-- 
select add_string('Yes, it') as outVal 
from dual 
; 

--------- 
OUTVAL 
Yes, it works! 

現在,我想結果集基於相同原理的查詢加載到ADODB記錄在MS- Access 2007中。我知道ADO不會無縫處理以WITH子句開頭的查詢(請參閱,例如Why can't I do a "with x as (...)" with ADODB and Oracle?)。我通常解決這個問題得到的方式是封閉的查詢在SELECT塊,像​​這樣:

select hey_yo 
from (
    with sub as (
    select 'hey' as hey 
    from dual 
) 
    select hey || ' yo!' as hey_yo 
    from sub 
) 
; 

--------- 
HEY_YO 
hey yo! 

不幸的是,這似乎並沒有與功能的處理條款時,在甲骨文的法律語法:

select * 
from (
    with 
    function add_string(p_string in varchar2) return varchar2 
    is 
     --Function to add a string 
     l_buffer varchar2(32767); 
    begin 
     l_buffer := p_string || ' works!'; 
     -- 
     return l_buffer; 
     -- 
    end ; 
    -- 
    select add_string('Yes, it') as outVal 
    from dual 
) 
; 

--------- 
PLS-00103: Encountered the symbol ")" when expecting one of the following: 

    . , @ ; for <an identifier> 
    <a double-quoted delimited-identifier> group having intersect 
    minus order partition start subpartition union where connect 
    sample 
06550. 00000 - "line %s, column %s:\n%s" 
*Cause: Usually a PL/SQL compilation error. 

這裏是我想在VBA運行子:

Sub TestSub() 

    Dim conn As ADODB.Connection 
    Dim rs As ADODB.Recordset 

    'Connection details 
    Dim strHostName As String 
    Dim nPortNum As Integer 
    Dim strUser As String 
    Dim strPassword As String 
    Dim strServiceName As String 


    Dim strConnection As String 
    Dim strSQL As String 

    Set conn = New ADODB.Connection 

    '[... set credentials ...] 

    'Open Connection 
    With conn 
     .ConnectionString = "Provider=MSDAORA;" & _ 
     "Data Source=(DESCRIPTION=(ADDRESS_LIST=" & _ 
     "(ADDRESS=(PROTOCOL=TCP)(HOST=" & strHostName & ")(PORT=" & nPortNum & ")))(CONNECT_DATA=(SERVICE_NAME=" & strServiceName & ")));" & _ 
     "User ID=" & strUser & ";Password=" & strPassword & ";" 

     .Open 

    End With 

    Set rs = New ADODB.Recordset 

    strSQL = "WITH FUNCTION add_string(p_string IN VARCHAR2) RETURN VARCHAR2 IS l_buffer VARCHAR2(32767); BEGIN l_buffer := p_string || ' works!'; RETURN l_buffer; END ; SELECT add_string('Yes, it') AS outval FROM dual" 
    rs.Open strSQL, conn, adOpenStatic, adLockReadOnly 

    '[... do stuff with data ...] 
    rs.MoveFirst 
    Debug.Print rs.Fields(0).Value 

    rs.Close 
    Set rs = Nothing 

    conn.Close 
    Set conn = Nothing 

End Sub 

任何想法如何解決這個問題? (不幸的是,編譯DB中的函數不適用於這個特定的項目)。

更新: 我應該提到在運行VBA代碼時,我得到的錯誤:

運行時錯誤3704:當對象是 封閉操作是不允許的。

rs.MoveFirst

+1

你可以嘗試OLE DB Oracle提供:'提供商OraOLEDB.Oracle'的=代替MSDAORA。您可以從這裏下載:[32位Oracle數據訪問組件](http://www.oracle。COM/technetwork /數據庫/窗/下載/ utilsoft-087491.html)。它可能工作,微軟供應商是[棄用](https://msdn.microsoft.com/en-us/library/ms675851%28v=vs.85%29.aspx)年齡 –

+0

@WernfriedDomscheit:恐怕我堅持使用MS驅動程序,客戶端對於軟件下載/安裝非常有限制。 – silentsurfer

+0

也許你有好運氣,oledb提供商已經安裝。 –

回答

3

使用「Oracle提供的OLE DB」,而不是「微軟的OLE DB提供程序的Oracle 」。甲骨文提供商可以從這裏下載:32-bit Oracle Data Access Components (ODAC) and NuGet Downloads

微軟提供商多年來一直是deprecated,它不是進一步發展,不應該再使用。 Oracle提供商的當前版本是12.1,即它應該也支持新的Oracle 12c功能。

連接字符串將Provider=OraOLEDB.Oracle; ...而不是Provider=MSDAORA;...

+0

謝謝,這使我的一天! – silentsurfer

0

不幸的是我無法測試以下,因爲我在我手上只有一個Oracle 11在這裏。

理論上它應該工作。但是,你應該使用ADODB.Command發送SQL,因爲它是馬上到Oracle

試試這個:

Dim strConnection As String 
Dim strSQL As String 

Dim cmdQuery As ADODB.Command 


Set conn = New ADODB.Connection 

'[... set credentials ...] 

'Open Connection 
With conn 
    .ConnectionString = "Provider=MSDAORA;" & _ 
    "Data Source=(DESCRIPTION=(ADDRESS_LIST=" & _ 
    "(ADDRESS=(PROTOCOL=TCP)(HOST=" & strHostName & ")(PORT=" & nPortNum & ")))(CONNECT_DATA=(SERVICE_NAME=" & strServiceName & ")));" & _ 
    "User ID=" & strUser & ";Password=" & strPassword & ";" 

    .Open 

End With 

Set rs = New ADODB.Recordset 

    strSQL = "WITH FUNCTION add_string(p_string IN VARCHAR2) RETURN VARCHAR2 IS l_buffer VARCHAR2(32767); BEGIN l_buffer := p_string || ' works!'; RETURN l_buffer; END ; SELECT add_string('Yes, it') AS outval FROM dual" 

Set cmdQuery = New ADODB.Command 
cmdQuery.ActiveConnection = conn 
cmdQuery.CommandText = strSQL 


With rs 
    .LockType = adLockPessimistic 
    .CursorType = adUseClient 
    .CursorLocation = adUseClient 
    .Open cmdQuery 
End With  

'[... do stuff with data ...] 
+0

感謝您的答案!不幸的是,我得到了同樣的錯誤。 – silentsurfer