powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Смена типа данных домена
25 сообщений из 44, страница 1 из 2
Смена типа данных домена
    #38924101
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Суть примерно следующая: сейчас данные хранятся в DOUBLE PRECISION и при работе с данными постоянно появляется погрешность в одну копейку. К тому же в некоторых запросах используется конструкция типа x/y/z - где типы данных каждого поля - DOUBLE PRECISION. При использовании такой конструкции выскакивает ошибка "Arithmetic exception, numeric overflow, or string truncation". Я так понимаю дробная часть получается слишком большой...

В связи с этим было принято решение изменить тип данных полей на numeric(18,6). Для этого был создан новый домен с требуемым типом данных. Для полей созданы копии с новым доменом. Данные перенесены update'ом в новые поля.
Код: plsql
1.
update table a set a.field = cast((select b.field from table b where b.rdb$db_key = a.rdb$db_key) as NEW_DOMAIN)


Закомментированы все процедуры, триггеры и удалены все связи на эти поля. Удалены поля со старым доменом. Новые поля с новым доменом переименованы в старые. Все связи восстановлены, триггеры и процедуры раскомментированы. И напоследок даже Backup-Restore сделаны, но проблемы это не решило. Как писали одной похожей теме:
kdvв IB/FB существует "версионность метаданных таблиц". то есть, когда ты меняешь структуру таблицы - порядок, типы или размер столбцов - данные не трогаются, а просто показываются в новом формате.
В моем случае данные точно так же просто отображаются в новом формате. Что было сделано не так? Alter domain читал, собственно по форуму тоже почитал, но однозначного ответа не нашел. Вроде бы все сделано по технологии, но результат не соответствует ожиданию.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924110
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26,

1. Какой диалект?
2. Если ты создавал новое поле с новым типом, то почему же ты скопировал это поле само в себя, а не новое поле?
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924117
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26,

какой диалект? а то с одной стороны разговор про double, а с другой - про numeric(18,6) и всякие arithmeric exception.

Freddie26update table a set a.field = cast((select b.field from table b where b.rdb$db_key = a.rdb$db_key) as NEW_DOMAIN)
ересь какая-то. ну каст из домена, а тип field остался тем же. Где тут "новые поля"?

Freddie26Вроде бы все сделано по технологии
по какой-такой технологии?
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924221
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про технологию не понял, но запрос вырвиглазный.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924270
MrCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Запрос будет куда проще, если новое поле делать в той же таблице, что и старое. Получится не "технология", а классическая смена типа через буферное поле, которую ещё Борри описала. В этом случае вопрос про "версионность метаданных" должен отпасть сам собой - создано новое поле и его номер формата - 0.

"дробная часть получается слишком большой" - странные слова. Overflow, скорее, вызывает большой порядок (что-то около 10^308) результата. Который получается, небось, из-за многократного деления на "что-то около нуля" ("x/y/z"). Которое получается, небось, как разница между двумя "почти равными" (float же ж) значениями. В этом случае переход на NUMERIC не спасёт, ибо будет деление уже на чистый ноль.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924279
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrCat,

можно много чего гадать, пока автор не ответит. Вообще тут много всякого.
- с одной стороны, автор показал свою крутизну использованием rdb$db_key
- с другой стороны, автор что-то говорит про "версионность метаданных", при этом обновляя столбец через каст.
Нафига ему понадобился вложенный запрос, я вообще не понял. Потому что, если он поменял тип столбца, то он просто мог бы сделать
update table set field = field
и из одного типа столбец преобразовался бы в другой.
Но что-то у меня такое в памяти, что столбец double precision не превратится в int64 если его тип поменять на numeric(18,6) (надо проверять, но мне это не интересно).

Если он добавил столбец нового типа к таблице, то опять же достаточно
update table set field1 = field
и зачем тут cast к "новому домену" - совершенно непонятно. Каст к новому домену имел бы какой-то смысл при проверке на конвертируемость столбца из старого типа в новый, и то при select.

А с переполнением в конструкции x/y/z совсем мутно. Я скорее поверю, что переполнение будет при numeric(18,6) в третьем диалекте, чем с double precision в любом диалекте. Потому что при умножении и делении numeric в третьем диалекте точность (scale) складывается. То есть num(18,6)/num(18,6) будет num(18,12), т.е. для целой части остается всего 6 знаков.
А double precision будет прекрасно делиться хоть 20 раз.

