Как выполнить запрос в MySQL для вставки юникодстроки

KsandrPRO

Местный
Регистрация
10 Окт 2008
Сообщения
30
Реакции
22
Credits
54
Доброго времени суток всем!

Вопрос относительно использования utf кодировки в проекте.
Среда разработки Delphi 2009
Сервер базы данных MySQL 5.0.45
Компоненты MySQLDAC 2.7

Проект пока пробный, испытательный... За корявость кода не пинайте :)
Пытаюсь создать базу и таблицу в utf8 кодировке и записать в таблицу записи содержащие казахские символы.
Если без SET NAMES, то получаю вопросы вместо символов.
А если использовать SET NAMES то ругается MySQL error code (1366)

Вот код:
Код:
  if not mySQLDatabase1.Connected then
    begin
      mySQLDatabase1.Params.Clear;
      mySQLDatabase1.Host := 'ip сервака';
      mySQLDatabase1.Port := 3306;
      mySQLDatabase1.UserName := 'root';
      mySQLDatabase1.UserPassword := 'мой пароль';
      mySQLDatabase1.Params.Add('SET CHARACTER SET utf8');
      mySQLDatabase1.Params.Add('SET CHARACTER_SET_CLIENT=utf8');
      mySQLDatabase1.Params.Add('SET CHARACTER_SET_CONNECTION=utf8');
      mySQLDatabase1.Params.Add('SET CHARACTER_SET_RESULTS=utf8');
    end;

  try
    mySQLDatabase1.Connect;
    mySQLQuery1.Active := false;
    mySQLQuery1.SQL.Clear;
    mySQLQuery1.SQL.Add('SET NAMES utf8;');
    mySQLQuery1.SQL.Add('CREATE DATABASE IF NOT EXISTS utfka CHARACTER SET utf8;');
    mySQLQuery1.SQL.Add('CREATE TABLE IF NOT EXISTS utfka.tempushka (name VARCHAR(255)) ENGINE=MyISAM DEFAULT CHARSET utf8;');
    mySQLQuery1.SQL.Add('DELETE FROM utfka.tempushka;');
    mySQLQuery1.SQL.Add('INSERT INTO utfka.tempushka (name) VALUES (:stroka);');
    // mySQLQuery1.SQL.Add('INSERT INTO utfka.tempushka (name) VALUES ("құү.ғ,өңәі");');
    mySQLQuery1.ParamByName('stroka').AsWideString := 'құү.ғ,өңәі';
    // mySQLQuery1.ParamByName('stroka').AsString := 'құү.ғ,өңәі';
    mySQLQuery1.SQL.Add('SELECT * FROM utfka.tempushka;');
    mySQLQuery1.Active := true;
  except
    mySQLDatabase1.Disconnect;
  end;

В данном случае я попробовал передать строку как параметр, но и непосредственно в запросе пробовал.
Как мне добиться результата?
Я конечно могу вместе со своей программой ставить драйвера KazWorkDrv - тогда даже программа на Delphi 7 будет с казахским работать. Но ведь Delphi 2009 сам работает прекрасно с юникодом и хотелось бы обойтись без дополнительных дров.

Забыл еще сказать, что сам казахский язык используется стандартный, который есть в любой XP-ке.
 
Последнее редактирование модератором:

KsandrPRO

Местный
Регистрация
10 Окт 2008
Сообщения
30
Реакции
22
Credits
54
Провел испытание: если не могу записать данные в базу в формате юникода, то хоть вытащу от туда...
Попробовал сначала через SQL Maestro for MySQL, но он отказался передавать казахский текст в базу. Тут же все превращалось в абру-кадабру.
Тогда я попробовал создать базу с таблицей и занести туда данные через PHP (благо дело у меня сервер с внутренним сайтом, через него то и создал базу и таблицу в UTF кодировке) Данные добавились и там же, в PHP, считываются как надо, т.е. там казахский работает.

Теперь попробовал вытащить данные в Delphi.

