//pass blob to oracle stored procedure  
//build by masterz 20050227 with VC2003, Windows 2003, Oracle 10g. 
//The tip: user oledb provider string! 
#include "stdafx.h" 
#import "C:\PROGRA~1\COMMON~1\System\ado\msado15.dll" rename( "EOF", "adoEOF" ) 
struct InitOle 

InitOle() { ::CoInitialize(NULL); } 
~InitOle() { ::CoUninitialize(); } 
} _init_InitOle_; 
void PrintProviderError(ADODB::_ConnectionPtr pConnection); void print_properties(LPCTSTR name, ADODB::PropertiesPtr Properties) 

long prop_count = Properties->GetCount(); 
printf("%s property count = %d\n",name,prop_count); 
for(long i=0;i <prop_count;i++) 

printf("%s property [%d]:%s\n",name,i,(LPCSTR)Properties->GetItem(i)->Name); 


int main(int argc, char* argv[]) 

ADODB::_ConnectionPtr Conn1; 
ADODB::_CommandPtr Cmd1; 
ADODB::_ParameterPtr oldParam= NULL; 
ADODB::_ParameterPtr inParam=NULL; 
ADODB::_ParameterPtr blobParam=NULL; 
_variant_t vtEmpty (DISP_E_PARAMNOTFOUND, VT_ERROR); 
_variant_t vtEmpty2 (DISP_E_PARAMNOTFOUND, VT_ERROR); 
_bstr_t bstrConnect="Provider=OraOLEDB.Oracle;Data Source=orcl;User Id=system;Password=oracle;"; 
_bstr_t bstrCreate ( "CREATE OR REPLACE PROCEDURE TEST_BLOB ( " 
"p_USERNAME in CHAR,p_OLD in CHAR,p_PHOTO in BLOB default empty_blob() ) " 
"as " 
"begin " 
"begin " 
"insert into USERPHOTO( " 
"USERNAME,OLD,PHOTO) " 
"values (p_USERNAME,p_OLD,p_PHOTO); " 
"commit; " 
"end; " 
"end TEST_BLOB;" ); 
_bstr_t bstrSP("{CALL TEST_BLOB(?,?,?)}" ); 
try 

_variant_t varOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);  
ADODB::_StreamPtr adostream; 
adostream.CreateInstance(_T("ADODB.Stream")); 
adostream->Type = ADODB::adTypeBinary; 
adostream->Open(varOptional,ADODB::adModeUnknown, ADODB::adOpenStreamUnspecified, _T(""), _T(""));  
adostream->LoadFromFile("C:\\123.jpg"); 
_variant_t vReadTo = adostream->Read(ADODB::adReadAll);  
long blob_size = adostream->GetSize(); 
adostream->Close(); _bstr_t bstrEmpty; 
Conn1.CreateInstance( __uuidof( ADODB::Connection ) ); 
Cmd1.CreateInstance( __uuidof( ADODB::Command ) ); 
Conn1->ConnectionString = bstrConnect; 
Conn1->Open( bstrConnect, bstrEmpty, bstrEmpty, -1 ); 
Conn1->Execute(bstrCreate,NULL,ADODB::adCmdText); 
Cmd1->ActiveConnection = Conn1; 
Cmd1->CommandText = bstrSP; 
Cmd1->CommandType = ADODB::adCmdText; 
Conn1->Properties->Refresh(); 
inParam = Cmd1->CreateParameter(_bstr_t("p_USERNAME"),ADODB::adChar,ADODB::adParamInput,2,_variant_t( "a" )); 
Cmd1->Parameters->Append(inParam); oldParam = Cmd1->CreateParameter(_bstr_t("p_OLD"),ADODB::adChar,ADODB::adParamInput,4,_variant_t( "yes" )); 
Cmd1->Parameters->Append(oldParam); blobParam = Cmd1->CreateParameter(_bstr_t("p_PHOTO"),ADODB::adLongVarBinary,ADODB::adParamInput,blob_size,vReadTo); 
Cmd1->Parameters->Append(blobParam); 
Cmd1->Properties->Refresh(); 
print_properties("Cmd1",Cmd1->Properties); ADODB::PropertyPtr prop = Cmd1->Properties->GetItem("SPPrmsLOB"); 
prop->PutValue(_variant_t(VARIANT_TRUE,VT_BOOL)) ; 
Cmd1->Execute(NULL,NULL,ADODB::adExecuteNoRecords); 
prop = Cmd1->Properties->GetItem("SPPrmsLOB"); 
prop->PutValue(_variant_t(VARIANT_FALSE,VT_BOOL)) ; 
Conn1->Close(); 

catch(_com_error &e) 