Так что автор намешал мешанину. А истина где-то рядом, но не здесь.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924445
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу прощения, что ввел в заблуждение. Постараюсь ответить всем.

Симонов Денис 1. Какой диалект?
1. Используем третий диалект
Симонов Денис 2. Если ты создавал новое поле с новым типом, то почему же ты скопировал это поле само в себя, а не новое поле?
2. Поле я копировал не в само себя, а в этих таблицах было создано буферное поле. В него и копировал. Запрос набросал на скорую руку.
kdv - с одной стороны, автор показал свою крутизну использованием rdb$db_key
3. если это не сарказм, то... не считаю это крутизной, потому что не придумал иного способа как скриптом на 600 полей в которых может быть составной первичный ключ найти соответствие по полю (каюсь, sql не на столько хорошо знаю, как стоило бы, но познаю потихоньку по мере надобности).
kdv Если он добавил столбец нового типа к таблице, то опять же достаточно
update table set field1 = field
и зачем тут cast к "новому домену" - совершенно непонятно.
4. Не знал о таких нюансах.
MrCatOverflow, скорее, вызывает большой порядок (что-то около 10^308) результата. Который получается, небось, из-за многократного деления на "что-то около нуля" ("x/y/z"). Которое получается, небось, как разница между двумя "почти равными" (float же ж) значениями. В этом случае переход на NUMERIC не спасёт, ибо будет деление уже на чистый ноль.
kdv А с переполнением в конструкции x/y/z совсем мутно. Я скорее поверю, что переполнение будет при numeric(18,6) в третьем диалекте, чем с double precision в любом диалекте. Потому что при умножении и делении numeric в третьем диалекте точность (scale) складывается. То есть num(18,6)/num(18,6) будет num(18,12), т.е. для целой части остается всего 6 знаков.
На сколько я теперь понимаю нашей проблемы смена домена не решит. Не знаю всех причин, но вроде как основная причина - ошибка при делении трех столбцов "Arithmetic exception, numeric overflow, or string truncation".
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924452
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Чуть не забыл повторить, вторая известная мне проблема - откуда-то берется копейка. Видимо где-то не округляется и потом в отчеты попадает эта самая копейка - я так понимаю это погрешность.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924517
Фотография S.G.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26Чуть не забыл повторить, вторая известная мне проблема - откуда-то берется копейка. Видимо где-то не округляется и потом в отчеты попадает эта самая копейка - я так понимаю это погрешность.Наоборот, это следствие округления.
Простой пример:
Берем рубль, делим на три. Получается 3 раза по 33 копейки.
Умножаем обратно, 3*0.33 = 0.99 рубля, одна копейка куда-то пропала. Или наоборот, осталсь лишней, если сравнивать с тем рублем.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924588
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
S.G.,

Вам известны методы борьбы с "копейкой" ? На сколько я понял банки, например, округляют через раз: один раз происходит округление в большую сторону, другой в меньшую. Других примеров мне не известно.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924599
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26S.G.,

На сколько я понял банки, например, округляют через раз: один раз происходит округление в большую сторону, другой в меньшую.

Особенно приятно, если строк в таблице нечетное количество, ага.

Freddie26 Других примеров мне не известно.

Перевести в INTEGER (т.е. все хранить сразу в копейках).
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924653
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26Вам известны методы борьбы с "копейкой" ?
Самый простой метод: не делить промежуточные результаты. То есть сначала складывать, а
потом делить вместо того чтобы сначала делить, а потом складывать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924694
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterFreddie26S.G.,

На сколько я понял банки, например, округляют через раз: один раз происходит округление в большую сторону, другой в меньшую.

Особенно приятно, если строк в таблице нечетное количество, ага.

Не путайте банковское и чередующее округление
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924706
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26Вам известны методы борьбы с "копейкой" ?
Ну например, вычислять "погрешность" и учитывать её при следующем округлении
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924837
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26Вам известны методы борьбы с "копейкой" ?Самое главное это внутренне осознать, что:
результат действия над округленными операндами отличается от результата действия над операндами и округление результата.
Причем для душевного спокойствия лучше считать, что отличается всегда, и только иногда мы этого (разницы результата) не замечаем.
Все остальное это вопросы реализации.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38924867
pastor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26S.G.,

