导航
  • 主页
  • VC综合技术
  • 互联网技术
  • MFC AppLauncher
  • .NET 技术
  • 界面
  • 进程
  • 算法
  • 硬件/系统
  • 数据库
  • VC++技术资源

1000分求 ADO 存取oracle blob字段(存jpg图片)的源码!

guojinghe 2002-07-31 10:56:02
急啊! 已到了安装现场,问题还没解决!
...全文
8 点赞 收藏 7
写回复
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
guojinghe 2002-08-02
谢谢各位,现在在网巴,还没来得及试!
回复
akademecia 2002-08-01
用odbc和vc++行不行啊
回复
kingzai 2002-08-01
At times, storing images and other types of documents like word document, or excel spread sheet or even a compressed zip file in the database is inevitable. MFC provides a supporting class to handle these BLOBs called CLongBinary. It is just a wrapper around the HGLOBAL of WIN32. But how do you use it? The wizard creates a member variable of type CLongBinary in your record set object and also creates the corresponding RFX routine (RFX_LongBinary).

Okay, does it mean that you can use this member just like any other variable? No, That's where this document comes in handy. For regular data types, all you have to is create an instance of the recordset object, assign the values and call Update. But for BLOBs, you have to do something special. For inserting BLOBs, you have to remember 3 points.

Allocate and lock the storage buffer using GlobalAlloc() and GlobalLock() calls
Prepare the recordset for blob operation using SetFieldDirty() and SetFieldNull() calls
Unlock the storage buffer

// Store the Image to database table
//
try
{
dbImages.Open();
dbImages.AddNew();

CFile fileImage;
CFileStatus fileStatus;

fileImage.Open("c:\\winnt\\winnt256.bmp", CFile::modeRead);
fileImage.GetStatus(fileStatus);

dbImages.m_BLOBName = fileImage.GetFileTitle();
dbImages.m_BLOBImage.m_dwDataLength = fileStatus.m_size;

HGLOBAL hGlobal = GlobalAlloc(GPTR,fileStatus.m_size);
dbImages.m_BLOBImage.m_hData = GlobalLock(hGlobal);

fileImage.ReadHuge(dbImages.m_BLOBImage.m_hData,fileStatus.m_size);

dbImages.SetFieldDirty(&dbImages.m_BLOBImage);
dbImages.SetFieldNull(&dbImages.m_BLOBImage,FALSE);
dbImages.Update();

GlobalUnlock(hGlobal);

dbImages.Close();

pList->InsertItem(0,fileImage.GetFileTitle());
}
catch(CException* pE)
{
pE->ReportError();
pE->Delete();
return;
}


// To restore image from db table
CdbImages dbImages(&theApp.m_DB);
CString strFileName = pList->GetItemText(nIndex,0);
dbImages.m_strFilter.Format("BLOBName = '%s'",strFileName);
try
{
dbImages.Open();
if (dbImages.IsEOF())
AfxMessageBox("Unable to get image from db");
else
{
char tmpPath[_MAX_PATH+1];
GetTempPath(_MAX_PATH,tmpPath);

strFileName.Insert(0,tmpPath);

CFile outFile(strFileName,CFile::modeCreate|CFile::modeWrite);
LPSTR buffer = (LPSTR)GlobalLock(dbImages.m_BLOBImage.m_hData);
outFile.WriteHuge(buffer,dbImages.m_BLOBImage.m_dwDataLength);
GlobalUnlock(dbImages.m_BLOBImage.m_hData);
outFile.Close();

theApp.OpenDocumentFile(strFileName);
}

dbImages.Close();

}
catch(CException* pE)
{
pE->ReportError();
pE->Delete();
return;
}

回复
winco 2002-08-01
高,up
回复
mfkzj 2002-08-01
ODBC Driver for Oracle
For the current Oracle ODBC Driver from Microsoft:

oConn.Open "Driver={Microsoft ODBC for Oracle};" & _
          "Server=OracleServer.world;" & _
          "Uid=myUsername;" & _
          "Pwd=myPassword;"

For the older Oracle ODBC Driver from Microsoft:

oConn.Open "Driver={Microsoft ODBC Driver for Oracle};" & _
          "ConnectString=OracleServer.world;" & _
          "Uid=myUsername;" & _
          "Pwd=myPassword;"


char *pBuf = m_pBMPBuffer ;

VARIANT varBLOB;

SAFEARRAY *psa;

SAFEARRAYBOUND rgsabound[1];

m_pRecordset->AddNew(); ///添加新记录

m_pRecordset->PutCollect("username",_variant_t("小李")); ///为新记录填充username字段

m_pRecordset->PutCollect("old",_variant_t((long)28); ///填充old字段

if(pBuf){

rgsabound[0].lLbound = 0;

rgsabound[0].cElements = m_nFileLen;

psa = SafeArrayCreate(VT_UI1, 1, rgsabound); ///创建SAFEARRAY对象

for (long i = 0; i < (long)m_nFileLen; i++)

SafeArrayPutElement (psa, &i, pBuf++); ///将pBuf指向的二进制数据保存到SAFEARRAY对象psa中

varBLOB.vt = VT_ARRAY | VT_UI1;///将varBLOB的类型设置为BYTE类型的数组

varBLOB.parray = psa; ///为varBLOB变量赋值 m_pRecordset->GetFields()->GetItem("photo")->AppendChunk(varBLOB); ///加入BLOB类型的数据

}

m_pRecordset->Update(); ///保存我们的数据到库中

至此我们的数据已经成功地保存到了数据库中,接下来我们所要做的工作便是将该数据提取出来,让我们继续吧!

3.2 BLOB数据的读取

对应于保存数据时我们所使用的AppendChunk函数,读取数据应该使用GetChunk函数,GetChunk的原型如下:
_variant_t GetChunk (long Length );
给出数据的长度后GetChunk将返回包含数据的VARIANT类型变量,然后我们可以利用SafeArrayAccessData函数得到VARIANT变量中指向数据的char *类型的指针,以方便我们的处理,具体代码如下:

long lDataSize = m_pRecordset->GetFields()->GetItem("photo")->ActualSize;
///得到数据的长度

if(lDataSize > 0)

{

_variant_t varBLOB;

varBLOB = m_pRecordset->GetFields()->GetItem("photo")->GetChunk(lDataSize);

  if(varBLOB.vt == (VT_ARRAY | VT_UI1)) ///判断数据类型是否正确

  {

  char *pBuf = NULL;

  SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
  ///得到指向数据的指针 /*****在这里我们可以对pBuf中的数据进行处理*****/

  SafeArrayUnaccessData (varBLOB.parray);

  }

}


回复
mfkzj 2002-08-01
我只有vc+access的 要不要
mfkzj@163.com
回复
guojinghe 2002-07-31
要求用Visual C++
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……