Импорт OLE-объекта из Access в MySQL
-
09-06-2019 - |
Вопрос
У меня есть таблица в таблице access, которая содержит записи о продукте, в одном из столбцов есть изображение jpg, сохраненное как OLE-объект.Я пытаюсь импортировать эту таблицу в MySQL, но, похоже, ничего не работает.Я пробовал инструмент миграции MySQL, но у него известная проблема с объектами Access и OLE.(Проблема в том, что это не работает и оставляет поля пустыми) Я также попробовал это предложение на этот сайт и хотя данные импортируются, кажется, что изображение повреждается при передаче.Когда я пытаюсь просмотреть изображение, я просто получаю двоичный вид, если я сохраняю его на диске в виде изображения в формате jpg и пытаюсь открыть его, я получаю сообщение об ошибке, указывающее, что изображение повреждено.
Изображения в Access в порядке, и их можно просмотреть предварительно.Access хранит данные в виде OLE-объекта, и когда я импортирую их в MySQL, они сохраняются в поле MediumBlob.
Сталкивался ли кто-нибудь с этой проблемой раньше и как они ее решали?
Решение 2
Хорошо, итак, в интересах публичного показа моего грязного кода приведу здесь то, что я придумал.
Примечание :это хак, предназначенный для того, чтобы его использовали один раз, а затем выбросили.
Этот метод принимает datarowview, содержащий 1 строку данных из таблицы access.Изображения обернуты в OLE-сериализацию, я не совсем знаком с тем, как это работает, но это то, как приложения Microsoft позволяют любому объекту быть встроенным во что-то другое.(например, изображения в ячейки Excel).Мне нужно было удалить мусор сериализации вокруг изображения, поэтому я загрузил все поле в виде массива байтов и искал в нем 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
Затем остается только преобразовать эти данные в растровое изображение.Таким образом, для каждой строки в таблице access я извлекаю растровое изображение, а затем обновляю соответствующую запись MySQL.
Это сработало нормально, но я предполагаю, что я мог бы удалить материал с сериализацией лучшим способом, возможно, есть API для этого.
Другие советы
Насколько я помню, Microsoft "Помощник по миграции SQL Server для доступа" будет правильно перенесен OLE-образ, но это только для Access-> SQLServer.Однако что вы можете сделать, так это использовать это для миграции на SQLServer Express (скачать бесплатно), а затем выполнить миграцию с SQLServer на MySQL.
Есть также олефильд - Модуль Python для извлечения данных из полей OLE-объекта в Access.Я успешно извлек с его помощью BMP-файлы.Вероятно, это могло бы работать с изображениями в формате jpeg, но я еще не пробовал.