Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Работа с неUNICODE и UNICODE базами одного Delphi-приложения

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2

Открыть новую тему     Написать ответ в эту тему

romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Приложение на Delphi XE с использованием FIBPlus 7.3.  
База данных в кодировке WIN1251.  
Возникла потребность обеспечить работу в программе для пользователей грузии.  
Решением было создать базу в UTF8, а в приложении менять Charset подключения к БД.  
Для этого была создана БД с аналогичной структурой в кодировке UTF8.  
Я расчитывал на то, что меняя DataBase.ConectParams.Charset c WIN1251 на UFT8 я смогу отрывать неUNICODE и UNICODE версию базы.  
Но когда я делаю DataSet.Open из базы с кодировкой UFT8 выдается ошибка:  
> Type mismatch for field 'NAME', expecting: Stri ng actual: WideString.  
Тип поля NAME VARCHAR(40), к примеру.  
Это значит что нужно удалить все String-поля во всех DataSet.FieldsEditors и заново их добавить, только после этого DataSets будут открываться.  
Что значительно усложняет дело. Значит не получится из одного и того же исходного кода скомпилировать приложение, которое будет работать как с Unicode и неUnicode базой.  
Подскажите, есть ли выход из этой ситуации? Как можно сделать чтобы одна версия исходного кода позволяла работать с базой в неUnicode и Unicode без перекомпиляции?
 
Суппорт Devrace.com морозится уже неделю

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 12:11 11-04-2013
OXDBA

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Это значит что нужно удалить все String-поля во всех DataSet.FieldsEditors

Удалить все поля всех типов

Цитата:
и заново их добавить

Не добавлять ничего

Всего записей: 426 | Зарегистр. 19-01-2005 | Отправлено: 12:49 11-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Нельзя не добавлять. В проекте порядка 70 форм, Columns используются как в Гридах, так и в коде

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 13:01 11-04-2013
OXDBA

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Columns используются как в Гридах,

Гридам совершенно параллельно статические или динамические TField'ы.

Цитата:
так и в коде

Эти грабельки сам разложил или кто помог?

Всего записей: 426 | Зарегистр. 19-01-2005 | Отправлено: 14:04 11-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Сам конечно же Ну книжечки по Delphi еще когда-то давно помогли
 

Цитата:
Гридам совершенно параллельно статические или динамические TField'ы.

Ну как параллельно, если в Field-е определено форматирование, заголовок, ширина и причие няшечки?

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 14:11 11-04-2013
miwa

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Ну книжечки по Delphi еще когда-то давно помогли

Ужс. Это в каких книжечках написано делать так, как у тебя?
 
По теме - я бы начал с вникание в работу String-а и Unicode в Delphi и FB. После чего все перевел на Unicode для всех пользователей.
 
Добавлено:

Цитата:
Ну как параллельно, если в Field-е определено форматирование, заголовок, ширина и причие няшечки?

А что мешает то же делать в коде? Паралельно подстраиваясь под параметры монитора пользователя.

Всего записей: 455 | Зарегистр. 10-10-2004 | Отправлено: 14:18 11-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Проект в принцпе Unicode-ready, просто клиентских установок дофига чтобы всех переводить.  
Думал сделать отдельный билд для грузина и отпустить его восвояси.
 

Цитата:
Ужс. Это в каких книжечках написано делать так, как у тебя?

Не понимаю сарказма. Что здесь ужасного? Как любой dbaware-control будет отображать Field, если он не добавлен в DataSet.Fields ?
 
Добавлено:

Цитата:
А что мешает то же делать в коде?

Ну типа визуальная разработка и все такое...
А еще репозиторий полей FibPlus

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 14:26 11-04-2013
OXDBA

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Ну как параллельно, если в Field-е определено форматирование, заголовок, ширина и причие няшечки?

  DataSet.DefaultFormats,  DataSet.Fields[0].DisplayLabel,  DataSet.Fields[0].DisplayWidth и прочие няшечки.

Цитата:
Как любой dbaware-control будет отображать Field, если он не добавлен в DataSet.Fields ?  

А что ему может помешать?

Цитата:
Ну типа визуальная разработка и все такое...

Не надо об этом

Цитата:
А еще репозиторий полей FibPlus

Ему вообще фиолетово как DataSet.Fields заполняется, в design или run time.

Всего записей: 426 | Зарегистр. 19-01-2005 | Отправлено: 15:24 11-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
DataSet.Fields[0].DisplayLabel,  DataSet.Fields[0].DisplayWidth и прочие няшечки.

