1. 创建Oracle基本对象:没有错误
(1)创建表/序列
create sequence SCAN_SEQUENCE
minvalue 1
maxvalue 99999999
start with 3801
increment by 1
cache 10;create table SCAN(
  ID          NUMBER(10),
  DATALEN     NUMBER(10),
  DATA        BLOB
);(2)存储过程:
create or replace procedure DataScan(
p_DataLen in NUMBER(10),
p_Data    in BLOB) isvNewID NUMBER;
begin
  select SCAN_SEQUENCE.NEXTVAL into vNewID from DUAL;
  insert
  into MON_DATA_SCANORI(INTERVALID,DATALEN,DATA)
  values(vNewID,p_DataLen,p_Data);
end DataScan;2.VC++利用ADO调用存储过程DataScan:将大二进制数据存到安全数组中,并将此数组指针作为存储过程DataScan的实参,传递到其形参p_Data中,结果执行存储过程报错,请各位大侠帮忙:m_pCommand->ActiveConnection = m_pConnection;
m_pCommand->CommandText=_bstr_t("DataScan");
m_pCommand->CommandType=adCmdStoredProc;

VARIANT vtTemp1;
vtTemp1.vt = VT_R8;
vtTemp1.dblVal = (double)m_pProDataPack->nlen;
_ParameterPtr lPara1= m_pCommand->CreateParameter(_bstr_t("p_DataLen"),adNumeric,adParamInput,10,vtTemp1);
m_pCommand->Parameters->Append(lPara1);VARIANT vtTemp2;
if (m_pProDataPack->pData)
{
//SAFEARRAY的主要目的是用于automation中的数组型参数的传递。
//因为在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray。
//包装一个SafeArray,定义变量
SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[1];
//创建SafeArray描述符
unsigned char *pBuf = m_pProDataPack->pData;
int bufLen = m_pProDataPack->nlen;
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = bufLen;
psa = SafeArrayCreate(VT_UI1, 1, rgsabound); //VT_UI1指示byte
//放置数据元素到SafeArray
for (long i=0;i<bufLen;i++)
{
SafeArrayPutElement(psa,&i,pBuf++);
}
//封装到VARIANT内
vtTemp2.vt = VT_ARRAY | VT_UI1;//VT_ARRAY指示 SAFEARRAY 指针
vtTemp2.parray = psa;
//AppendChunk 用于将数据追加到大的文本或二进制数据 Field 或 Parameter 对象  m_pRecord->Fields->GetItem("OriData")->AppendChunk(vtTemp2);
}
_ParameterPtr lPara2 = m_pCommand->CreateParameter(_bstr_t("p_Data"),adLongVarBinary,adParamInput,
m_pProDataPack->pData,vtTemp2);
m_pCommand->Parameters->Append(lPara2);

m_pCommand->Execute(NULL,NULL,adCmdStoredProc); m_pConnection->Close();

解决方案 »

  1.   

    BLOB,CLOB,Long数据类型的字段是无法直接执行Insert操作的。
    参考:DECLARE
      clob_test CLOB := EMPTY_CLOB;
      len     BINARY_INTEGER;  dbms_lob.createtemporary(clob_test, TRUE);
      dbms_lob.open(clob_test, dbms_lob.lob_readwrite);
      dbms_lob.writeappend(clob_test,len,clob_data);
      

  2.   

    可以试试utl_raw.cast_to_raw('varchar2')
    把字符串类型的数据转换成clob
      

  3.   

    请问 hanks_gao :怎样利用ADO调用Oracle存储过程存储超过32KB的BLOB数据?
    关键是利用ADO,而且数据类型是BLOB类型
      

  4.   

    请问楼主 wcb2003:“”的意思是先给分数,再给答案吗?
      

  5.   

    多谢大侠 iihero 的回复,请问您两个问题:
    (1)VC++利用ADO如何向Oracle9i存储过程传递元素为BLOB类型数组参数;
    (2)Oracle9i存储过程如何返回BLOB字段的定位器;
    希望大侠给两个具体的代码例子,谢谢!
      

  6.   


    1) 你的示例代码即可
    2) 无法弄到定位器,不过,可以通过中间过程传递。
    你用AdoCommand执行一个中间体:
    DECLARE dpBlob BLOB; BEGIN DBMS_LOB.CREATETEMPORARY(dpBlob, False, 0); :tmpBlob := dpBlob; END;
    然后将你超过32K的blob值通过tmpBlob传递进来
    最后直接将tmpBlob的值送到你要用的存储过程里头去。这好像是一种临时解决方案。