请教ODBC API直接存二进制大文件的问题

jianhui323 2007-09-13 10:39:31
大家好,我新来的csdn。多多关照!我用ODBC无邦定的方式连接数据库,然后用ODBC API直接向access数据库里存大文件。但是怎么没存进去阿?请各位高手帮我看看代码:相片(一般1M以上)已经读入到内存了,但是数据库却没有变大,但是在数据库中的photo(OLE类型)字段已经改变了,变成了长二进制数据,如果各位做过的话,会明白我的意思。下面是代码:
CString strFilter = "JPEG文件 (*.jpg)|*.jpg|BMP文件 (*.bmp)|*.bmp|GIF文件 (*.gif)|*.gif||";
CFileDialog fileDialog(true, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter);
CString strPathName;
CString strFileName;
if(fileDialog.DoModal() == IDOK)
{
strPathName = fileDialog.GetPathName();
strFileName = fileDialog.GetFileTitle();

CFile file;
if(!file.Open(strPathName, CFile::modeRead))
{
MessageBox("打开文件失败!", "提示");
return;
}
DWORD fileLength = file.GetLength();
HGLOBAL hMemory = NULL;
if((hMemory = ::GlobalAlloc(GMEM_MOVEABLE, fileLength)) == NULL)
{
MessageBox("创建内存失败", "提示");
return;
}

LPVOID lpBuf = ::GlobalLock(hMemory);
if(file.Read(lpBuf, fileLength) != fileLength)
{
MessageBox("读取文件失败", "提示");
return;
}
////////////////////////////////////////////
SQLHSTMT hsmt;
CDatabase db;
db.Open(this->m_strFileName);
CRecordset rs(&db);
CRecordset* pSet = &rs;
hsmt = pSet->m_hstmt;

//CString strInsert = "insert into jpg (photo) values (?) where id = 26";
CString strInsert = "update jpg set photo = ? where id = 38";//你先看一下数据库,
//把29改成31,31的photo是空的,
//然后插入,数据库变化了!但是不对
SQLPrepare(hsmt, (UCHAR*)strInsert.GetBuffer(strInsert.GetLength()), strInsert.GetLength());

SQLINTEGER cbDeptName = SQL_NTS;

SQLBindParameter(hsmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 5, 0,
lpBuf, 0, &cbDeptName);

SQLPutData(hsmt, lpBuf, fileLength);
SQLExecute(hsmt);

pSet->Close();
db.Close();
::GlobalUnlock(hMemory);
::GlobalFree(hMemory);
}
else
return;

关键是这一块:
CString strInsert = "update jpg set photo = ? where id = 38";//你先看一下数据库,
//把29改成31,31的photo是空的,
//然后插入,数据库变化了!但是不对
SQLPrepare(hsmt, (UCHAR*)strInsert.GetBuffer(strInsert.GetLength()), strInsert.GetLength());

SQLINTEGER cbDeptName = SQL_NTS;

SQLBindParameter(hsmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 5, 0,
lpBuf, 0, &cbDeptName);

SQLPutData(hsmt, lpBuf, fileLength);
SQLExecute(hsmt);
等待高手的解释,先谢谢阿。还有就是请不要说用别的方法实现。就题论题!
...全文
484 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
light_snifer 2011-07-14
  • 打赏
  • 举报
回复
哥们,跪求啊,怎么解决的?
许文君 2011-02-01
  • 打赏
  • 举报
回复
资源版都是N年不结贴的圣斗士啊,不知哪位仁兄挖坟被删了。
jianhui323 2007-09-14
  • 打赏
  • 举报
回复
自己解决了
OracleRoob 2007-09-13
  • 打赏
  • 举报
回复
可能确实有限制。

改用ADO的流操作试试。
wwwwb 2007-09-13
  • 打赏
  • 举报
回复
用ODBC存入BMP文件,大于1M有问题,
http://topic.csdn.net/t/20021017/13/1103044.html
jianhui323 2007-09-13
  • 打赏
  • 举报
回复
呵呵,没用过vb,关键问题就在SQLPutData()这里。
OracleRoob 2007-09-13
  • 打赏
  • 举报
