不是我不会,而是实在有问题!用ADO方式AppendChunk插入数据库的blob字段(另外两个mediumblob,longblob都试过了)用ODBC 3.51驱动会报错,用ODBC 5.0驱动不报错,但是存储完以后,其它字段正常,blob那个字段为空!再不解决就完蛋了!绝对不是二进制数的长短问题,长的短的我都试过了!!分不够可以加~只要你来回答!

解决方案 »

  1.   

    1、MYSQL版本;
    2、安装ODBC5.1试试;
    3、代码贴出来看看。
      

  2.   

    终于有人回帖,先谢过!_RecordsetPtr MySet;
    MySet.CreateInstance(__uuidof(Recordset));
    SOpen.Format("SELECT * FROM test_data ");
    MySet->Open(_bstr_t(SOpen),_variant_t((IDispatch*)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdText);
    VARIANT varBLOB;
    SAFEARRAY *psa;
    SAFEARRAYBOUND rgsabound[1];
    MySet->AddNew(); ///添加新记录
    if(buffer)//要保存的数据都在buffer[]里
    {
    try
    {   rgsabound[0].lLbound = 0;
        rgsabound[0].cElements = 12020;
        psa = SafeArrayCreate(VT_UI1, 1, rgsabound); ///创建SAFEARRAY对象
        for (long i = 0; i < 12020; i++)
    SafeArrayPutElement (psa, &i, buffer++); ///将buffer指向的二进制数据保存到SAFEARRAY对象psa中
        varBLOB.vt = VT_ARRAY | VT_UI1; ///将varBLOB的类型设置为BYTE类型的数组
        varBLOB.parray = psa; ///为varBLOB变量赋值
        HRESULT   hr; 
        hr=MySet->Fields->GetItem("data")->AppendChunk(varBLOB);///加入BLOB类型的数据
        if(SUCCEEDED(hr)) 
        AfxMessageBox("ok");
        }
        catch(_com_error   &e) 
        { 
            dump_com_error(e); 
            return   FALSE; 
        } 
                        
        }
    MySet->PutCollect("file_name",_variant_t(record.FileName));
        MySet->PutCollect("test_date",_variant_t(record.Date));
        MySet->PutCollect("switch_id",_variant_t(Switch_ID));
        MySet->PutCollect("test_type",_variant_t(record.Type));
        MySet->PutCollect("time",_variant_t(record.Time));
        MySet->Update(); //到这行就出错了
        MySet->Close();///关闭记录集
                    
        }我现在用的是MySQL5.2,看到已经有MySQL6.0了,但是下下来用好像原来那个GUI跟它有些不配,在导入表以后删除添加记录都会报错“no database selected”不知道是不是版本原因。
      

  3.   

    会报错“no database selected”不知道是不是版本原因。
    没有选择数据库,与版本没有多大关系吧
      

  4.   

    是在那个MySQL的GUI界面里,直接在那个table里添加啊,怎么会没有选择数据库啊?
      

  5.   

    这个不是问题啦,主要问题是在语言中要插二进制数据到数据库中,blob字段一直为空。上面说的“no database selected”错误是在mySQL中的,跟程序无关,现在已经好了。
      

  6.   

    OK,下一个问题,BLOB中插入的内容是什么?图片、WORD、EXCEL文件?
      

  7.   

    是我们自己定义的数据文件,后缀为.bin,里面放的其实是12020个byte型数据,二进制数。之前用access数据库的时候,一切正常,换成MySQL才这样blob字段存不进去
      

  8.   

    对了,上面说错,我的驱动就是ODBC5.1
      

  9.   

    是ADO+MYODBC吗?可能是MYODBC的BUG,或不支持ADO这种UPDATE
    换成直接用参数化的INSERT 语句 INSERT INTO 。。 VALUES (?)吧ADO的UPDATE内部有个复杂的过程,虽然最后的结果也是映射到以上INSERT语句,但中间还有很多流程,只要有一环节出了毗漏,最后结果就会出错。如果要看到底哪个环节出问题,trace一下odbc吧
      

  10.   

    是ADO+MYODBC吗?可能是MYODBC的BUG,或不支持ADO这种UPDATE
    换成直接用参数化的INSERT 语句 INSERT INTO 。。 VALUES (?)吧ADO的UPDATE内部有个复杂的过程,虽然最后的结果也是映射到以上INSERT语句,但中间还有很多流程,只要有一环节出了毗漏,最后结果就会出错。如果要看到底哪个环节出问题,trace一下odbc吧
      

  11.   

    我也觉得肯定是不支持ADO的UPDATE,直接用参数化的INSERT 语句 INSERT INTO 。。 VALUES (?),这个二进制的VALUE我要怎么给它赋值呢?谢谢!
      

  12.   

    呵呵,还是被我自己解决了!!难道我是高手了不成??其实早就注意到了,在网上的文章中看到过,自己也试过,可是没成功,就是在插blob字段前,先要给它插空,然后再打开记录集修改blob字段,就可以插进去了,这就是为什么很多人往blob里面插数据总是显示NULL的原因了!!RecordsetPtr MySet;
    MySet.CreateInstance(__uuidof(Recordset));
    SOpen.Format("SELECT * FROM test_data ");
    MySet->Open(_bstr_t(SOpen),_variant_t((IDispatch*)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdText);
    VARIANT varBLOB;
    SAFEARRAY *psa;
    SAFEARRAYBOUND rgsabound[1];
    MySet->AddNew(); ///添加新记录
    MySet->PutCollect("file_name",_variant_t(record.FileName));
    MySet->PutCollect("test_date",_variant_t(record.Date));
    MySet->PutCollect("switch_id",_variant_t(Switch_ID));
    MySet->PutCollect("test_type",_variant_t(record.Type));
    MySet->PutCollect("time",_variant_t(record.Time));
    MySet->Update(); 
    MySet->Close();///关闭记录集);//第一遍不要管那个blob字段
    MySet.CreateInstance(__uuidof(Recordset)););//第二遍再往blob字段插入数据SOpen.Format("SELECT * FROM test_data ");
    MySet->Open(_bstr_t(SOpen),_variant_t((IDispatch*)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdText);if(buffer)//要保存的数据都在buffer[]里
    {
    try
    {   rgsabound[0].lLbound = 0;
        rgsabound[0].cElements = 12020;
        psa = SafeArrayCreate(VT_UI1, 1, rgsabound); ///创建SAFEARRAY对象
        for (long i = 0; i < 12020; i++)
    SafeArrayPutElement (psa, &i, buffer++); ///将buffer指向的二进制数据保存到SAFEARRAY对象psa中
        varBLOB.vt = VT_ARRAY | VT_UI1; ///将varBLOB的类型设置为BYTE类型的数组
        varBLOB.parray = psa; ///为varBLOB变量赋值
        HRESULT   hr; 
        hr=MySet->Fields->GetItem("data")->AppendChunk(varBLOB);///加入BLOB类型的数据
        if(SUCCEEDED(hr)) 
        AfxMessageBox("ok");
        }
        catch(_com_error   &e) 
        { 
            dump_com_error(e); 
            return   FALSE; 
        } 
                        
        }                
        }
      

  13.   

    呵呵,还是被我自己解决了!!难道我是高手了不成??其实早就注意到了,在网上的文章中看到过,自己也试过,可是没成功,就是在插blob字段前,先要给它插空,然后再打开记录集修改blob字段,就可以插进去了,这就是为什么很多人往blob里面插数据总是显示NULL的原因了!!RecordsetPtr MySet;
    MySet.CreateInstance(__uuidof(Recordset));
    SOpen.Format("SELECT * FROM test_data ");
    MySet->Open(_bstr_t(SOpen),_variant_t((IDispatch*)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdText);
    VARIANT varBLOB;
    SAFEARRAY *psa;
    SAFEARRAYBOUND rgsabound[1];
    MySet->AddNew(); ///添加新记录
    MySet->PutCollect("file_name",_variant_t(record.FileName));
    MySet->PutCollect("test_date",_variant_t(record.Date));
    MySet->PutCollect("switch_id",_variant_t(Switch_ID));
    MySet->PutCollect("test_type",_variant_t(record.Type));
    MySet->PutCollect("time",_variant_t(record.Time));
    MySet->Update(); 
    MySet->Close();///关闭记录集);//第一遍不要管那个blob字段
    MySet.CreateInstance(__uuidof(Recordset)););//第二遍再往blob字段插入数据SOpen.Format("SELECT * FROM test_data ");
    MySet->Open(_bstr_t(SOpen),_variant_t((IDispatch*)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdText);if(buffer)//要保存的数据都在buffer[]里
    {
    try
    {   rgsabound[0].lLbound = 0;
        rgsabound[0].cElements = 12020;
        psa = SafeArrayCreate(VT_UI1, 1, rgsabound); ///创建SAFEARRAY对象
        for (long i = 0; i < 12020; i++)
    SafeArrayPutElement (psa, &i, buffer++); ///将buffer指向的二进制数据保存到SAFEARRAY对象psa中
        varBLOB.vt = VT_ARRAY | VT_UI1; ///将varBLOB的类型设置为BYTE类型的数组
        varBLOB.parray = psa; ///为varBLOB变量赋值
        HRESULT   hr; 
        hr=MySet->Fields->GetItem("data")->AppendChunk(varBLOB);///加入BLOB类型的数据
        if(SUCCEEDED(hr)) 
        AfxMessageBox("ok");
        }
        catch(_com_error   &e) 
        { 
            dump_com_error(e); 
            return   FALSE; 
        } 
                        
        }                
        }
      

  14.   


    检查编码格式。 BLOB显示的时候会以字符形式显示出来。
      

  15.   

    用ADO的command对象和parameters对象可以进行执行参数化的插入语句如果还有问题我觉得是APPENDTRUNK的问题,或者是用法不对不用appendtrunk行不行,ADO 允许使用 Value 属性设置和返回长二进制的数据。
      

  16.   

    我也觉得问题出在appendtrunk上面,但是不用appendtrunk我不是很懂,应该怎么存呢?
      

  17.   

    怎么用ADO的command对象和parameters对象进行执行参数化的插入语句 呢?
      

  18.   

    终于解决了,
    MySQL5.1参考手册
    26.1.12.2. 无论何时,当我使用AppendChunk()或GetChunk() ADO方法时,遇到错误“多步操作导致错误,请检查每个状态值”
    将光标位置指定为adUseServer时,ADO的GetChunk()和AppendChunk()方法不能按预期的方式工作。从另一方面上讲,可使用adUseClient克服该问题。原来答案就一直在离我咫尺的地方,我却找了那么久,众里寻它千百度,蓦然回首唉,要好好反省
      

  19.   

    我在给它插空时,执行到Myset->update();时就出错了,不知为什么啊?
      

  20.   

    我在给它插空时,执行到Myset->update();时就出错了,不知为什么啊?