VC 使用ADO处理大字段BLOB

修改BLOB


// 修改BLOB
void CAdoDlg::OnBnClickedButton2()// 设置BLOB
{
	// TODO:  在此添加控件通知处理程序代码
	CAdo ado;
	ado.InitADOConn();
	CString sql("SELECT * FROM t_USER WHERE LoginID= 'li'");

	ado.OpenRecordset(sql);

	CFile file;
	if (!file.Open(_T("E:/li2.bmp"), CFile::modeRead))
		return;
	const int nLen = file.GetLength();
	BYTE* buf = new BYTE[nLen];
	file.Read(buf, nLen);
	_variant_t varBlob;
	varBlob.vt = VT_ARRAY | VT_UI1;
	SAFEARRAY* pSafeArr = NULL;
	SAFEARRAYBOUND bound;
	bound.cElements = nLen;
	bound.lLbound = 0;
	pSafeArr = SafeArrayCreate(VT_UI1, 1, &bound);
	for (long i = 0; i < nLen; ++i)
	{
		//SafeArrayPutElement(pSafeArr, &i, buf++);//buf改变了后 delete[] buf会出错
		SafeArrayPutElement(pSafeArr, &i, buf + i);
	}
	delete[] buf;
	varBlob.parray = pSafeArr;
	//ado.m_pRecordset->PutCollect("photo", varBlob);
	//Or
	ado.m_pRecordset->GetFields()->GetItem("photo")->AppendChunk(varBlob);
	ado.m_pRecordset->Update();

	ado.UnInitADOConn();
}

查询BLOB / 获取BLOB

// 查询BLOB
void CAdoDlg::OnBnClickedButton1()// 获取BLOB
{
	CAdo ado;
	ado.InitADOConn();
	CString sql("SELECT * FROM t_USER WHERE LoginID= 'li'");
	
	ado.OpenRecordset(sql);

	或者使用
	读取图像字段的实际大小
	//long lDataSize = ado.m_pRecordset->GetFields()->GetItem("DIGITALNAME")->ActualSize;
	从图像字段中读取数据到varBLOB中
	//_variant_t varBLOB;
	//varBLOB = ado.m_pRecordset->GetFields()->GetItem("DIGITALNAME")->GetChunk(lDataSize);

	_variant_t varBlob;
	varBlob = ado.m_pRecordset->GetCollect("photo");
	if ((VT_ARRAY | VT_UI1) == varBlob.vt)
	{
		SAFEARRAY* pSafeArr = varBlob.parray;
		long nLen = pSafeArr->rgsabound[0].cElements;
		BYTE* buf = new BYTE[nLen];
		for (long i = 0; i < nLen; ++i)
		{
			SafeArrayGetElement(pSafeArr, &i, buf + i);
		}
		CFile file;
		if (file.Open(_T("E:/res.bmp"), CFile::modeCreate | CFile::modeWrite))
		{
			file.Write(buf, nLen);
		}
		delete[] buf;
	}
	

	ado.UnInitADOConn();
}

添加 BLOB

CAdo ado;
ado.InitADOConn();
try
{
	ado.OpenRecordset(_T("select * from picture"));//或者“select top 1 * from picture”
	ado.m_pRecordset->AddNew();//添加新行
	
	CFile file (strFilePath,CFile::modeRead);
	DWORD fileLen = file.GetLength();
	char * buffer = new char[fileLen];
	file.Read(buffer,fileLen);
	file.Close();
	VARIANT	 varBlob;
	varBlob.vt= VT_ARRAY|VT_UI1;
	SAFEARRAY* pSafeArr;
	SAFEARRAYBOUND bound;
	bound.cElements = fileLen;
	bound.lLbound = 0;
	pSafeArr = SafeArrayCreate(VT_UI1,1,&bound);
	for(long i=0; i < fileLen ; i++)
	{
		SafeArrayPutElement(pSafeArr, &i, buffer++);
	}	
	varBlob.parray = pSafeArr;
		
	ado.m_pRecordset->GetFields()->GetItem("编号")->Value = (_bstr_t)m_id;
	ado.m_pRecordset->GetFields()->GetItem("姓名")->Value = (_bstr_t)m_name;
	ado.m_pRecordset->GetFields()->GetItem("性别")->Value = (_bstr_t)m_sex;
	ado.m_pRecordset->GetFields()->GetItem("学历")->Value = (_bstr_t)m_knowledge;
	ado.m_pRecordset->GetFields()->GetItem("照片")->AppendChunk(varBlob);
	ado.m_pRecordset->Update();
}
catch(...)
{
	MessageBox("操作失败");
	return;
}
MessageBox("操作成功.");

