目的:把一些文档资料存入SQL SERVER数据库,在需要的时候调出查看。
主要用的方法:
文件操作;
AppendChunk,GetChunk
ShellExecute Me.hwnd, "open", file, vbNullString, vbNullString, SW_SHOWMAXIMIZED'从数据库读出文件后,用相应的应用程序打开文件。表中的相关的主要字段:
    ADORst("BiaoTI").Value = txtbiaoti '给动态集的字段赋值
    ADORst("LeiXing").Value = txtleixing
    Set ADOFld = ADORst("WenJian")'数据类型image
用数据库操作出现了问题:
1.对OFFICE文件,存入后再读出,保存成的文件根本打不开。后来我调试晕了,连读成文件都不成功了。
现在是一从数据段读数据到缓冲,就提示:当前操作使用了错误类型的值,错误处在代码中有标明。
2.换用简单的TXT文件做实验,内容为:
说明.txt
ok?
先看数据库设计_报告
再看具体表结构。
1)整块存入再读出,形成的文件到还有内容,但开头有几个乱码:
 + ok?
先看数据库设计_报告
再看具体表结构。
2)分块存入再读出则全成了乱码
3.在存入数据库的时候,另建了个文件存缓冲读入的数据,形成的这个文件却是对的,和原文件一样的。很郁闷啊,究竟二进制数据在SQL SERVER中存入又读出的过程有什么问题?主要的地方我在代码中用************************标出来了,哪位高人指教一下把?谢谢!
如果有任何帮助资料,请不吝发我邮箱:[email protected],再次感谢!Public Function SaveFileToDB(ByVal Filename As String, dbField As ADODB.Field, _
                                Optional PackageSize As Long = 8192&) As Long
    
    Dim bTemp() As Byte '定义数据块数组
    Dim lngActualSize As Long '标识文件长度
    Dim lChunkRemainder As Long '定义剩余字节长度
    Dim lChunkCount As Long '定义数据块个数
    
    Dim i As Integer
    lngActualSize = FileLen(Filename)
    If lngActualSize <= 0 Then
        Err.Raise ERR_SIZE_EQU_OR_LESS_ZERO, "writeFileToDB"
    End If
    '读取文件内容保存/////////////
    Dim hFile As Long
    hFile = FreeFile()'文件存入数据库!!!!后面通过Getchunk读出为C:\下的同名文件,以备与原文件比较是否正确恢复了*************
    Open Filename For Binary As hFile 
'手工做了个文件c:\shoudong供存入,与上句存入数据库后再读出的文件做比较。*******************************
    Open "c:\shoudong" & ADORst("LeiXing").Value For Binary As #2     '整块写入////////////////////////////////////////
'    ReDim bTemp(lngActualSize - 1)
'    Get hFile, , bTemp '从文件中取出一块
'    dbField.Value = Null
'    dbField.AppendChunk (bTemp)
    '整块写入////////////////////////////////////////
    
    '文件比较大时应分块写入////////////////////////////////////////
    
    dbField.AppendChunk (bTemp)  '将块写入字段中
    lChunkCount = LOF(hFile) \ PackageSize    '取块数
    lChunkRemainder = LOF(hFile) Mod PackageSize
    'If lChunkRemainder > 0 Then lChunkCount = lChunkCount + 1
    ReDim bTemp(PackageSize - 1) '临时存贮块
    For i = 1 To lChunkCount
        Get hFile, , bTemp '从文件中取出一块
        dbField.AppendChunk (bTemp)  '将块写入字段中
        Put #2, , bTemp
    Next
    ReDim bTemp(lChunkRemainder - 1) '临时存贮块
    Get hFile, , bTemp '从文件中取出一块
    dbField.AppendChunk (bTemp)  '将块写入字段中
    Put #2, , bTemp
    '分块写入////////////////////////////////////////
    Close #1
    Close #2
    '读取文件内容保存/////////////
   
    SaveFileToDB = 0
