Excel это не сложно
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
19.04.2024, 13:04:34

Войти
Хотите поблагодарить участника за дельный совет? Нажмите [Повысить]. Так вы заслуженно поднимите репутацию активному участнику.
33 242 Сообщений в 5 457 Тем от 6 758 Пользователей
Последний пользователь: Сергей2662
*
Перейти на сайт Хитрости Надстройка MulTEx Обучающие тренинги Наша группа ВКонтакте
Правила форума Начало Помощь Поиск Календарь Войти Регистрация Выйти
+  Excel это не сложно
|-+  Основные форумы
| |-+  Вопросы по Excel и VBA
| | |-+  Обрезается текст при передаче строки в MySQL с помощью ADODB
Страниц: [1]   Вниз
Печать
Автор Тема: Обрезается текст при передаче строки в MySQL с помощью ADODB  (Прочитано 3560 раз)
0 Пользователей и 1 Гость смотрят эту тему.
McConst
Постоялец
***

Репутация: +1/-0
Офлайн Офлайн

Сообщений: 238


Просмотр профиля E-mail
« : 15.09.2019, 10:17:23 »

Добрый день.
Написал скрипт для копирования данных из таблицы Access в таблицу MySQL. Структура таблиц и там и там одинакова. Сначала я всю таблицу Access переношу в массив типа Variant, из которого построчно беру данные и заполняю c помощью метода CopyRecord записи в MySQL. Сам CopyRecord просто создает Adodb.Command, которая вызывает хранимую процедуру SetRecord из MySQL и передаёт туда поля в виде параметров. В целом код рабочий и выглядит вот так

Код: (vb)

Public Sub CopyRecord(AccessArrayRecordNum As Long, AccessArrayTable As Variant)
'Заполнить строку в базе данных входящими параметрами
'AccessArrayTable - таблица данных из Access
'AccessArrayRecordNum - порядковый номер строки из базы данных Access, для которого выполнется запись в MySQL

Dim Command As Object

Set Command = CreateObject("ADODB.Command")
Set Command.ActiveConnection = Conn
Command.CommandType = 4 'Процедура
Command.NamedParameters = False 'Параметры поименованные
Command.commandtext = "SetRecord" 'Хранимая процедура на добавление или обновление записи в таблицу

Command.Parameters.Append Command.CreateParameter("varID", 19, 1) 'Создаем параметр adUnsignedInt(19), 1-входной
With Command.Parameters("varID")
    .Value = AccessArrayTable(0, AccessArrayRecordNum)
End With

Command.Parameters.Append Command.CreateParameter("varPayment", 17, 1) 'Создаем параметр adUnsignedTinyInt(17), 1-входной
With Command.Parameters("varPayment")
    .Value = CByte(AccessArrayTable(1, AccessArrayRecordNum))
End With

Command.Parameters.Append Command.CreateParameter("varAnalyse_Date", 133, 1) 'Создаем параметр adDBDate(133), 1-входной
With Command.Parameters("varAnalyse_Date")
    .Value = AccessArrayTable(2, AccessArrayRecordNum)
End With

Command.Parameters.Append Command.CreateParameter("varNotes", 129, 1, 254) 'Создаем параметр adChar(129), 1-входной
With Command.Parameters("varNotes")
    If IsNull(AccessArrayTable(21, AccessArrayRecordNum)) Then
        .Value = ""
    Else
        .Value = AccessArrayTable(21, AccessArrayRecordNum)
    End If
End With

Command.Execute
Set Command = Nothing

End Sub

Приведенная процедура является методом моего класса для работы с базой данных. В самом начале для соединения с MySQL используется объект Conn, который инициализируется в методе OperDB:
Код: (vb)

Public Sub OpenDB()
'Открыть соединение с базой данных на сайте
'Для успешной работы объекта предварительно требуется инсталляция ODBC MySQL Connector Driver
'Драйвер скачивается https://dev.mysql.com/downloads/connector/odbc/
'Для офиса 2003 разрядность драйвера 32bit не зависимо от разрядности Windows
'Правильное название драйвера при проиписывании строки-коннекта можно
'найти после инсталляции в ветке реестра
'HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers\

Dim ConnString ' Строка для коннекта
Dim Driver As String

Driver = "DRIVER={MySQL ODBC 8.0 Unicode Driver}" 'Драйвер для коннекта. Имя/версию драйвера приписать в фигурных скобках
Set Conn = CreateObject("ADODB.Connection")

ConnString = Driver & ";" & _
    "SERVER=" & ServerDB & ";" & _
    "PORT=" & PortDB & ";" & _
    "DATABASE=" & NameDB & ";" & _
    "UID=" & UserDB & ";" & _
    "PWD=" & PasswordDB & ";"
Conn.ConnectionTimeout = 5  'Время до обрыва ожидания соединения
Conn.Open ConnString

End Sub


Это всё предыстория. Подобным кодом, только с другой строкой для коннекта я базу данных Access заполнял без проблем. А вот с заполнением MySQL выскочила неожиданная проблема. При заполнении полей MySQL типа char обрезаются концевые пробелы в тексте.
Например, я передаю в качестве параметра в объект ADODB переменную со строкой такого вида "МОЙ ТЕКСТ  ". А в базе MySQL он появляется в таком виде "МОЙ ТЕКСТ".
Если в параметр ADODB попадает строка с точкой в середине, то все данные начиная от точки и далее обрезаются и в поле базы данных не поступают. Например:
"3257, Serials ...938AA and ...936AA are same catalysts." обрезается и в MySQL остается вот это - "3257, Serials"
Тех.поддержка сказала, что проблема скорее всего в наличие кавычек вокруг текста. По факту это так и оказалось. Если код в методе CopyRecord видоизменить таким образом:
Код: (vb)

