ADO访问Oracle结果集的心得

刚接触Oracle一个星期不到, 为了公司的项目勿勿学习了一下Oracle,原以为基本上搞定表空间、模式之类Sql Server用不到的概念,再学会基本的PL SQL语句就Ok了。 用ADO连接Oracle的返回简单数据类型的存储过程也搞得定,心里不禁洋洋得意。我是天才, 我怕谁? 上头说,电信的项目搞得定不?(电信是用Oracle)。我很豪爽地答了句: 没问题! 可一接到电信的存储过程就傻眼了,Package中定义了返回结果集的存储过程,而且包头给你看, 包体却木有。 试了很久, 在csdn上问没人答。也看到一些网上的教程,不管是中文的还是外文的都木有用,这下就郁闷了。
不行, 我得自己建个这样的包试试。包定义是这样的形式:

CREATE   OR   REPLACE  PACKAGE PK_ConsolManager_LoginCheck   AS
/******************************************************************************
   NAME:       PK_ConsolManager_LoginCheck 
   PURPOSE:

   REVISIONS:
   Ver        Date        Author           Description
   ---------  ----------  ---------------  ------------------------------------
   1.0        2005-11-25             1. Created this package.
*****************************************************************************
*/

TYPE T_CURSOR 
IS  REF  CURSOR ;                                                                
  
PROCEDURE  MyProcedure(Param1  IN   NUMBER , Param3 Out  Number , Param2 OUT T_CURSOR);
END  PK_ConsolManager_LoginCheck ;
/

包体定义:

CREATE   OR   REPLACE  PACKAGE BODY PK_ConsolManager_LoginCheck
AS

PROCEDURE  MyProcedure(Param1  IN   NUMBER ,Param3 Out  Number , Param2 OUT T_CURSOR) 
IS  

BEGIN
    
Open  Param2  FOR
    
SELECT  LoginName, Password  from  ConsoleManager  where  SerialRights  =  Param1;
    Param3 :
=  Param1;
END ;

END ;
/

用C# 试试ADO.net访问它,so easy,因为ADO.net有OracleTypes.Cursor类型,马上就可以得到答案!这里顺便提醒用ADO.net的兄弟们,连接字符串不易过长, 要不然会有异常的 :)

再用网上的方法试试,就是把最后一个返回REF Cursor的参数省略,然后执行返回RecordSet的函数试试。

// OracleCursorApp.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"

#include 
<ole2.h>
#include 
<stdio.h>
#include 
"conio.h"

//Function declaration
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ExecuteSql(VOID);
void PrintProviderError(_ConnectionPtr pConnection);

///
//                                                       //
//      Main Function                                    //
//                                                       //
///
void main()
{
    HRESULT  hr 
= S_OK;

    
if(FAILED(::CoInitialize(NULL)))
        
return;

    ExecuteSql();
    
    
//Wait here for the user to see the output.
    printf("/n/n按任意键继续");
    getch();
    ::CoUninitialize(); 
}



///
//                                                       //
//      ExecuteSql Function                              //
//                                                       //
///
VOID  ExecuteSql(VOID)
{

    HRESULT hr 
= S_OK;

    
// Define ADO object pointers.
    
// Initialize pointers on define.
    
// These are in the ADODB::  namespace.
    _RecordsetPtr pRs = NULL; 
    _CommandPtr pCmd 
= NULL;
    _ParameterPtr pPrmParam1 
= NULL;
    _ParameterPtr pPrmParam3 
= NULL;
    _ConnectionPtr pConnection 
= NULL;

    _bstr_t strCnn(
"Provider=OraOLEDB.Oracle;Data Source=Console;User Id=aol;Password=123;");

    _bstr_t strMessage, strAuthorID;

    
int intParam1;
    VARIANT vtParam1;
    VARIANT vtParam3;

    
try
    
{
        
//Open a Connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        hr 
= pConnection->Open(strCnn,"","",adConnectUnspecified);
        pConnection
->CursorLocation = adUseClient;

        
//Open Command Object with one Parameter
        TESTHR(pCmd.CreateInstance(__uuidof(Command)));
        pCmd
->CommandText = "PK_ConsolManager_LoginCheck.MyProcedure";
        pCmd
->CommandType = adCmdStoredProc;

        
//Get parameter value and append parameter
        printf("输入: ");
        scanf(
"%d",&intParam1);

        
//Define Integer/variant.
        vtParam1.vt = VT_I2;
        vtParam1.iVal 
= intParam1;
        pPrmParam1 
= pCmd->CreateParameter("Param1",adInteger,adParamInput,sizeof(int),vtParam1);
        pCmd
->Parameters->Append(pPrmParam1);
        pPrmParam1
->Value  = vtParam1;
        

        vtParam3.vt 
= VT_I2;
        pPrmParam3 
= pCmd->CreateParameter("Param3", adInteger, adParamOutput, sizeof(int), vtParam3);
        pCmd
->Parameters->Append(pPrmParam3);
       
              
        
//Create Recordset by executing the command

        
//printf("%d", pRs->GetRecordCount());
        pCmd->ActiveConnection = pConnection;
        pRs 
= pCmd->Execute(NULL,NULL,adCmdStoredProc);

        _bstr_t  bstrLoginName;
        bstrLoginName 
= pRs->Fields->Item["LoginName"]->Value;
        printf(
"登录名: %s /n", (LPCSTR) bstrLoginName);
        

        vtParam3 
= pCmd->Parameters->Item["Param3"]->Value;
        printf(
"%d", vtParam3.intVal);


    }

    
catch(_com_error &e)
    
{
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        PrintProviderError(pConnection);

        printf(
"/n 源 : %s /n 描述 : %s /n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }


    
if (pRs)
        
if (pRs->State == adStateOpen)
            pRs
->Close();

    
if (pConnection)
        
if (pConnection->State == adStateOpen)
            pConnection
->Close();
}



///
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///

VOID PrintProviderError(_ConnectionPtr pConnection)
{
    
// Print Provider Errors from Connection object.
    
// pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr = NULL;
    
long        nCount = 0;    
    
long        i = 0;

    
if( (pConnection->Errors->Count) > 0)
    
{
        nCount 
= pConnection->Errors->Count;
        
// Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        
{
            pErr 
= pConnection->Errors->GetItem(i);
            printf(
"Error number: %x/n Error Description: %s/n", pErr->Number,(LPCSTR) pErr->Description);
        }

    }

}

再试,得到异常:

输入: 0
Error number: 80040e14
 Error Description: ORA-06550: 第 1 行, 第 7 列:
PLS-00306: 调用 'MYPROCEDURE' 时参数个数或类型错误
ORA-06550: 第 1 行, 第 7 列:
PL/SQL: Statement ignored

 源 : OraOLEDB
 描述 : ORA-06550: 第 1 行, 第 7 列:
PLS-00306: 调用 'MYPROCEDURE' 时参数个数或类型错误
ORA-06550: 第 1 行, 第 7 列:
PL/SQL: Statement ignored


按任意键继续...
网上的方法还是没用,郁闷至极啊!!!
就这样试了N次, 郁闷了N天, 终于有一天人品爆发,我把连接字符串改成:
_bstr_t strCnn("Provider=MSDAORA.1;Data Source=Console;User Id=aol;Password=123;");
结果得答案:
输入: 0
登录名: Jeremy
0

按任意键继续...
成功了~!
真想说句我kao!!!
这就是我用ADO操作Oracle结果集的心得。



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值