Трудности кодировки

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Zhekius
Сообщения: 25
Зарегистрирован: 08 июл 2008, 14:57

Трудности кодировки

Сообщение Zhekius » 03 фев 2010, 08:53

Здраствуйте.
Что имеется: 1.Есть неизвестно кем и где созданная таблица с данными формата GDB. Под
2.Подключаюсь через IBExpert в FireBird 2.0. Замечательно читаю данные из таблицы - по умолчанию в настройках базы кодировка win1251
3.Пишу там же хранимую процедуру по выборке данных из таблицы. Там же проверяю - всё ок.
4. Запускаю Delphi 2009. Пишу клиентскую приладу через IBX
5. Через IBTable проверяю как вообще считывается таблица: не сразу, но подобрал кодировку (Unicode_fss). Были ошибка типа Division by zero либо Arithmetic overflow or division by zero has occurred. arithmetic exception, numeric overflow, or string truncation. Cannot transliterate character between character sets.
6. Ставлю компонент IBDataSet. В Select пишу вызов ХП типа Select * from ZHEKA_SHOW ('Петров','Иван').
7. Делаю коннект с выводом на DBGRID.
8. Ошибка кодировки! Неверно отображаются символы. КРАКАЗЯБЫ.
Проблема: перебрал все кодировки, доступные в IBDataBase и переподключался. Результата нет.
Вопрос: почему в простом прямом Select данных из таблицы кодировку подобрать можно, а через ХП - не подходит?
Какие были решения: менял кодировку для выходных и входных параметров в самой ХП: при условии что кодировка NONE - некоторые кодировки в клиентском приложении в Delphi дают просто ПУСТУЮ строчку. При других кодировка в основном КРАКАЗЯБА или Devision by Zero
Так же пробовал делать БэкАп. Результата нет.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Трудности кодировки

Сообщение kdv » 03 фев 2010, 11:29

Через IBTable проверяю как вообще считывается таблица: не сразу, но подобрал кодировку (Unicode_fss)
Были ошибка типа Division by zero
www.ibase.ru/unicode_faq.html

дальше - самостоятельно скопировать данные из старой базы в новую.

Zhekius
Сообщения: 25
Зарегистрирован: 08 июл 2008, 14:57

Re: Трудности кодировки

Сообщение Zhekius » 03 фев 2010, 15:22

Дмитрий, благодарю за информацию. Прочитал. А разве RESTORE после BACKUP'а не позволяет сменить кодировку базы?
Нужно делать миграцию?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Трудности кодировки

Сообщение kdv » 03 фев 2010, 18:35

А разве RESTORE после BACKUP'а не позволяет сменить кодировку базы?
с чего бы, никогда такой возможности не было.
Нужно делать миграцию?
только так. создаете новую базу в новой кодировке, потом
- старая база в старой кодировке, новая - в новой, копируете данные из старой в новую.

Zhekius
Сообщения: 25
Зарегистрирован: 08 июл 2008, 14:57

Re: Трудности кодировки

Сообщение Zhekius » 05 фев 2010, 09:04

Я сделал следющим образом:
1. Создал новую базу в IBEXPERT FireBird2.0. Кодировка win1251
2. С помощью инструмента Copy Object скопировал все объекты из старой базы в новую
3. Открываю своим клиентом из Delphi2009.
Те же КРАКАЗЯБЫ. Что я не так сделал?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Трудности кодировки

Сообщение kdv » 08 фев 2010, 02:40

Те же КРАКАЗЯБЫ. Что я не так сделал?
если я правильно понимаю, UNICODE_FSS само по себе автоматом в win1251 не копируются. Автоматическое преобразование есть только для UTF8<->win1251.
2. С помощью инструмента Copy Object скопировал все объекты из старой базы в новую
что это за инструмент - неизвестно. и непонятно, о каких именно "объектах" идет речь.
1. Создал новую базу в IBEXPERT FireBird2.0. Кодировка win1251
почему не FB 2.1 ?

Резюме. Кодировка БД по умолчанию находится в rdb$database. Кодировки столбцов не по умолчанию находятся в описании столбцов, это можно увидеть в IBExpert, закладка DDL на таблице. Если там и правда unicode_fss, то декодировать придется в 1251 вручную, самостоятельно.

Zhekius
Сообщения: 25
Зарегистрирован: 08 июл 2008, 14:57

Re: Трудности кодировки

Сообщение Zhekius » 09 фев 2010, 14:07

Так-с. После некоторых манипуляций были совершены следующие действия:
1. проверены кодировки в базах с помощью rdb$database. Результат "Win1251
2. с помощью IBExpert был сделан БЭКАП базы в версии FireBird 2.0
3. с помощью IBExpert восстановлен БЭКАП базы в версии FireBird 2.1
4. Записываю строчку запроса для ХП в поле SelectSQL компонента IBDataSet 'Select * from HranProcedure ('Иванов','Иван'). Делаю свойство Active в True.
Выдаёт опять КРАКАЗЯБЫ.
5. Поменял в компоненте IBDataBase свойство соединения "Character Set" с Win1251 на UNICODE_FSS. Делаю опять Active в True. Выдаёт ошибку типа
"Arithmetic exception, numeric overflow, or string truncaction. Cannot transliterate character betwenn cjaracter sets"
6. Косяк кодировки со стороны клиента.
7. Делаю запрос в ХП типа параметрического Select * from HranProcedure (:Family,:Name)
8. Программно заполняю параметры, запуская Active в True. Наслаждаюсь хорошим и полным результатом.
Всем спасибо за помощь. Узнал много нового )

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Трудности кодировки