Command.Parameters.Append Command.CreateParameter("varNotes", 129, 1, 254) 'Создаем параметр adChar(129), 1-входной
With Command.Parameters("varNotes")
    If IsNull(AccessArrayTable(21, AccessArrayRecordNum)) Then
        .Value = ""
    Else
        .Value = Chr(34) & AccessArrayTable(21, AccessArrayRecordNum) & Chr(34)
    End If
End With


тогда текст не усекается, передается полностью, но он в поле базы данных так и выглядит закавыченым. Полагаю, что проблема в особенности работы драйверов ODBC для MySQL, так как при экспорте данных в Access таких приколов с данными у меня не было. Кто-нибудь знает как извернуться, чтобы нормально передать текст в MySQL?
« Последнее редактирование: 15.09.2019, 10:20:40 от McConst » Записан
boa
Старожил
****

Репутация: +22/-0
Офлайн Офлайн

Сообщений: 252


Доброта спасет мир...


Просмотр профиля WWW
« Ответ #1 : 15.09.2019, 17:22:33 »

Здравствуйте,
я не работал с MySQL,  но для MSSQL текст лучше передавть в одинарных кавычках (например: 'Мой текст   ').
Причем если внутри текста встречается одинарная кавычка, то при передаче в строке, она должна быть задвоена (например: 'Мой '' текст   ').
Записан

Ничто не обходится нам так дешево и не ценится так дорого, как вежливость...  Мигель Сервантес де Сааведра

McConst
Постоялец
***

Репутация: +1/-0
Офлайн Офлайн

Сообщений: 238


Просмотр профиля E-mail
« Ответ #2 : 15.09.2019, 19:34:19 »

С одинарными кавычками тоже пробовал. В текстовом поле текст появляется ограниченный одинарными кавычками - та же беда.
Нашел более эффективное решение. Для начала я создал локальную базу данных MySQL и сконвертил таблицу Access туда. С помощью менеджера баз данных HeidiSQL подключился к локальной базе и сохранил таблицу в скрипт-файл .sql
Файл .sql открывается обычным блокнотом, там оказались стандартные команды в стиле

Код: (sql)

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
DELETE FROM AutocatPrice;
/*!40000 ALTER TABLE `AutocatPrice` DISABLE KEYS */;
INSERT INTO AutocatPrice (`ID`, `Payment`, `Analyse_Date`, `Brand`, `Model`, `Engine_Type`, `Engine_Size`, `Engine_Name`, `Year_First`, `Year_Last`, `Serial`, `Mass`, `Cat_Type`, `Pt`, `Pd`, `Rh`, `PricePerKg`, `Total_Price`, `Company`, `URL`, `Method`, `Notes`) VALUES
   (1, 0, '2018-09-05', 53, NULL, NULL, NULL, NULL, NULL, NULL, 'KBA17001 / RFK-TT-20 / A', '0.70', 4, NULL, NULL, NULL, '67', '47', 1, NULL, 5, NULL),
   (2, 0, '2018-10-03', 53, NULL, NULL, NULL, NULL, NULL, NULL, 'KBA17012', '1.50', 4, NULL, NULL, NULL, '67', '100', 1, NULL, 5, NULL)

HeidiSQL позволяет выполнять .sql скрипт для подключенной базы данных. Если подключиться к MySQL на удаленном сервере, то в отличие от ADODB, который выполняет последовательное обновление записей минут 30, через скрипт база обновляется за секунды.
Написать макрос, создающий подобный файл .sql по подсмотренному шаблону - это уже дело техники.
Апострофы  внутрь текста можно заносить в виде комбинаций \' или \" - синтаксис mysql
Были кое-какие сложности с форматом файла. FSO создает файлы в формате UTF-16, а база данных работает с UTF-8, из-за этого скрипт не распознавался. В гугле нашел примеры, в которых с помощью ADODB.Stream файлы можно конвертировать из одной кодировки в другую.
Осталось разобраться как запустить .sql файл без сторонних приложений.
« Последнее редактирование: 16.09.2019, 00:46:57 от vikttur » Записан
boa
Старожил
****

Репутация: +22/-0
Офлайн Офлайн

Сообщений: 252


Доброта спасет мир...


Просмотр профиля WWW
« Ответ #3 : 15.09.2019, 20:25:52 »

Опять же, на примере MSSQL...
я таблицы сервера SQL подключаю в Access как линки, через ODBC и потом читаю с них данные вообще без проблем, как с локальной таблицы. А для записи на сервер(проверено) использую в VBA OLEDB коннект. Не к залинкованным в Access таблицам, а непосредственно к таблицам сервера. Более быстрого(скоростного) решения я не знаю. При этом синтаксис SQL-запросов аналогичен синтаксису сервера, а не Access'а, что даже лучше, т.к. SQL в Access'e очень скудный и не всегда адекватный.
Поэтому конвертация базы SQL в локальное хранилище для дальнейшего использования мне не понятно.
Записан

Ничто не обходится нам так дешево и не ценится так дорого, как вежливость...  Мигель Сервантес де Сааведра

McConst
Постоялец
***

Репутация: +1/-0
Офлайн Офлайн

Сообщений: 238


Просмотр профиля E-mail
« Ответ #4 : 15.09.2019, 20:46:19 »

Наоборот. Сама база ведется в локалке в Accesse, наполняется результатами измерений и т.д. А в MySQL на сервере просто храним данные, которыми планируем делиться со сторонними людьми по интернету. Т.е. в интернете просто неполная реплика данных из Access.
Впринципе, тех возможностей SQL, которые Access предлагает, совместно с VBA вполне хватает на данный момент.
Записан
Страниц: [1]   Вверх
Печать
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Яндекс.Метрика Рейтинг@Mail.ru