Фух, дошло! Но сначала немного оффтопа: компоненты для БД, наверное, самые сырые из всех, т.к. мало кто ими пользуется и мало кто ищет ошибки в них и сообщает на форуме. А также мало примеров, мало уроков, не разобраны нестандартные ситуации. Поэтому я буквально чувствую себя чуть ли не первопроходцем по этим компонентам. Если неправ - буду рад пообщаться с более опытными товарищами.
А теперь решение. Оказалось, что существует функция
mysql_real_escape_string(), к-я экранирует все спецсимволы, и любой текст можно передать с её помощью. Есть она и в
libmySQL.dll, описана в файле
mysqllib.pas. Если через неё преобразовать текст, его можно без проблем передавать в БД.
Как оказалось, эта функция используется в
MySQL.pas, в методе
BlobToString. А он как раз есть в
dbMySQL_Exec.pas - для передачи бинарных данных в БД, т.е. blob. Так что бинарные данные на самом деле преобразуются в строку (к-ая может содержать в т.ч. непечатные символы в случае реальных бинарных данных, например картинки).
Но ведь это означает, что текст тоже можно передать как blob, и в нём уже никакие спецсимволы мешать не будут, т.к. все обрабатывается через
mysql_real_escape_string()! Поэтому текст со спецсимволами передаём как бинарные данные, и всё работает!
Проблема в том, в справке к компоненту толком не описано, как использовать blob в компоненте. Едва нашёл его здесь:
Хотя описание должно быть в разделе dbMySQL_Exec. Кстати, и на картинке неточно описание: двоеточием предваряется не имя поля, а фрагмент, к-ый будет заменён на бинарные данные.
Ну да ладно. Вот примерная схема:
Add(FormatStr,15252615,924,707)
{
DataCount=1
Mask="UPDATE wp_posts SET post_content = :str WHERE ID = %1\r\n"
link(onFString,16165819:doExec,[])
}
Add(Case,3190599,1043,714)
{
Value=String(str)
DataOnTrue=Integer(0)
link(onTrue,12913199:In,[])
}
Add(dbMySQL_Exec,16165819,973,707)
{
link(onResult,472517:doMessage,[])
link(onGetBlob,3190599:doCase,[])
link(onError,13817250:doMessage,[(1021,727)(1021,783)])
link(BlobData,81347:Var,[])
}
Add(Charset,9005689,777,707)
{
Type=6
link(onCharset,12410778:doConvert,[])
}
Add(StreamConvertor,12410778,826,707)
{
Mode=7
link(onResult,13687111:doCopy,[])
}
Add(MemoryStream,13687111,875,707)
{
Point(doPosition)
link(onCopy,15252615:doString,[])
}
Add(LineBreak,11548220,945,616)
{
link(Out,81347:doIndex,[])
Primary=[12913199,140,105]
}
Add(GetIndexData,81347,987,616)
{
link(Data1,13687111:Stream,[(993,604)(937,604)(937,751)(881,751)])
}
Add(Message,472517,1211,707)
{
Caption="Успешно. Количество изменённых полей:"
Icon=4
}
Add(Message,13817250,1036,777)
{
Caption="Ошибка"
}
Т.е. по событию onGetBlob определяем, какое поле сейчас обрабатывается компонентом, и подаём в этот момент нужные данные.