ado.UnInitADOConn();

获取BLOB(bmp图片)

	CString sql;
	sql.Format("select*from picture where 编号='%s'",m_id);

	CAdo ado;
	ado.InitADOConn();
	ado.OpenRecordset(sql);
	
	HBITMAP m_hBitmap;
	//读取图像字段的实际大小
	long lDataSize = ado.m_pRecordset->GetFields()->GetItem("照片")->ActualSize;
	char *buffer;  //定义缓冲变量
	if(lDataSize > 0)
	{
		//从图像字段中读取数据到varBLOB中
		_variant_t varBLOB;
		varBLOB = ado.m_pRecordset->GetFields()->GetItem("照片")->GetChunk(lDataSize);
		if(varBLOB.vt == (VT_ARRAY | VT_UI1))
		{
			if(buffer = new char[lDataSize+1])	//分配必要的存储空间
			{	
				char *pBuf = NULL;
				SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
				memcpy(buffer,pBuf,lDataSize); ///复制数据到缓冲区buffer
				SafeArrayUnaccessData (varBLOB.parray);
			
				//将数据转换为HBITMAP格式
				LPSTR hDIB;
				LPVOID lpDIBBits;
				BITMAPFILEHEADER bmfHeader;  //用于保存BMP文件头信息,包括类型、大小、位移量等
				DWORD bmfHeaderLen;  //保存文件头的长度
				bmfHeaderLen = sizeof(bmfHeader);  //读取文件头的长度
				//将buffer中文件头复制到bmfHeader中
				strncpy((LPSTR)&bmfHeader, (LPSTR)buffer, bmfHeaderLen); 	
				if (bmfHeader.bfType != (*(WORD*)"BM"))   //如果文件类型不对,则返回
				{
					MessageBox("BMP文件格式不准确");
					return;
				}
				hDIB = buffer + bmfHeaderLen;  //将指针移至文件头后面
				//读取BMP文件的图像数据,包括坐标及颜色格式等信息到BITMAPINFOHEADER对象
				BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB;
				//读取BMP文件的图像数据,包括坐标及颜色格式等信息到BITMAPINFO对象
				BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
				//根据bfOffBits属性将指针移至文件头后
				lpDIBBits = (buffer) + ((BITMAPFILEHEADER *)buffer)->bfOffBits;
				CClientDC dc(this);  //生成一个与当前窗口相关的CClientDC,用于管理输出设置
				//生成DIBitmap数据
				m_hBitmap = CreateDIBitmap(dc.m_hDC,&bmiHeader,CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);
			}
		}
	}
	if(m_hBitmap != NULL)
	{
		CDC* pDC = m_pictureshow.GetDC();
		CRect r;
		m_pictureshow.GetClientRect(&r);
		//将位图选进设备场景中
		CDC memdc;	
		memdc.CreateCompatibleDC( pDC );
		memdc.SelectObject(m_hBitmap);
		BITMAP bmp;
		GetObject(m_hBitmap,sizeof(bmp),&bmp);
		pDC->StretchBlt(r.left,r.top,r.Width(),r.Height(),&memdc,0,0,
				bmp.bmWidth,bmp.bmHeight,SRCCOPY);	
		memdc.DeleteDC();
	}
	ado.UnInitADOConn();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值