2016-08-23 72 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