回复

--参考资料:

使用流对象保存和显示图片
打开vb6,新建工程。

添加两个按钮,一个image控件
注意:Access中的photo字段类型为OLE对象.
SqlServer中的photo字段类型为Image

'** 引用 Microsoft ActiveX Data Objects 2.5 Library 及以上版本
‘2.5版本以下不支持Stream对象
Dim iConcstr As String
Dim iConc As ADODB.Connection


'保存文件到数据库中
Sub s_SaveFile()
Dim iStm As ADODB.Stream
Dim iRe As ADODB.Recordset
Dim iConcstr As String

'读取文件到内容
Set iStm = New ADODB.Stream
With iStm
.Type = adTypeBinary '二进制模式
.Open
.LoadFromFile App.Path + "\test.jpg"
End With


'打开保存文件的表
Set iRe = New ADODB.Recordset
With iRe
.Open "select * from img", iConc, 1, 3
.AddNew '新增一条记录
.Fields("photo") = iStm.Read
.Update
End With


'完成后关闭对象
iRe.Close
iStm.Close
End Sub


Sub s_ReadFile()
Dim iStm As ADODB.Stream
Dim iRe As ADODB.Recordset
'打开表
Set iRe = New ADODB.Recordset
‘得到最新添加的纪录
iRe.Open "select top 1 * from img order by id desc", iConc, adOpenKeyset, adLockReadOnly
'保存到文件
Set iStm = New ADODB.Stream
With iStm
.Mode = adModeReadWrite
.Type = adTypeBinary
.Open
.Write iRe("photo")
‘这里注意了,如果当前目录下存在test1.jpg,会报一个文件写入失败的错误.
.SaveToFile App.Path & "\test1.jpg"
End With


Image1.Picture = LoadPicture(App.Path & "\test1.jpg")
'关闭对象
iRe.Close
iStm.Close
End Sub


Private Sub Command1_Click()
Call s_ReadFile
End Sub


Private Sub Command2_Click()
Call s_SaveFile
End Sub


Private Sub Form_Load()
'数据库连接字符串
iConcstr = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False" & _
";Data Source=F:\csdn_vb\database\保存图片\access图片\img.mdb"

‘下面的语句是连接sqlserver数据库的.
‘iConcstr = "Provider=SQLOLEDB.1;Persist Security Info=True;" & _
‘ "User ID=sa;Password=;Initial Catalog=test;Data Source=yang"


Set iConc = New ADODB.Connection
iConc.Open iConcstr
End Sub


Private Sub Form_Unload(Cancel As Integer)
iConc.Close
Set iConc = Nothing
End Sub


jianhui323 2007-09-13
  • 打赏
  • 举报
回复
1.以前用java,30多M的文件放入数据库都没有问题。所以没必要更改我的需求,我就是存文件。
2.ADO我当然会!但是直接用ODBC API就有问题,我想知道问题在哪里?谢谢。请就题论题,不要让我用其他方法!!
wwwwb 2007-09-13
  • 打赏
  • 举报
回复
1、建议只在数据库中存储路径及文件名;
2、向OLE字段中写入数据要用ADO流;
3、具体程序实现请到相应的语言版块去问吧。
jianhui323 2007-09-13
  • 打赏
  • 举报
回复
谦虚可以,前提是你会!!!!!我也没让你回答!!
wwwwb 2007-09-13
  • 打赏
  • 举报
回复
在论坛上,没有人有义务回答你的问题
wwwwb 2007-09-13
  • 打赏
  • 举报
回复
请教问题态度谦虚一点,你的问题确实与ACCESS无关,转到VC版
jianhui323 2007-09-13
  • 打赏
  • 举报
回复
vc的代码不能在这里发吗???你不浪费时间吗?
OracleRoob 2007-09-13
  • 打赏
  • 举报
回复
你这根本就是VC代码的问题,与Access何干?

jianhui323 2007-09-13
  • 打赏
  • 举报
回复
我最讨厌让我改变实现方法。我还不知道用ado能实现?还用你说?

2,586

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 资源
社区管理员
  • 资源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