WIN1251 в БД

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

SergeyDV
новенький
Сообщения: 18
Зарегистрирован: 18.12.2008 21:22:31

WIN1251 в БД

Сообщение SergeyDV »

Доброго времени суток!

Существует такая программа СуперОкна 2006. Используется БД Firebird 1.5.
Нужно написать небольшую программу для выдергивания нужных данных из БД суперокон.
Раньше писал на Делфи, потом пошли проверки... Делфи пришлось удалить...
В журнале Линукс Формат наткнулся на упоминание Lazarus-а и его сравнение с Делфи.
Решил попробовать, и сразу облом :)

Есть в ней таблица CLIENTS, как не трудно догадаться таблица содержит данные о клиентах.
Пробовал различные компоненты (TIBConnection, ZEOSDBO-6.6.4-stable, FIBL 0.7.3), везде один и тот же эффект!!!
В свойство Params добавляю строку: lc_ctype=WIN1251.
Открываем таблицу

Код: Выделить всё

select * from clients
и видим пустые строчки (за исключением редких цифорок и латинских буковок).

Почитал этот форум и в одной из веток http://www.freepascal.ru/forum/viewtopic.php?f=5&t=3855&st=0&sk=t&sd=a&hilit=win1251 с подобной проблемой, есть совет поставить кодировку UTF8.
При открытии таблицы появляется ошибка "arithmetic exception, numeric overflow, or string trucation"...

В IB Expert база открывается на ура с charset=WIN1251.
Что же это? Недоработка самого Lazarus или класса TConnection?

С Уважением Сергей.

p.s.: прошу прощения за несколько сумбурное изложение... :oops:
да кстати версия Lazarus 0.9.26
NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Сообщение NTFS »

1) Попробуй использовать более старую версию Lazarus (например, 0.9.24)
2) Попробуй указывать при подключении кодировку NONE
SergeyDV
новенький
Сообщения: 18
Зарегистрирован: 18.12.2008 21:22:31

Сообщение SergeyDV »

NONE пробовал, результат - пустые строчки...
Переходить на более старую версию религия непозволяет :D
Шутка! Попробую вечерком...
Не кто не в курсе когда 0.9.27 выйдет?
Аватара пользователя
amateur
энтузиаст
Сообщения: 552
Зарегистрирован: 03.08.2007 10:15:32

Сообщение amateur »

Привет...
:) уже вышел...
ftp://ftp.freepascal.org/pub/lazarus

"aText := AnsiToUtf8(Sender.AsString);" - рулит :)

у меня кодировка краше (866) в дбф файлах -красота :)
NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Сообщение NTFS »

На самом деле, использование более старой версии среды разработки - вполне нормальный прием. Так что попробуй 0.9.24
SAK
постоялец
Сообщения: 158
Зарегистрирован: 17.02.2006 23:45:14
Откуда: Тим
Контактная информация:

Сообщение SAK »

Я уже прелагал здесь viewtopic.php?f=5&t=3743&p=27627 вариант решения такой проблемы. Можно даже переписать метод TDataset.Translate в dataset.inc и если наследники его не перекроют, то это тоже сработает.
Аватара пользователя
alexs
долгожитель
Сообщения: 4066
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Попробуй использовать в качестве сервера версию птицы 2.0.4
проблем не должно быть - у меня проги не даже не заметили что было обновление сервера (в некоторх случаях - производительность лучше).
Естественно - пробуй на копии БД.
2-я птица умеет правильно перекодировать тексты (за исключением блоб). Чтобы и блобы автоматом перекодились - нужна версия 2.1 - но там обновление - не тривиальное.

Ну а если не получится - то лучше всего - через ручной перевод. В принципе - в FBDataSet могу даже событие включить на - OnTranslate.
SergeyDV
новенький
Сообщения: 18
Зарегистрирован: 18.12.2008 21:22:31

Сообщение SergeyDV »

Обновить птичку пока не получится, т.к. выше означенная программа (СуперОкна2006) работает только с 1.5 и разработчики не планируют переход на двойку. Так же они практически обещают возникновение глюков с FB2...

alexs а может быть включить то что предлагает SAK в Lazarus по умолчанию?

to SAK: В файле fields.inc свойство Transliterate изменил на true. Пересобрал Lazarus.
Так и не смог наити TSQLQuery.Translate... Правда я непонял почему именно для SQLQuery надо добавлять этот метод, ведь:

Код: Выделить всё

function TStringField.GetValue(var AValue: string): Boolean;
Var Buf, TBuf : TStringFieldBuffer;
begin
  Result:=GetData(@Buf);
  If Result then
    begin
    if transliterate then
      begin
      DataSet.Translate(Buf,TBuf,False);  // <----  Метод Translate объекта DataSet. -----<-----<-----<-----<-----<-----
      AValue:=TBuf;
      end
    else
      AValue:=Buf
    end