Вам известны методы борьбы с "копейкой" ? На сколько я понял банки, например, округляют через раз: один раз происходит округление в большую сторону, другой в меньшую. Других примеров мне не известно.

Например, все суммы кратны 18 копейкам.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38925024
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пока что у меня вопросов больше не осталось. С ошибкой "Arithmetic exception, numeric overflow, or string truncation" вроде разобрался, по крайней мере приведение результата деления cast-ом к numeric(18,6) помогло... Осталось проверить сотруднику, которому нужна эта реализация.

По поводу копейки методы реализации будем рассматривать. Лично мне подсказанное помогло узнать что-то новое, за что я всем благодарен.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38926120
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем начальству не нравится, что запросы надо переделывать, им подавай поля с новым доменом и чтобы все работало. Потому пытаюсь копать дальше...

Сейчас создал буферные поля, заполнил их запросами типа:
Код: plsql
1.
2.
3.
update table A set A.Field1 =  (select B.field from table B where B.RDB$DB_KEY = A.RDB$DB_KEY)
/*Собственно такие запросы выполнились быстрее, чем следующий, а результат тот же*/
update table set field1 = field


Получаю: значение в ячейке отображается как 7589,030000, а при двойном клике по ячейке вижу значение 7589,0299999999998. Тип поля Numeric(18,6). Просматриваю таблицу через IBExpert.
Вопрос: Почему значение показывается с некоторой погрешностью (и можно ли так выражаться в данном случае вообще??) и отразится ли это как-то на результатах запросов к этим полям?
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38926136
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hello, Freddie26!
You wrote on 3 апреля 2015 г. 12:16:37:

Freddie26> при двойном клике по ячейке вижу значение 7589,0299999999998.
> Тип поля Numeric(18,6).
у тебя поле создано не в третьем диалекте.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38926140
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или ты врёшь про диалект, или это баг эксперта.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38926143
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kdv Но что-то у меня такое в памяти, что столбец double precision не превратится в int64 если его тип поменять на numeric(18,6) (надо проверять, но мне это не интересно).
В какой тип можно конвертировать double precision? Что сделать, чтобы не отображалось этой погрешности?

В другой теме спрашивали как сменить numeric на double precision, советовали для применения сделать "холостой update" т.е. поле присвоить самому себе - тоже не помогает.
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38926154
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящий Hello, Freddie26!
You wrote on 3 апреля 2015 г. 12:16:37:

Freddie26
> при двойном клике по ячейке вижу значение 7589,0299999999998.
> Тип поля Numeric(18,6).

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


Диалект БД судя информации записанной в RDB$DATABASE - 3.
При подключении к БД я явно нигде не указываю диалект и собственно не нашел где его можно явно указать. Да и вроде бы он по умолчанию должен быть третьим.

Dimitry Sibiryakov Или ты врёшь про диалект, или это баг эксперта.
Что за выражение "врешь"? Я заинтересован в нахождении истины, зачем мне намеренно давать ложные данные?
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38926171
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26Что за выражение "врешь"?
У DS это синоним "вводишь в заблуждение"

зы. Обращай внимание на смысл его советов и не обращай внимания на некоторую "резкость" его высказываний,
он в большинстве случаев прав
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38926173
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Freddie26,

чем подключаешься?
...
Рейтинг: 0 / 0
Смена типа данных домена
    #38926217
Freddie26
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис,

Выполняю скрипты в IBExpert в редакторе скриптов. На сколько я понял вы говорите, что я поля создал не в 3-м диалекте. Так вот мои действия:
Код: plsql
1.
2.
3.
4.
5.
SET SQL DIALECT 3;
...
alter table TABLE add FIELD1 MONEYRUB_NUM;
--и так далее
--где MONEYRUB_NUM - домен с типом numeric(18,6)



Код: plsql
1.
2.
3.
4.
5.
SET SQL DIALECT 3;
...
update table set field1 = field;
update table2 set field1 = field;
--и так далее
...
Рейтинг: 0 / 0
25 сообщений из 44, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Смена типа данных домена
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]