从访问MySQL导入OLE对象

时间:2020-03-05 18:47:00  来源:igfitidea点击:

我在包含产品条目的访问表中有一个表,其中一列具有存储为OLE对象的jpg图像。我正在尝试将此表导入MySQL,但似乎没有任何效果。我已经尝试使用MySQL迁移工具,但是Access和OLE对象存在一个已知问题。 (问题是它无法正常工作,并将字段留空)我也在此网站上尝试了建议
在导入数据的同时,图像似乎在传输中已损坏。当我尝试预览图像时,我只是得到了一个二进制视图,如果我将其以jpg图像的形式保存在磁盘上并尝试打开它,则会收到错误消息,指出该图像已损坏。

Access中的图像很好,可以预览。 Access将数据存储为OLE对象,当我将其导入MySql时,它将保存在MediumBlob字段中。

以前有没有人遇到过这个问题,他们是如何解决的?

解决方案

回答

据我所知,Microsoft"用于Access的SQL Server迁移助手"将正确迁移OLE映像,但这仅用于Access-> SQLServer。但是,我们可以使用此方法迁移到SQLServer Express(免费下载),然后从SQLServer迁移到MySQL。

回答

好吧,为了在这里公开发布我的肮脏代码,我想出了什么。
注意:这是一种旨在仅使用一次然后被丢弃的hack。

此方法从访问表中获取一个包含1行数据的datarowview。图像包装在OLE序列化中,我并不完全熟悉它的工作原理,但是Microsoft应用程序如何将任何对象嵌入到其他对象中。 (例如,将图像导入Excel单元格)。我需要删除图像周围的序列化垃圾,因此我将整个字段加载为Byte数组,并在其中搜索3个并发条目(FF D8 FF),这些条目表示该字段中图像数据的开始。

Private Function GetImageFromRow(ByRef row As DataRowView, ByVal columnName As String) As Bitmap
    Dim oImage As Bitmap = New Bitmap("c:\default.jpg")
    Try
        If Not IsDBNull(row(columnName)) Then
            If row(columnName) IsNot Nothing Then
                Dim mStream As New System.IO.MemoryStream(CType(row(columnName), Byte()))
                If mStream.Length > 0 Then

                    Dim b(Convert.ToInt32(mStream.Length - 1)) As Byte
                    mStream.Read(b, 0, Convert.ToInt32(mStream.Length - 1))

                    Dim position As Integer = 0

                    For index As Integer = 0 To b.Length - 3
                        If b(index) = &HFF And b(index + 1) = &HD8 And b(index + 2) = &HFF Then
                            position = index
                            Exit For
                        End If
                    Next

                    If position > 0 Then
                        Dim jpgStream As New System.IO.MemoryStream(b, position, b.Length - position)
                        oImage = New Bitmap(jpgStream)
                    End If
                End If
            End If
        End If
    Catch ex As Exception
        Throw New ApplicationException(ex.Message, ex)
    End Try
    Return oImage
End Function

然后,将这些数据提取到位图中就成为问题了。因此,对于访问表中的每一行,我提取位图,然后更新相应的MySQL条目。
它工作正常,但我想我本可以以更好的方式删除序列化的东西,也许有一个API可以做到。