1.我用ADO向一SQLSERVER数据库中加入一二进制文件到一表中的image类型字段后,用另一个函数再将此字段中的二进制数据导出另存为一外部文件时,发现新保存的文件同导入的源文件长度一致,但导出的文件大约后半部份内容全为十六进制的 CD CD CD ,例如我将一位图文件abc.bmp用一自定义函数LoadFileToBinField导入到数据库后,又用另一函数SaveBinFieldToFile保存到另一位图文件123.bmp后,打开123.bmp文件查看,发现图象的下半部份正常,上半部份为灰色(相当于文件中为CD CD..的内容)
2.我用基本相同的代码的函数对ACCESS数据库进行操作,一切都正确,真是百思不行其解(ACCESS数据库中的以应字段类型为 OLE对象 类型)这4个函数如下,请高手帮忙找原因://将外部文件内容导入到SQLSERVER数据库
//参数:
//CString dbsrc:SQL Server服务器名
//CString dbname:数据库名
//CString user:用户名
//CString pass:密码
//CString tableName:表名
//LONG ID: 要更新表中的关键字段值(一般ID不重复)
//CString idFieldName:ID关键字段名
//CString binFieldName: 长二进制字段名
//CString FileName :外部文件名
//CString sizeField /*=""*/:表中如果有字段大小的字段名,将fileSize值同进写入
//返回文件的大小,返回0表示没成功
LONG CAdoSQL::LoadFileToBinField(CString dbsrc, CString user, CString pass,
CString dbname,CString tableName,
LONG ID, CString idFieldName,
CString binFieldName,
CString FileName, CString sizeFieldName /*=""*/)
{
LONG ReSize = 0;
BOOL b = TRUE;
CString s;
BYTE *pbuf;
CString SqlTxt;
if(!FileExist(FileName))
{
s.Format("文件:'%s'不存在,请重新选择!",FileName);
AfxMessageBox(s);
return 0L;
} //打开文件得到文件二进制内容(不能用CFile类,不知为何总打不开文件)
ifstream infile;
LONG size = GetFileLength(FileName); infile.open(LPCTSTR(FileName), ios::in | ios::binary);
if(infile.is_open())
{
pbuf = new BYTE[size+1];
// memset(pbuf,0,size+1);
infile.read(pbuf,(LONG)size); //经测试pbuf中的内容同加载文件中的内容一样
infile.close();
}
else
return 0L;
CAdoConnection ado; //这两个类为自定义的对ADO封装类
CAdoRecordSet rec; INT count =0;
if(ado.ConnectSQLServer(dbsrc,dbname,user,pass))
{
rec.SetAdoConnection(&ado);
SqlTxt.Format("SELECT %s FROM %s WHERE ID=%d",binFieldName,tableName,ID);
if(rec.Open(SqlTxt, adCmdText))
{
INT count = rec.GetRecordCount();
if(count>=1)
{
rec.MoveFirst();
if (rec.AppendChunk(rec.GetField(binFieldName), pbuf, size))
{
rec.Update();
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
if (pbuf != NULL)
{
delete[] pbuf;
pbuf = NULL;
}
return size;
}
//将SQLSERVER中的长二进制数据字段内容另存为一外部文件
BOOL CAdoSQL::SaveBinFieldToFile(CString dbsrc, CString user, CString pass,
CString dbname,CString tableName,LONG ID, CString idFieldName,
CString binFieldName,
CString FileName,BOOL bIgnoreHasFile/*=TRUE*/)
{
CAdoConnection ado;
CAdoRecordSet rec;
CString SqlTxt;
INT count =0;
if(ado.ConnectSQLServer(dbsrc,dbname,user,pass))
{
rec.SetAdoConnection(&ado);
SqlTxt.Format("SELECT %s FROM %s WHERE ID=%d",binFieldName,tableName,ID);
if(rec.Open(SqlTxt,adCmdText))
{
count = rec.GetRecordCount();
if(count == 1)
{
if(FileExist(FileName))
{
if(!bIgnoreHasFile)
{
CString filePathName,Name,filePath;
if(ShowOpenFileDialog(filePathName,Name,filePath,"","所有文件(*.*)|*.*|","文件已存在,请重新指定文件名"))
FileName = filePathName;
}
} long size = rec.GetFieldActualSize(binFieldName);
if ((adFldLong & rec.GetFieldAttributes(binFieldName)) && size > 0)
{
BYTE *lpData = new BYTE[size+1];
if (rec.GetChunk(rec.GetField(binFieldName), (LPVOID)lpData))
{
//将文件内容写入文件
if(FileExist(FileName))
{
if(!bIgnoreHasFile)
{
CString filePathName,Name,filePath;
if(ShowOpenFileDialog(filePathName,Name,filePath,"","所有文件(*.*)|*.*|","文件已存在,请重新指定文件名"))
FileName = filePathName;
}
} ofstream outfile;
outfile.open(LPCTSTR(FileName), ios::out | ios::binary);
if(outfile.is_open())
{
outfile.write(lpData,size);
outfile.close();
delete[] lpData;
lpData = NULL;
}
else
{
delete[] lpData;
lpData = NULL;
return FALSE;
}
}
else
return FALSE;
}
else
return FALSE;
}
} }
else
TRACE("联接数据库失败\n"); return FALSE;
}
//导入文件内容到ACCESS数据库中的OLE字段中(测试正确)
BOOL CAdoSQL::LoadFileToAccess(CString dbname, CString tableName, LONG ID, CString idFieldName,
CString binFieldName, CString fileName, CString sizeFieldName/*=""*/)
{
CAdoConnection ado;
CAdoRecordSet rec;
CString SqlTxt;
INT count =0;
if(ado.ConnectAccess(dbname))
{
rec.SetAdoConnection(&ado);
SqlTxt.Format("SELECT %s FROM %s WHERE ID=%d",binFieldName,tableName,ID);
if(rec.Open(SqlTxt, adCmdText))//以表名方式打开数据库rec.Open(tableName, adCmdTable);
{
INT count = rec.GetRecordCount();
if(count>=1)
{
rec.MoveFirst();
if (rec.AppendChunk(binFieldName, LPCTSTR(fileName)))
{
rec.Update();
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
return TRUE;}//将二进制字段内容另存到ACCESS数据库中
BOOL CAdoSQL::SaveBinFieldToAccess(CString dbname, CString tableName, LONG ID, CString idFieldName,
CString FieldName, CString FileName, BOOL bIgnoreHasFile/*=TRUE*/)
{
CAdoConnection ado;
CAdoRecordSet rec;
CString SqlTxt;
INT count =0; if(ado.ConnectAccess(dbname))
{
rec.SetAdoConnection(&ado);
SqlTxt.Format("SELECT %s FROM %s WHERE ID=%d",FieldName,tableName,ID);
if(rec.Open(SqlTxt, adCmdText))//以表名方式打开数据库rec.Open(tableName, adCmdTable);
{
INT count = rec.GetRecordCount();
if(count >=1)
{
long size = rec.GetFieldActualSize(FieldName);
if ((adFldLong & rec.GetFieldAttributes(FieldName)) && size > 0)
{
BYTE *lpData = new BYTE[size+1];
if (rec.GetChunk(rec.GetField(FieldName), (LPVOID)lpData))
{ //将文件内容写入文件
if(FileExist(FileName))
{
if(!bIgnoreHasFile)
{
CString filePathName,Name,filePath;
if(ShowOpenFileDialog(filePathName,Name,filePath,"","所有文件(*.*)|*.*|","文件已存在,请重新指定文件名"))
FileName = filePathName;
}
} ofstream outfile;
outfile.open(LPCTSTR(FileName), ios::out | ios::binary);
if(outfile.is_open())
{
outfile.write(lpData,size);
outfile.close();
delete[] lpData;
lpData = NULL;
}
else
{
delete[] lpData;
lpData = NULL;
return FALSE;
} }
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE; return TRUE;
}
2.我用基本相同的代码的函数对ACCESS数据库进行操作,一切都正确,真是百思不行其解(ACCESS数据库中的以应字段类型为 OLE对象 类型)这4个函数如下,请高手帮忙找原因://将外部文件内容导入到SQLSERVER数据库
//参数:
//CString dbsrc:SQL Server服务器名
//CString dbname:数据库名
//CString user:用户名
//CString pass:密码
//CString tableName:表名
//LONG ID: 要更新表中的关键字段值(一般ID不重复)
//CString idFieldName:ID关键字段名
//CString binFieldName: 长二进制字段名
//CString FileName :外部文件名
//CString sizeField /*=""*/:表中如果有字段大小的字段名,将fileSize值同进写入
//返回文件的大小,返回0表示没成功
LONG CAdoSQL::LoadFileToBinField(CString dbsrc, CString user, CString pass,
CString dbname,CString tableName,
LONG ID, CString idFieldName,
CString binFieldName,
CString FileName, CString sizeFieldName /*=""*/)
{
LONG ReSize = 0;
BOOL b = TRUE;
CString s;
BYTE *pbuf;
CString SqlTxt;
if(!FileExist(FileName))
{
s.Format("文件:'%s'不存在,请重新选择!",FileName);
AfxMessageBox(s);
return 0L;
} //打开文件得到文件二进制内容(不能用CFile类,不知为何总打不开文件)
ifstream infile;
LONG size = GetFileLength(FileName); infile.open(LPCTSTR(FileName), ios::in | ios::binary);
if(infile.is_open())
{
pbuf = new BYTE[size+1];
// memset(pbuf,0,size+1);
infile.read(pbuf,(LONG)size); //经测试pbuf中的内容同加载文件中的内容一样
infile.close();
}
else
return 0L;
CAdoConnection ado; //这两个类为自定义的对ADO封装类
CAdoRecordSet rec; INT count =0;
if(ado.ConnectSQLServer(dbsrc,dbname,user,pass))
{
rec.SetAdoConnection(&ado);
SqlTxt.Format("SELECT %s FROM %s WHERE ID=%d",binFieldName,tableName,ID);
if(rec.Open(SqlTxt, adCmdText))
{
INT count = rec.GetRecordCount();
if(count>=1)
{
rec.MoveFirst();
if (rec.AppendChunk(rec.GetField(binFieldName), pbuf, size))
{
rec.Update();
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
if (pbuf != NULL)
{
delete[] pbuf;
pbuf = NULL;
}
return size;
}
//将SQLSERVER中的长二进制数据字段内容另存为一外部文件
BOOL CAdoSQL::SaveBinFieldToFile(CString dbsrc, CString user, CString pass,
CString dbname,CString tableName,LONG ID, CString idFieldName,
CString binFieldName,
CString FileName,BOOL bIgnoreHasFile/*=TRUE*/)
{
CAdoConnection ado;
CAdoRecordSet rec;
CString SqlTxt;
INT count =0;
if(ado.ConnectSQLServer(dbsrc,dbname,user,pass))
{
rec.SetAdoConnection(&ado);
SqlTxt.Format("SELECT %s FROM %s WHERE ID=%d",binFieldName,tableName,ID);
if(rec.Open(SqlTxt,adCmdText))
{
count = rec.GetRecordCount();
if(count == 1)
{
if(FileExist(FileName))
{
if(!bIgnoreHasFile)
{
CString filePathName,Name,filePath;
if(ShowOpenFileDialog(filePathName,Name,filePath,"","所有文件(*.*)|*.*|","文件已存在,请重新指定文件名"))
FileName = filePathName;
}
} long size = rec.GetFieldActualSize(binFieldName);
if ((adFldLong & rec.GetFieldAttributes(binFieldName)) && size > 0)
{
BYTE *lpData = new BYTE[size+1];
if (rec.GetChunk(rec.GetField(binFieldName), (LPVOID)lpData))
{
//将文件内容写入文件
if(FileExist(FileName))
{
if(!bIgnoreHasFile)
{
CString filePathName,Name,filePath;
if(ShowOpenFileDialog(filePathName,Name,filePath,"","所有文件(*.*)|*.*|","文件已存在,请重新指定文件名"))
FileName = filePathName;
}
} ofstream outfile;
outfile.open(LPCTSTR(FileName), ios::out | ios::binary);
if(outfile.is_open())
{
outfile.write(lpData,size);
outfile.close();
delete[] lpData;
lpData = NULL;
}
else
{
delete[] lpData;
lpData = NULL;
return FALSE;
}
}
else
return FALSE;
}
else
return FALSE;
}
} }
else
TRACE("联接数据库失败\n"); return FALSE;
}
//导入文件内容到ACCESS数据库中的OLE字段中(测试正确)
BOOL CAdoSQL::LoadFileToAccess(CString dbname, CString tableName, LONG ID, CString idFieldName,
CString binFieldName, CString fileName, CString sizeFieldName/*=""*/)
{
CAdoConnection ado;
CAdoRecordSet rec;
CString SqlTxt;
INT count =0;
if(ado.ConnectAccess(dbname))
{
rec.SetAdoConnection(&ado);
SqlTxt.Format("SELECT %s FROM %s WHERE ID=%d",binFieldName,tableName,ID);
if(rec.Open(SqlTxt, adCmdText))//以表名方式打开数据库rec.Open(tableName, adCmdTable);
{
INT count = rec.GetRecordCount();
if(count>=1)
{
rec.MoveFirst();
if (rec.AppendChunk(binFieldName, LPCTSTR(fileName)))
{
rec.Update();
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
return TRUE;}//将二进制字段内容另存到ACCESS数据库中
BOOL CAdoSQL::SaveBinFieldToAccess(CString dbname, CString tableName, LONG ID, CString idFieldName,
CString FieldName, CString FileName, BOOL bIgnoreHasFile/*=TRUE*/)
{
CAdoConnection ado;
CAdoRecordSet rec;
CString SqlTxt;
INT count =0; if(ado.ConnectAccess(dbname))
{
rec.SetAdoConnection(&ado);
SqlTxt.Format("SELECT %s FROM %s WHERE ID=%d",FieldName,tableName,ID);
if(rec.Open(SqlTxt, adCmdText))//以表名方式打开数据库rec.Open(tableName, adCmdTable);
{
INT count = rec.GetRecordCount();
if(count >=1)
{
long size = rec.GetFieldActualSize(FieldName);
if ((adFldLong & rec.GetFieldAttributes(FieldName)) && size > 0)
{
BYTE *lpData = new BYTE[size+1];
if (rec.GetChunk(rec.GetField(FieldName), (LPVOID)lpData))
{ //将文件内容写入文件
if(FileExist(FileName))
{
if(!bIgnoreHasFile)
{
CString filePathName,Name,filePath;
if(ShowOpenFileDialog(filePathName,Name,filePath,"","所有文件(*.*)|*.*|","文件已存在,请重新指定文件名"))
FileName = filePathName;
}
} ofstream outfile;
outfile.open(LPCTSTR(FileName), ios::out | ios::binary);
if(outfile.is_open())
{
outfile.write(lpData,size);
outfile.close();
delete[] lpData;
lpData = NULL;
}
else
{
delete[] lpData;
lpData = NULL;
return FALSE;
} }
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE; return TRUE;
}
而用SQLSERVER就会有那问题,那只能是SQLSERVER的字段设置的问题
估计是不是初始大小有问题?
void SaveBinaryInfo(BYTE* info,_RecordsetPtr* recordset,LPCTSTR strFldName,int length)
{
VARIANT varBLOB;
SAFEARRAY* psa;
SAFEARRAYBOUND rgsabound[1];
if (info)
{
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = length;
psa = SafeArrayCreate(VT_UI1,1,rgsabound);
for (long i =0 ; i < length ; i++)
SafeArrayPutElement(psa,&i,info++);
varBLOB.vt = VT_ARRAY | VT_UI1;
varBLOB.parray = psa;
(*recordset)->GetFields()->GetItem(strFldName)->AppendChunk(varBLOB);
SafeArrayDestroy(psa);
}
}这样写文件试下。