Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Смена типа данных домена / 25 сообщений из 44, страница 1 из 2
01.04.2015, 17:02
    #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
01.04.2015, 17:08
    #38924110
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смена типа данных домена
Freddie26,

1. Какой диалект?
2. Если ты создавал новое поле с новым типом, то почему же ты скопировал это поле само в себя, а не новое поле?
...
Рейтинг: 0 / 0
01.04.2015, 17:13
    #38924117
kdv
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
01.04.2015, 19:40
    #38924221
Ivan_Pisarevsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смена типа данных домена
про технологию не понял, но запрос вырвиглазный.
...
Рейтинг: 0 / 0
01.04.2015, 21:01
    #38924270
MrCat
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смена типа данных домена
Запрос будет куда проще, если новое поле делать в той же таблице, что и старое. Получится не "технология", а классическая смена типа через буферное поле, которую ещё Борри описала. В этом случае вопрос про "версионность метаданных" должен отпасть сам собой - создано новое поле и его номер формата - 0.

"дробная часть получается слишком большой" - странные слова. Overflow, скорее, вызывает большой порядок (что-то около 10^308) результата. Который получается, небось, из-за многократного деления на "что-то около нуля" ("x/y/z"). Которое получается, небось, как разница между двумя "почти равными" (float же ж) значениями. В этом случае переход на NUMERIC не спасёт, ибо будет деление уже на чистый ноль.
...
Рейтинг: 0 / 0
01.04.2015, 21:13
    #38924279
kdv
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
02.04.2015, 08:42
    #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
02.04.2015, 08:56
    #38924452
Freddie26
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смена типа данных домена
Чуть не забыл повторить, вторая известная мне проблема - откуда-то берется копейка. Видимо где-то не округляется и потом в отчеты попадает эта самая копейка - я так понимаю это погрешность.
...
Рейтинг: 0 / 0
02.04.2015, 09:47
    #38924517
S.G.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смена типа данных домена
Freddie26Чуть не забыл повторить, вторая известная мне проблема - откуда-то берется копейка. Видимо где-то не округляется и потом в отчеты попадает эта самая копейка - я так понимаю это погрешность.Наоборот, это следствие округления.
Простой пример:
Берем рубль, делим на три. Получается 3 раза по 33 копейки.
Умножаем обратно, 3*0.33 = 0.99 рубля, одна копейка куда-то пропала. Или наоборот, осталсь лишней, если сравнивать с тем рублем.
...
Рейтинг: 0 / 0
02.04.2015, 10:27
    #38924588
Freddie26
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смена типа данных домена
S.G.,

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

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

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

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

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

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

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

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

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

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

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

В другой теме спрашивали как сменить numeric на double precision, советовали для применения сделать "холостой update" т.е. поле присвоить самому себе - тоже не помогает.
...
Рейтинг: 0 / 0
03.04.2015, 12:31
    #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
03.04.2015, 12:44
    #38926171
m7m
m7m
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Смена типа данных домена
Freddie26Что за выражение "врешь"?
У DS это синоним "вводишь в заблуждение"

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

чем подключаешься?
...
Рейтинг: 0 / 0
03.04.2015, 13:15
    #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
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Смена типа данных домена / 25 сообщений из 44, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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