Ну да, для 30 датасетов с 10-20-30 и больше полями прописывать все это и многое другое руками в коде - то еще веселье...

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 16:50 11-04-2013 | Исправлено: romano501, 07:09 12-04-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
romano501
Чтото про добавление полей динамически и статически - глухо натянуто у преподов. Если динамически лучше значит дизайн редактор плохо справляется с этим. Если так то можно выяснить типы и отличия создаваемые динамически и просто их заменить в форме.
 
Походу я обязан один филд одного общего датасета в DB модуле прописывать во всех гридинах и инспекторах как DisplayLabel так и формат. Про ширину полей умолчим, но всё остальное не соответствует изначальной постановке работы разработчика.
 
Добавлено:
romano501

Цитата:
Если так то можно выяснить типы  

Если проблемма в том что TFIBWideStringField надо заменить на TFIBStringField, то это всего лишь замена в тексовом редакторе формы. Если не справитесь в ПМ дам телефон скинете базу, очень интересно.
 
Добавлено:
Кстати без вопросов переходите на Unicode - как ни странно - преобразования в 2 раза быстрее чем с WideString.
procedure _VarToUStr(var S: UnicodeString; const V: TVarData);
    varOleStr:   S := Copy(WideString(Pointer(V.VOleStr)), 1, MaxInt);
Боролись со счётчиком
 
Добавлено:

Цитата:
Не добавлять ничего

А вдруг разработчик хочет иметь контроль компилятора раньше чем ошибки всплывут у клиента??? Я знаком с мнением иметь динамические филды и раньше глупо доверял этому мнению (IMXO), я выбрал другой путь - мне так удобнее.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 17:58 11-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
TFIBStringField было изначально, но когда открываешь UNICODE-базу, то строковое поле становится TFIBWideStringField
 
Преобразования типа

Цитата:
varOleStr:   S := Copy(WideString(Pointer(V.VOleStr)), 1, MaxInt);

у меня в проектах не используется.
 
А что останавливало от перевода проекта полностью на UNICODE:
1) программа используется только для славянских пользователей. Это один пользователь из грузии захотел чтоб по грузински все писалось и я попробовал реализовать поддержку, не ожидал что будет затык
2) не хочется чтобы объем БД становился больше
3) даже если выпустить новую версию, переведя все строковые фиелды на WideString нужно вручную каждую базу каждого клиента переконвертировать. По времени это достаточно долго.
 
Проекту изначально не нужен был Unicode.
 
delover

Цитата:
я выбрал другой путь - мне так удобнее.

Всмысле определить фиелдсы в датасетах на этапе дизайна форм/датамодуля?
 

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 20:37 11-04-2013
miwa

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Ну да, для 30 датасетов с 10-20-30 и больше полями прописывать все это и многое другое руками в коде - то еще веселье...

 
Поэтому в проектах с более чем одной формой все формы наследуются от какой-то одной базовой, в которой кроме прочего делаются подобные вещи. Один раз. И потом во всем проекте все везде одинаково красиво.

Всего записей: 455 | Зарегистр. 10-10-2004 | Отправлено: 20:45 11-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
... и этот проект не исключение

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 20:46 11-04-2013
miwa

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
... и этот проект не исключение

Ну так же ж отлично Я не знаю специфики проекта, поэтому решение в лоб

Код:
 
for c := 0 to self.ComponentCount do
  if self.Components[c] is TpFIBDataSet then
    with (self.Components[c] as TpFIBDataSet) do  
    begin
      DefaultFormat := ...;
      AutoCommit := ...;
      for j := 0 to FieldCount do
        case Fields[j].DataType of
            ...
        end;
    end;
 

Что-то типа такого. Пишется один раз в одном месте. Удобно, правильно, понятно, быстро.
 

Цитата:
не хочется чтобы объем БД становился больше  

Не уверен, что кто-то заметит разницу.
 

Цитата:
даже если выпустить новую версию, переведя все строковые фиелды на WideString нужно вручную каждую базу каждого клиента переконвертировать.

Зачем? Один раз пишется и тестируется скрипт, котрый все делает во время технического перерыва. И если база не используется 24х7х365 - то хоть всю ночь.

