从访问MySQL导入OLE对象
我在包含产品条目的访问表中有一个表,其中一列具有存储为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可以做到。