End FunctionPublic Function GetFileFromDB(ByRef dbField As ADODB.Field, vData As Variant, Optional ByVal SaveAs As String = "", _
                                Optional PackageSize As Long = 8192&) As Long
    Dim i%
    Dim lngActualSize As Long '获取的数据库文件数据大小
    Dim lngRemainSize As Long
    Dim lChunkCount As Long '数据块数
    Dim vTemp As Variant, bTemp() As Byte
    Dim hFile As Long    lngActualSize = dbField.ActualSize
    lChunkCount = lngActualSize \ PackageSize
    lngRemainSize = lngActualSize Mod PackageSize
    
    If Trim(SaveAs) = "" Then '未给文件名的,把获取的数据存入一个变体数据类型中
        For i = 1 To lChunkCount
            vTemp = dbField.GetChunk(PackageSize)
            vData = vData & vTemp
        Next
    Else
        hFile = FreeFile() '给出字符串参数的,以其为名保存成文件。
        Open SaveAs For Binary As hFile
        '整块读出///////////////////////////
'        Put #hFile, , dbField.GetChunk(lngActualSize)
        '整块读出///////////////////////////        '分块读出///////////////////////
        'Put #hFile, , dbField.Value '写入文件
        ReDim bTemp(PackageSize - 1)'这里试过bTemp(PackageSize),结果无影响**********************
        For i = 1 To lChunkCount
            bTemp = dbField.GetChunk(PackageSize)'***************************对OFFICE文件出错,TXT文件读成乱码
            Put #hFile, , bTemp '写入文件
        Next
        ReDim bTemp(lngRemainSize - 1)
        bTemp = dbField.GetChunk(lngRemainSize)
        Put #hFile, , bTemp '写入文件
        Close
        ShellExecute Me.hwnd, "open", SaveAs, vbNullString, vbNullString, SW_SHOWMAXIMIZED
    End If    GetFileFromDB = 0
End Function

解决方案 »

  1.   

    试试下面的:
    使用流对象保存和显示图片 
    打开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
      

  2.   

    好帖子,我昨天也和寝室的人讨论,把大文件保存到sql中去的问题,其实保存应该没有问题,但是显示出来可能就不是那么方便.还有统计分析什么的,我觉得更难.希望楼主解决了能给我门分享一下啊
      

  3.   

    原来是一堆学生在讨论。我希望CSDN有更多的专业人士。
      

  4.   

    Leftie给的方式实现正确!谢谢!
    如此简练的代码就解决了,早知道真该变换个方式去实现啊。谢谢Leftie!:)
    残留疑点:
    1.用STREAM写入读出正确,但写在SQL SERVER中的记录不能手动删除:“无法编辑该单元”。查了一下,SQL SERVER对计算得到的一些数据项不能手动操作,不可操作的原理是什么呢?对这些数据是否就只能通过代码操作了?或者,是否有解决的办法?
    2.我还是很想知道我用的GETCHUNK方式操作,问题究竟出在哪里了?对二进制数据在底层的操作问题很想认识清楚,闷~~~。如果不好解释,提供给些资料也是好的。
      

  5.   

    谢谢给出建设性回复的朋友,WAITING MORE,三日后结贴。
      

  6.   

    看了各位的帖子很有收获,我现在要把access数据库中的ole字段中存储到vb的ole控件中,和存储到image控件的性质差不多,但是ole控件怎么用,实在不明白。试着用下面的程序,总是会出错。有懂得吗,帮我看看吧。
       Dim chunksize As Long
       Dim FileNum As Integer  '取文件号。
       Dim filename As String
       
       If Not IsNull(rs.Fields("题目")) Then   'rs是数据记录集
          chunksize = rs.Fields("题目").ActualSize()
          ReDim strbyte(1 To chunksize) As Byte
          strbyte = rs.Fields("题目").GetChunk(chunksize)
            FileNum = FreeFile
       '打开要保存的文件。
          filename = "temp.doc"
          Open filename For Binary As FileNum
          Put #FileNum, 1, strbyte
          Close #FileNum
          Open filename For Binary As FileNum
          ole1.FileNumber = FileNum
          ole1.ReadFromFile FileNum    ‘错误在这句,
                                       ‘实时错误‘31037’
                           ’系统错误&H800401C0(-2147221056) OLESTREAM GET 方法失败
                          
        End If