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;
}

解决方案 »

  1.   

    我自己用createfile ,readfile,writefile 配合ADO没有出现你的问题你的问题有2个疑点1。你读取文件到内存中,这段你测试数据是没有错误,把内存数据保存到sqlserver这部分由于被封装了,感觉这里有些问题,有可能是写到sql server的时候,数据出现问题你有一个字段记录文件数据。另外一个记录文件大小你可以用select *,datealength([数据字段]),[记录大小的字段] from table检查一下两个值是否一致2,假设写入到SQL Server数据库里数据有错误,实际数据字段的大小小于文件打下,那么在读出的时候,你试图按照记录大小的字段去申请内存,在没有进行填充和清0的时候,该缓冲区应该是debug模式下的CD Cd而读取的数据字段比如10K,填充20K缓冲区,那么后面多的部分就有可能是CD CD...
    当然如果写入数据库的时候,就已经出现CDCD,那么肯定是被封装的写入部分出问题
    仔细检查
    另外,如果要稳定地读写文件,建议使用createfile等API来操作文件