Сообщение kdv » 09 фев 2010, 15:34

3. с помощью IBExpert восстановлен БЭКАП базы в версии FireBird 2.1
ругани никакой не было при ресторе? А то вдруг был пункт 2.
Выдаёт опять КРАКАЗЯБЫ.
см. выше про процедуры. Точно проблема именно в этом.
8. Программно заполняю параметры, запуская Active в True. Наслаждаюсь хорошим и полным результатом.
не-не. рестор надо правильно сделать с апгрейдом кодировок метаданных.
http://www.ibase.ru/firebird/21/metadata_charset.htm

Zhekius
Сообщения: 25
Зарегистрирован: 08 июл 2008, 14:57

Re: Трудности кодировки

Сообщение Zhekius » 09 фев 2010, 16:00

Гм. Дмитрий, спасибо за дельные советы. Вот сейчас начинаю нормально ее считывать параметрически, и даже засомневался, стоит ли чего-то менять ))))
Если не лень будет, то попробую.
Насчёт ругани - нет, вроде бы ничего не выдавала.
не-не. рестор надо правильно сделать с апгрейдом кодировок метаданных.
- Средствами IBExpert я там не нашёл каких-либо особо выдающихся параметров. А может просто не понял. Если это возможно сделать средствами IBExpert, привиди примерчик, если не турдно. Я попробую переконвертить - БэкАП, сделанный с FIREBIRD 2.0 еще лежит на диске. О результатах доложусь.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Трудности кодировки

Сообщение kdv » 10 фев 2010, 15:12

если параметрически работает, а явно - нет, значит однозначный косяк в кодировке метаданных.
Если это возможно сделать средствами IBExpert, привиди примерчик, если не трудно.
OMG! :) IBExpert не является утилитой Firebird, поэтому НИКАКОЙ специфики, особенно в данном вопросе, он не поддерживает.
Выполнить указанные в документе действия в SQL Editor IBExpert-а можно.

Zhekius
Сообщения: 25
Зарегистрирован: 08 июл 2008, 14:57

Re: Трудности кодировки

Сообщение Zhekius » 12 фев 2010, 10:11

:) мда-с. Ладно, много новых терминов узнал. Нужно чтоб в голове осели.
Другой немного вопрос не потеме, но по той же базе. В той же ХП интересный момент нашёл. Работаю в IBEXpert. Проблемы с индексами.
1. Есть текст ХП. Различные свзи и прочее.
2. Есть первый вариант запроса. Структура For Select Family From Spisok S Where S.Family LIKE 'Сидоро%' INTO :Family DO suspend;
3. 1 млн записей. Индекс по полю построен. Запрос мгновенный. Выдает всех, кто начианается на "Сидоро". В IBExpert'е смотрю анализ производительности: показывает, что запрос был выполнен индексированно.
4. Делаю второй вариант запроса. Использую параметр после слова "LIKE". Структура For Select Family From Spisok S Where S.Family LIKE :LIKE_Family||'%' INTO :Family DO suspend;
5. В папарметр заталкиваю "Сидоро". С тормозами, в течение 2-3 секунд выдала результат. Смотрю анализ производительности - запрос был выполнен без индексирования.
Почему такая лажа? Опять кодировка? Или лыжи не те? :(

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Трудности кодировки

Сообщение kdv » 12 фев 2010, 11:24

LIKE :LIKE_Family||'%'
ну ей-богу, сервер-то откуда узнает, что когда-то потом в значении ПАРАМЕТРА будет %, и с какой стороны?!
Естественно, что в этом случае индекс он использовать не хочет, и правильно делает.

Это ты видишь, что делаешь конкатенацию параметра с %. А сервер не обладает human brain, и кроме того, ты же сам можешь воткнуть в параметр строку '%Сидоро'. И что тогда?
А планы запросов строятся на этапе prepare, когда до реальных значений параметров еще очень далеко.

Zhekius
Сообщения: 25
Зарегистрирован: 08 июл 2008, 14:57

Re: Трудности кодировки

Сообщение Zhekius » 12 фев 2010, 12:49

Блин. Не силён. Не врублюсь, как же мне подготовить параметризированный запрос ручками, чтобы сервер правильно параметры определял?
Или нужно обратиться к внутренним механизьмам типа IBDataSet.Prepare()?

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: Трудности кодировки

Сообщение Dimitry Sibiryakov » 12 фев 2010, 13:20

А может стоит RTFM Language Reference на предмет STARTING WITH?..

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Трудности кодировки

Сообщение kdv » 12 фев 2010, 13:25

как же мне подготовить параметризированный запрос ручками, чтобы сервер правильно параметры определял?
никак. как только написано field like :param индекс по полю field использован НЕ БУДЕТ. Потому что см. выше, я уже объяснил.
starting with :param действует как прибитый гвоздями like с % в конце строки поиска, т.е. всегда ищет с начала, и поэтому индекс будет использован.
Или нужно обратиться к внутренним механизьмам типа IBDataSet.Prepare()?
нет никаких "внутренних механизмов". prepare делается всегда (кроме execute immediate), при выполнении любого запроса с клиента.

Zhekius
Сообщения: 25
Зарегистрирован: 08 июл 2008, 14:57

Re: Трудности кодировки

Сообщение Zhekius » 15 фев 2010, 13:58

Парни, большое спасибо. Конструкиця starting with - вполне приемлемый LIKE, прибитый гвоздями. :)
Вообще я понял, что плохо знаю весь синтаксис языка хранимых процедур, так что прошу прощения за глупые вопросы.
Всё хрюкает и фырчит просто супер. Запросы летают, индексы работают, клиент доволен.

Ответить