end;

Зато нашел TDataset.Translate и сделал вот так:

Код: Выделить всё

Function TDataset.Translate(Src, Dest: PChar; ToOem: Boolean): Integer;
  // новая переменная
  var s: string;
begin
  // ---------- мои изменения -------------
  if Src = nil then begin Result:=0; exit end;
  if ToOem then  s:=UTF8ToAnsi(src)
           else  s:=AnsiToUTF8(src);
  StrNCopy(Dest, PChar(s), dsMaxStringSize);
  Result:=strlen(Dest);
  { ---------- то что было -------------
  strcopy(dest,src);
  Result:=StrLen(dest);
  }
end;

После пересборки Lazarusa как выводились пустые строчки в таблице так и выводятся... :(

Подумал, что это с БД какая то бяка.
С помощью IB Expet-a создал БД. Изначально с WIN1251.
В БД одна таблица clients с двумя полями:
clid - integer автоинкремент,
clname - varchar(50).
Добавил парочку записей с русскими символами и открыл с помощью своей проги.
Результат как говорится на лице :(
Поведение такое же....

Попробовал в function TStringField.GetValue изменить
с StrNCopy(Dest, PChar(s), dsMaxStringSize);
на strcopy(dest,PChar(s));

Толку ноль...
Аватара пользователя
alexs
долгожитель
Сообщения: 4066
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

попробуй сделать вывод в файл содержимого таблицы после внесённых тобой изменений в коде - посмотри что получится - в какой кодировке.
SergeyDV
новенький
Сообщения: 18
Зарегистрирован: 18.12.2008 21:22:31

Сообщение SergeyDV »

а как сделать вывод в файл содержимого таблицы?? :oops:

Добавлено спустя 1 минуту 40 секунд:
С кодировкой по идее все в порядке!!!
IB Expert подключается к ней в WIN1251 и все русские символы видно.
Аватара пользователя
alexs
долгожитель
Сообщения: 4066
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Код: Выделить всё

SQLQuery.First;
while not Table.Eof do
begin
  writeln(f, SQLQuery.FieldByName('clname').AsString);
  SQLQuery.Next;
end;

Это поможет тебе определить - а работают ли твои процедуры перекодировки?
SergeyDV
новенький
Сообщения: 18
Зарегистрирован: 18.12.2008 21:22:31

Сообщение SergeyDV »

AkelPad определяет кодировку созданного test.txt как WIN1251.
То есть получается все в порядке!!!
Почему же их невидно в DBGrid?

Добавлено спустя 1 минуту 41 секунду:
ps: чего то протупил с выгрузкой в файл :oops:
стыдно до невозможности... :oops: :oops: :oops:

Добавлено спустя 9 минут 33 секунды:
В момент работы программы добавил новую запись в таблицу и выгрузил.
В AkelPad эту строчку я смог прочитать только в кодировке UTF-8...
Аватара пользователя
alexs
долгожитель
Сообщения: 4066
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Текст должен быть в UTF8 - всё что в другой кодировке программа на отобразит (или отобразит вопросами)
так что - смотри - перекодировщик у тебя почему то не работает.
v-t-l
энтузиаст
Сообщения: 744
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение v-t-l »

обсуждалось уже не раз. вот, например: http://www.freepascal.ru/forum/viewtopic.php?f=6&t=2932&p=18864

Добавлено спустя 8 минут 50 секунд:
SergeyDV писал(а):В свойство Params добавляю строку: lc_ctype=WIN1251.

Сервер сам знает в какой кодировке у него база - надо указать в какой кодировке передавать данные клиенту, а приложения последнего Lazarus используют кодировку UTF8.

Невнимательно прочитал ветку. :oops:
ink
незнакомец
Сообщения: 3
Зарегистрирован: 25.12.2008 11:00:53

Сообщение ink »

В лазарусе 0.9.26 при подключении к firebird 1.5 в компоненте IBConnection устанавливаю свойство CharSet = WIN1251
Для правильного отображения кириллицы в гриде (DBGrid-DataSource-TSQLQuery-IBConnection) достаточно
в свойство грида onDrawColumnCell добавить

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
DBGrid1.Canvas.TextOut(Rect.left,Rect.Top + 1,AnsitoUTF8(column.Field.Text));
end;

Если грид привязан к DBF файлу с 866 кодировкой то column.Field.Text необходимо сначала преобразовать OEMToChar в 1251
А вот при работе с полями приходится их конвертировать в UTF8... AnsiToUTF8, а при записи в базу обратно в 1251.....
Ответить