Код:
// қңә.ғәіңөғұңқәі - то что содержится в таблице в базе
  // Т›ТЈУ™.Т“У™С–ТЈУ©Т“Т±ТЈТ›У™С– - то что я получаю на экране в гриде при включенном SET NAMES

  if not mySQLDatabase1.Connected then
    begin
      mySQLDatabase1.Params.Clear;
      mySQLDatabase1.Host := 'xxx.xxx.xxx.xxx';
      mySQLDatabase1.Port := 3306;
      mySQLDatabase1.UserName := 'root';
      mySQLDatabase1.UserPassword := 'xxxxxxxxxx';
      mySQLDatabase1.Params.Add('SET CHARACTER SET utf8');
      mySQLDatabase1.Params.Add('SET CHARACTER_SET_CLIENT=utf8');
      mySQLDatabase1.Params.Add('SET CHARACTER_SET_CONNECTION=utf8');
      mySQLDatabase1.Params.Add('SET CHARACTER_SET_RESULTS=utf8');
    end;

  try
    mySQLDatabase1.Connect;
    mySQLQuery1.Active := false;
    mySQLQuery1.SQL.Clear;
    mySQLQuery1.SQL.Add('SET NAMES utf8;');
    mySQLQuery1.SQL.Add('SELECT name FROM utfka.tempushka;');
    mySQLQuery1.Active := true;
  except
    mySQLDatabase1.Disconnect;
  end;

Если стоит включенный SET NAMES я уже указал в начале кода, какую строку я получаю.
Если же SET NAMES отключить, то вместо казахских символов получаю вопросы.
Сам грид использую TMS-овский. Пробовал у него включать и выключать режим отображения unicode.
Все без толку.

Кстати, у кого проблемы с русским были, могу сказать, что русский язык у меня работает на УРА при кодировке cp1251, а вот казахский и русский при кодировке UTF8 - труба дело...

Может кто помочь разобраться?
 

KsandrPRO

Местный
Регистрация
10 Окт 2008
Сообщения
30
Реакции
22
Credits
54
Судя по количеству людей людей, посетивших эту тему, тема эта не безинтересна многим.
Правда никто не смог дать ответа.
Ну что же... К радости своей и тех, кому тоже интересно, сообщаю, что на сайте microolap нашел таки инфу (правда на английском) на тему поддержки utf8 в MySQLDAC.

Привожу текст от туда:
Q. How to use Unicode data in my application?

A. Delphi/C++Builder support Unicode strings starting from 2009 version (Tiburon). DAC for MySQL supports Unicode data starting from v2.7.0. So, to support Unicode in your application you should use Delphi/C++Builder at least version 2009 and DAC for MySQL at least version 2.7.0.

Another issue for Unicode-enabled DB-applications is connection characterset. DAC for MySQL support Unicode strings only for UTF8 connection characterset. You have to set TmySQLDatabase.ConnectionCharacterSet property to 'utf8' to make DAC for MySQL represent strings as Unicode strings.

Connection character set can be UTF8 even if you don't set TmySQLDatabase.ConnectionCharacterSet property to 'utf8', e.g. if the server is configured to use UTF8 as default connection character set. You can use TmySQLDatabase.Utf8Used property to ensure that your application is connected to MySQL server using UTF8 connection character set.

If TmySQLDatabase.Utf8Used property value is False all strings are treated as sinlge-byte strings with ANSI encoding. Such ANSI-behaviuor is the same as for DAC for MySQL before 2.7.0 version.

Таким образом я добавил в своем коде строчку:
mySQLDatabase1.ConnectionCharacterSet := 'utf8';

Код:
  if not mySQLDatabase1.Connected then
    try
      mySQLDatabase1.Params.Clear;
      mySQLDatabase1.Host := 'xxx.xxx.xxx.xxx';
      mySQLDatabase1.Port := 3306;
      mySQLDatabase1.UserName := 'root';
      mySQLDatabase1.UserPassword := 'xxxxxxxxxx';
      mySQLDatabase1.ConnectionCharacterSet := 'utf8';
      mySQLDatabase1.Connect;
    except
      mySQLDatabase1.Disconnect;
      Exit;
    end;

  mySQLQuery1.Active := false;
  mySQLQuery1.SQL.Clear;
  mySQLQuery1.SQL.Add('SET NAMES utf8;');
  mySQLQuery1.SQL.Add('CREATE DATABASE IF NOT EXISTS utfka CHARACTER SET utf8;');
  mySQLQuery1.SQL.Add('CREATE TABLE IF NOT EXISTS utfka.tempushka (name VARCHAR(255)) ENGINE=MyISAM DEFAULT CHARSET utf8;');
  mySQLQuery1.SQL.Add('INSERT INTO utfka.tempushka (name) VALUES ("құү.ғ,өңәі");');
  mySQLQuery1.SQL.Add('SELECT * FROM utfka.tempushka;');
  mySQLQuery1.Active := true;

В результате я смог и добавить в таблицу текст, содержащий казахские символы, и получить его от туда назад и отобразить в гриде.
 
Последнее редактирование модератором: