Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.05;
Скачать: CL | DM;

Вниз

Неправильный расчет выражений в SQL   Найти похожие ветки 

 
Delphi basic ©   (2006-09-01 10:59) [0]

В Firebird выполняю следующий запрос:

select (ts.moto_hour * c.fuel_norm_moto), c.fuel_norm_moto, ts.moto_hour
from travel_sheet ts, car c, subdivision s
where ts.car = c.ui and
  ts.subdivision = s.ui and
  extract(month from ts.work_date) = 7 and
  extract(year from ts.work_date) = 2006 and
  s.code = "СМИТ" and
  ts.state = 1

результаты:

150   20   7,5
 75   20   3,8
 60    6      6
 60   20     3

почему выражение (1-й столбец) неправильно считается?
Чего-то я не понимаю :(


 
ANB ©   (2006-09-01 11:06) [1]

приведи DDL всех таблиц и куски данных.


 
Delphi basic ©   (2006-09-01 11:14) [2]

ОК, вот:

1-я табл

CREATE TABLE TRAVEL_SHEET (
   UI                  INTEGER NOT NULL,
   CAR                 INTEGER NOT NULL,
   DRIVER              INTEGER NOT NULL,
   SUBDIVISION         INTEGER NOT NULL,
   EXPENSE_CIPHER      INTEGER NOT NULL,
   PREFIX              VARCHAR(10) NOT NULL,
   NUMBER              INTEGER NOT NULL,
   BEGIN_DATE          DATE NOT NULL,
   END_DATE            DATE NOT NULL,
   STATE               INTEGER NOT NULL,
   WORK_DATE           DATE NOT NULL,
   SPEEDOMETER_BEFORE  INTEGER NOT NULL,
   SPEEDOMETER_AFTER   INTEGER NOT NULL,
   REMAINDER_BEFORE    NUMERIC(10,3) NOT NULL,
   REMAINDER_AFTER     NUMERIC(10,3) NOT NULL,
   KM_CITY             INTEGER DEFAULT 0 NOT NULL,
   KM_CITY_CARGO       INTEGER DEFAULT 0 NOT NULL,
   CITY_CARGO          NUMERIC(10,1) DEFAULT 0 NOT NULL,
   KM_HIGHWAY          INTEGER DEFAULT 0 NOT NULL,
   KM_HIGHWAY_CARGO    INTEGER DEFAULT 0 NOT NULL,
   HIGHWAY_CARGO       NUMERIC(10,1) DEFAULT 0 NOT NULL,
   KM_FIELD            INTEGER DEFAULT 0 NOT NULL,
   MOTO_HOUR           NUMERIC(10,1) DEFAULT 0 NOT NULL,
   FUEL_ISSUED         NUMERIC(10,3) DEFAULT 0 NOT NULL,
   MECH_HOUR           NUMERIC(10,1) DEFAULT 0 NOT NULL,
   FUEL_USED           NUMERIC(10,3) DEFAULT 0 NOT NULL
);

2-я табл:
CREATE TABLE CAR (
   UI                 INTEGER NOT NULL,
   MARK               INTEGER NOT NULL,
   CAR_TYPE           INTEGER NOT NULL,
   DRIVER             INTEGER NOT NULL,
   GSM_CARD           INTEGER NOT NULL,
   SUBDIVISION        INTEGER NOT NULL,
   GSM_TYPE           INTEGER NOT NULL,
   GOS_NUMBER         VARCHAR(10) NOT NULL,
   YEAR_ISSUE         INTEGER NOT NULL,
   USAGE_BEGIN        DATE,
   USAGE_END          DATE,
   FUEL_NORM          NUMERIC(5,1) NOT NULL,
   FUEL_NORM_MOTO     NUMERIC(5,1) NOT NULL,
   GARAGE_NUMBER      VARCHAR(10),
   AVERAGE_SPEED      INTEGER DEFAULT 40 NOT NULL,
   NO_USE_CORR_COEFF  INTEGER DEFAULT 0 NOT NULL
);

куски данных как-то неудобочитаемы будут, особенно для 1-й табл.


 
ANB ©   (2006-09-01 11:16) [3]

Эта, первичные ключи неплохо бы еще напечатать . . .


 
Delphi basic ©   (2006-09-01 11:18) [4]

У всех они по UI построены.


 
Delphi basic ©   (2006-09-01 11:35) [5]

Вот так считает правильно:

select (cast(ts.moto_hour as numeric(10, 1)) * cast(c.fuel_norm_moto as numeric(10, 1))), c.fuel_norm_moto, ts.moto_hour,
ts.UI, ts.car
 from travel_sheet ts, car c, subdivision s
 where ts.car = c.ui and
   ts.subdivision = s.ui and
   extract(month from ts.work_date) = 7 and
   extract(year from ts.work_date) = 2006 and
   s.code = "СМИТ" and
   ts.state = 1

Это что ж, получается, придется обязательно к одному типу приводить, чтобы получить корректный результат?


 
ANB ©   (2006-09-01 11:43) [6]


> Delphi basic ©   (01.09.06 11:35) [5]

В оракле такие проблемы не возникают :)


 
Delphi basic ©   (2006-09-01 11:51) [7]

Я знаю, но "каждому свое" ©
В смысле проекту в зависимости от масштаба.
На оракле у нас корпоративная АСУ - тот еще мастодонтище :)


 
Desdechado ©   (2006-09-01 12:10) [8]

провел эксперимент на FB 1.5.3

таблицы:
CREATE TABLE CAR (
   UI              INTEGER NOT NULL,
   FUEL_NORM_MOTO  NUMERIC(5,1) NOT NULL
);

UI  FUEL_NORM_MOTO  
1          20,000  
2          20,000  
3           6,000  
4          20,000  

CREATE TABLE TRAVEL_SHEET (
   UI         INTEGER NOT NULL,
   MOTO_HOUR  NUMERIC(10,1) DEFAULT 0 NOT NULL
);

UI  MOTO_HOUR  
1      7,500  
2      3,800  
3      6,000  
4      3,000  

запрос:
select (ts.moto_hour * c.fuel_norm_moto), c.fuel_norm_moto, ts.moto_hour
from travel_sheet ts, car c
where ts.ui = c.ui

получил такое
F_1      FUEL_NORM_MOTO  MOTO_HOUR  
150,000          20,000      7,500  
76,000          20,000      3,800  
36,000           6,000      6,000  
60,000          20,000      3,000  

делаем выводы...

PS AFAIR, операнды автоматически приводятся к большему типу


 
Delphi basic ©   (2006-09-01 12:16) [9]

У меня та же версия FB, но без CAST"ов упорно не хочет правильно считать.


 
Delphi basic ©   (2006-09-01 12:18) [10]


> Desdechado ©   (01.09.06 12:10) [8]

Какой диалект у базы? У моей 3-й.


 
Виталий Панасенко   (2006-09-01 12:23) [11]

Не через БДЕ случаем ?


 
Delphi basic ©   (2006-09-01 12:32) [12]

В IBExpert"е


 
Desdechado ©   (2006-09-01 12:36) [13]

диалект 1, но имхо на числа это не должно влиять


 
Delphi basic ©   (2006-09-01 13:03) [14]


> Desdechado ©   (01.09.06 12:10) [8]

Провел тот же эксперимент с двумя базами, с 1-м и 3-м диалектом. Считает правильно... Так какого рожна в исходной базе ему надо?


 
unknown ©   (2006-09-01 13:57) [15]


> Desdechado ©   (01.09.06 12:36) [13]

Очень даже влияет :
NUMERIC
диалект 3 - 64 bit int
диалект 1 - double precision


 
Desdechado ©   (2006-09-01 14:06) [16]

да, подзабыл
просто с фиксированной точкой да и 3-м диалектом редко пользуюсь

Precision    Dialect 1                                  Dialect 3
1 to 4       SMALLINT for NUMERIC datatypes SMALLINT
              INTEGER for DECIMAL datatypes
5 to 9       INTEGER                                   INTEGER
10 to 18    DOUBLE PRECISION                     INT64

Но это всего лишь способ ХРАНЕНИЯ, а не выполнения матем. операций


 
Delphi basic ©   (2006-09-01 14:09) [17]


> unknown ©   (01.09.06 13:57) [15]

Точно? Я в хелпе интербейзовском вычитал много чего интересного, например, то, что numeric для size <= 9 хранит как Integer для обоих диалектов, а начиная с size 10 - как double precision/64 bit в зависимости от диалекта.


 
Delphi basic ©   (2006-09-01 14:20) [18]


> Delphi basic ©   (01.09.06 13:03) [14]


Но результаты [14] все равно непонятны...
Если уж считать неправильно, то делать это применительно ко всем базам на одном и том же сервере...


 
Виталий Панасенко   (2006-09-02 11:29) [19]

backup/restore не делал ? может, база рухнула ?


 
kaif ©   (2006-09-05 01:09) [20]

Я сталкивался с подобной ошибкой.
Если перемножается INTEGER и DECIMAL (NUMERIC)
зачастую FB рассматривает результат как INTEGER.
Использование CAST всегда спасает.


 
atruhin ©   (2006-09-05 17:02) [21]

> зачастую FB рассматривает результат как INTEGER.

Вроде не зачастую, а всегда. Это документированно.
А вот то, что у автора похоже на
> [19] Виталий Панасенко   (02.09.06 11:29)


 
Desdechado ©   (2006-09-05 17:07) [22]

Комбинируем
> FUEL_NORM_MOTO  NUMERIC(5,1)
и
>Precision    Dialect 1                                  Dialect 3
>5 to 9       INTEGER                                   INTEGER
и
kaif ©   (05.09.06 01:09) [20]

Может, каким-то боком и вылазит?


 
Delphi basic ©   (2006-09-06 11:06) [23]


> Виталий Панасенко   (02.09.06 11:29) [19]

Сделал, теперь нормально считает.


> atruhin ©   (05.09.06 17:02) [21]
> А вот то, что у автора похоже на
> > [19] Виталий Панасенко   (02.09.06 11:29)

И все же почему так странно себя ведет?
Получается, если не сделал backup/restore в какой-то (какой?) момент времени, можно получить сюрпризы с непонятно откуда растущими ногами вроде того, который был у меня? Ведь остальное все нормально работало.


 
Desdechado ©   (2006-09-06 13:35) [24]

> можно получить сюрпризы с непонятно откуда растущими ногами
Сюрпризы всегда возможны. А b/r вполне нормальная процедура, рекомендуется для периодичного выполнения. Можно и gfix.


 
atruhin ©   (2006-09-07 15:33) [25]

> [23] Delphi basic ©   (06.09.06 11:06)
> Получается, если не сделал backup/restore в какой-то (какой?
> ) момент времени, можно получить сюрпризы

Не совсем так. Ошибки базы бывают как правило после "падения" сервера, а также восле модификации структуры БД. В некоторых случаях когда в таблице есть данные, и ты изменяешь тип поля, в поле могут оказаться неправильные данные. Это известный глюк IB. При нормальной работе база может работать годами без b/r. ( видел такие случаи)


 
Desdechado ©   (2006-09-07 15:36) [26]

> При нормальной работе база может работать годами без b/r
Особенно в режиме R/O с компашки :)
А то ведь предел нумерации транзакций когда-то же наступит...

> Это известный глюк IB.
Документированный глюк - это фича!


 
atruhin ©   (2006-09-07 17:16) [27]

> А то ведь предел нумерации транзакций когда-то же наступит...

Ну, ну :) Счетчик = integer;
Основная цель b/r - удаление зависших транзакций, пересчет статистики индексов. (Это для аатора)


 
Desdechado ©   (2006-09-07 17:35) [28]

>  пересчет статистики индексов.
Перестройка индексов. Пересчет статистики можно сделать и без b/r командой SET STATISTICS. А в бэкапе индексы не хранятся, только правила их построения.
Хотя и индексы можно перестроить (INACTIVE/ACTIVE), но это уже другая песня.


 
atruhin ©   (2006-09-07 20:34) [29]

Да я то знаю, все можно сделать отдельно, но бэкап это все делает сразу, автоматически.



Страницы: 1 вся ветка

Текущий архив: 2006.11.05;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.064 c
15-1160773435
Иксик
2006-10-14 01:03
2006.11.05
Зотов


15-1161152975
Alien1769
2006-10-18 10:29
2006.11.05
Прошу помощь по физике /куда копать, источник, ссылку/


15-1160723593
Prohodil Mimo
2006-10-13 11:13
2006.11.05
WinXP Home и IIS


2-1161677938
parasolka
2006-10-24 12:18
2006.11.05
Завершение процедуры.


2-1160898769
Zhekson
2006-10-15 11:52
2006.11.05
как запрограммировать пульт ДУ?