_bstr_t bstrSource(e.Source()); 
_bstr_t bstrDescription(e.Description()); 
printf("\nCOM error occurred, Source : %s \n Description : %s \n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription); 
PrintProviderError(Conn1); 

printf("\nprogram end\n"); 
return 0; 

VOID PrintProviderError(ADODB::_ConnectionPtr pConnection) 

ADODB::ErrorPtr pErr = NULL; 
long nCount = 0; 
long i = 0; 
if( (pConnection->Errors->Count) > 0) 

nCount = pConnection->Errors->Count; 
for(i = 0; i  < nCount; i++) 

pErr = pConnection->Errors->GetItem(i); 
printf("\n\t Error number: %x\t%s", pErr->Number, (LPCSTR)pErr->Description); 



上面这个,是可以运行的. 
但我现在多了一个字段, CREATE OR REPLACE PROCEDURE TEST_BLOB ( " 
"p_USERNAME in CHAR,p_OLD in CHAR,p_PHOTO in BLOB default empty_blob(), p_PHOTO1 in BLOB default empty_blob()) 然后我想通过存储过程来插入,第一个 blob是有数据的,但第二个为空,怎么操作? 存储过程已经定死,不能动. blobParam = Cmd1->CreateParameter(_bstr_t("p_PHOTO1"),ADODB::adLongVarBinary,ADODB::adParamInput,blob_size,vReadTo); 
Cmd1->Parameters->Append(blobParam); 
Cmd1->Properties->Refresh(); 
print_properties("Cmd1",Cmd1->Properties); 
应该是这里修改一下,但我把 blob_size 改为0,调用不成功,请大家帮帮忙啊! 
 
 
 
问题点数:100 回复次数:5 显示所有回复显示星级回复显示楼主回复 修改 删除 举报 引用 回复   
  加为好友 
发送私信 
在线聊天
 tabby 
-_-b .. 内存泄漏 
等级:
 发表于:2008-04-23 22:24:401楼 得分:0 
append一个空的数组不行吗?? 
 
修改 删除 举报 引用 回复   
 
 加为好友 
发送私信 
在线聊天
 guojackey 
光棍一条 
等级:
 发表于:2008-04-23 23:11:362楼 得分:0 
已经定死了,必须是blob类型! 
 
修改 删除 举报 引用 回复   
 
 加为好友 
发送私信 
在线聊天
 tabby 
-_-b .. 内存泄漏 
等级:
 发表于:2008-04-24 12:15:363楼 得分:0 
是blob没错,你添加数据的时候,adostream为空不行吗?? 
 
修改 删除 举报 引用 回复   
 
 加为好友 
发送私信 
在线聊天
 guojackey 
光棍一条 
等级:
 发表于:2008-04-24 12:51:474楼 得分:0 
如果是append空的, 会提示 
ORA-24801 illegal parameter value in OCI lob function Cause: One of the parameter values in the OCI LOB function is illegal. Action: Check every parameter in the OCI Lob function call to make sure they are correct. Offsets should be greater than or equal to one. 
 
修改 删除 举报 引用 回复   
 
 加为好友 
发送私信 
在线聊天
 guojackey 
光棍一条 
等级:
 发表于:2008-04-24 13:31:335楼 得分:0 
 调用的存储过程看不到,现在多次测试的情况是很有可能没有default,也就是说,必须要append一个,急死啦! 
加个空的,又报参数错 
 

解决方案 »

  1.   

    解决了一并给分! 
    谢谢!
    http://topic.csdn.net/u/20080423/21/562af837-e366-4fb1-a9d2-7b242ff0e24c.html
      

  2.   

    append的方法
    直接把读的文件改成一个存在的长度为0k的文件,如 123.jpg为ok
    adostream->LoadFromFile("C:\\123.jpg"); 
    _variant_t vReadTo = adostream->Read(ADODB::adReadAll);  
    long blob_size = adostream->GetSize(); 
    ,这样 vReadTo 就为 VT_NULL, blob_size 为0; 此时是不能append的.
    提示如下:
       不正常地定义参数对象。提供了不一致或不完整的信息。" (1)}
    好像看过一个文章,此时要把blob_size 设为1, 然后可以append了.然后运行到下面
    ADODB::PropertyPtr prop = Cmd1->Properties->GetItem("SPPrmsLOB"); 
    prop->PutValue(_variant_t(VARIANT_TRUE,VT_BOOL)) ; 
    Cmd1->Execute(NULL,NULL,ADODB::adExecuteNoRecords); 

       {"ORA-24801: 在 OCI lob 函数中非法的参数值" (1)}
    再如果改为下面这样
    ADODB::PropertyPtr prop = Cmd1->Properties->GetItem("SPPrmsLOB"); 
    prop->PutValue(_variant_t(VARIANT_FALSE,VT_BOOL)) ; 
    Cmd1->Execute(NULL,NULL,ADODB::adExecuteNoRecords); 
    {"ORA-06550: 第 1 行, 第 7 列: 
    PLS-00306: 调用 'TEST_BLOB' 时参数数量或类型错误
    ORA-06550: 第 1 行, 第 7 列: 
    PL/SQL: Statement ignored" (1)}
    ADODB::PropertyPtr prop = Cmd1->Properties->GetItem("SPPrmsLOB"); 
    prop->PutValue(_variant_t(VARIANT_FALSE,VT_BOOL)) ;
    到底是为true还是false,因为如果有2个blob,一个为空,一个不为空!谢谢啊,麻烦您了!
      

  3.   

    不要使用Microsoft ODBC for ORacle,使用Oracle自带的驱动程序,微软的blob字段不能为空
      

  4.   

    #import "C:\PROGRA~1\COMMON~1\System\ado\msado15.dll" rename( "EOF", "adoEOF" )  用的这个,请问怎样使用使用Oracle自带的驱动程序?? 谢谢!