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)创建表/序列
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();
参考: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);
把字符串类型的数据转换成clob
关键是利用ADO,而且数据类型是BLOB类型
(1)VC++利用ADO如何向Oracle9i存储过程传递元素为BLOB类型数组参数;
(2)Oracle9i存储过程如何返回BLOB字段的定位器;
希望大侠给两个具体的代码例子,谢谢!
1) 你的示例代码即可
2) 无法弄到定位器,不过,可以通过中间过程传递。
你用AdoCommand执行一个中间体:
DECLARE dpBlob BLOB; BEGIN DBMS_LOB.CREATETEMPORARY(dpBlob, False, 0); :tmpBlob := dpBlob; END;
然后将你超过32K的blob值通过tmpBlob传递进来
最后直接将tmpBlob的值送到你要用的存储过程里头去。这好像是一种临时解决方案。