Всего записей: 455 | Зарегистр. 10-10-2004 | Отправлено: 01:12 12-04-2013 | Исправлено: miwa, 01:12 12-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
miwa
Все DataSets находятся в DataModule.
Цикл ни к чему, т.к. есть DataSet.DafaultFormats. И у каждого Field есть свой собственный атрибут: DisplayLabel, DisplayWidth, не говоря уже о том, что у некоторых полей есть обработчик GetText, SetText и тому подобные, обработчик проверки условия и еще некоторые детали.
И вообще, нереально для CRUD-приложения, напичканого различными DBControls, писать весь код руками, вместо определения DataSet.FieldsDefs в DesignTime.
Согласен что для какой-то задачи обработки данных, где нет активного взаимодействия с пользователем, динамическая работа с Fields будет более оправдана.
У меня есть в проекте DataSet без Fields. Это отчетная форма, где каждый запрос имеет различный состав полей. И работа с таким DataSet динамически - довольно неудобно, но приходится, что делать.  
Код fdsEmployeeID.Value, fdsEmployeeNAME.Value гораздо информативнее, чем fdsEmployee.Fields[0].Value и fdsEmployeeю.Fields[1].Value.  
Это еще надо помнить какой номер у каждого поля для каждого DataSet - да ну нах.
Ну еще контроль во время компиляции - тоже немаловажно.

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 07:27 12-04-2013
OXDBA

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Код:
 
const
  fnEmployeeId = 'ID';
....
  fdsEmployee.FieldByName(fnEmployeeId).asInteger
 

Совсем не информативно?

Цитата:
Ну еще контроль во время компиляции - тоже немаловажно.

Угу, особенно после

Код:
ALTER TABLE EMPLOYEEE ALTER NAME TYPE VARCHAR(128)

а есть еще и ALTER DOMAIN...

Цитата:
И работа с таким DataSet динамически - довольно неудобно

Тогда уж сразу drop table FIB$DATASETS_INFO.
 
 

Всего записей: 426 | Зарегистр. 19-01-2005 | Отправлено: 10:18 12-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
OXDBA
 

Код:
 
const
  fnEmployeeId = 'ID';
....
  fdsEmployee.FieldByName(fnEmployeeId).asInteger
 

Да, это вполне рабочая конструкция. Используется в унифицированной форме-справочнике для стандартных полей ID, NAME, NOTE и некоторых других.  
Но при этом я подстрахован уже определенными в DataSet.Fields именами полей.
 

Код:
ALTER TABLE EMPLOYEEE ALTER NAME TYPE VARCHAR(128)

После изменения длины строкового поля, либо домена достаточно переоткрыть датасет в Design-time чтобы в DataSet.FieldsDefs подставилась новая длина поля и все.

Цитата:
Тогда уж сразу drop table FIB$DATASETS_INFO.

Ну это ты, батенька, уже во все тяжкие бросаешься.
 
 
Предлагаю все таки вернуться к моему вопросу, а не обсуждению стилей программирования.
OXDBA, твой посыл понятен. Работать с наборами полей датасетов динамически. К сведению принято. Но этот вариант мне не походит.  
 

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 12:12 12-04-2013
miwa

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Ну да, для 30 датасетов с 10-20-30 и больше полями прописывать все это и многое другое руками в коде - то еще веселье...

 

Цитата:
После изменения длины строкового поля, либо домена достаточно переоткрыть датасет в Design-time чтобы в DataSet.FieldsDefs подставилась новая длина поля и все.  

 
Таки датасет один, или 30?  
 

Цитата:
Все DataSets находятся в DataModule.  

Вообще все? Со всего приложения? На екране место еще не закончилось? А что будет, если закончится?
 

Цитата:
Предлагаю все таки вернуться к моему вопросу, а не обсуждению стилей программирования.  

Тогда предлагаю полный переход на юникод. Потому что сегодня грузинский клиент что-то захотел, завтра казахский будет ругаться, что его 1251 не совпадает с вашей, послезавтра турки захотят вашу программу, а через месяц отечественный заказчик откроет представительство в Китае. Глобализация

Всего записей: 455 | Зарегистр. 10-10-2004 | Отправлено: 13:10 12-04-2013
romano501



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Датасетов много, 30 это я обозначил примерный объем, пока в одном DataModule помещаются
 
Итак, вариант №2 - полный переход на UNICODE - принято

Всего записей: 137 | Зарегистр. 24-03-2007 | Отправлено: 13:17 12-04-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
romano501

Цитата:
Цитата:
varOleStr:   S := Copy(WideString(Pointer(V.VOleStr)), 1, MaxInt);
 
у меня в проектах не используется.  

 
Процедура _VarToUStr подключается автоматически, она в модуле Variants.pas,
когда:
 String2010 := TField(MyWidestringField).Value;  
Проверить достаточно просто - встаньте там отладчиком и посортируйте.  
Если у Вас нет WideStringField, то скорее всего из вариантов, которые содержат видестринг строка не извлекается.
 
 
Добавлено:

Цитата:
встаньте там отладчиком и посортируйте.  

Не смотрите, в новых фибах нормальная сортировка. Однако я сам иногда ленюсь и пользуюсь переменными Variant.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 15:26 12-04-2013 | Исправлено: delover, 16:13 12-04-2013
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Работа с неUNICODE и UNICODE базами одного Delphi-приложения


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru