Ошибка с SQLite (округляет числа в выборке)

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ошибка с SQLite (округляет числа в выборке)

Сообщение tria » 21.04.2015 11:23:19

Кусок кода:
Код: Выделить всё
 
var qS: TSQLQuery;
     SQLCon: TSQLite3Connection;
     trn:TSQLTransaction;

  qS.SQL.Add('SELECT A.Tov tovar_id, A.NumStrPrih numstrprih,');
  qS.SQL.Add('       sum(A.Kvo)  kvo  FROM DocsStr A');
  qS.SQL.Add('WHERE IdDoc=110');
  qS.SQL.Add('GROUP BY A.Tov,  A.NumStrPrih, A.Comment');

  qS.Open;

  while not qS.EOF do  begin
    s:='';
    for j := 0 to qs.FieldCount - 1 do begin
      s:=s+qs.Fields[j].FieldName+'='+qs.Fields[j].AsString+'  ';
    end;
    Memo1.Lines.Add(s);
    qS.Next;
  end;

Если в выборке первая запись kvo целое, то во всех остальных записях оно округляется до целого. А не должно!
Если дробное, то результат запроса такой, каким должен быть.
Если в запросе убрать суммирование/группирование, то результат правильный.
Тр..сь второй день...
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение Снег Север » 21.04.2015 20:01:22

А поле Kvo как определено в базе данных? Как double или integer?

Добавлено спустя 1 час 44 минуты 42 секунды:
В общем проверил у себя. SQLite позволяет без проблем писать дробные числа в поля, определенные как integer. Но для правильной обработки данных в функциях и пр. надо для поля использовать CAST(<имя> AS FLOAT)
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение tria » 22.04.2015 19:05:40

Тип поля kvo NUMERIC(12,3)

Извиняюсь, был занят...
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение Снег Север » 22.04.2015 20:10:56

tria писал(а):Тип поля kvo NUMERIC(12,3)
Извиняюсь, был занят...
всё равно попробуйте sum(CAST(A.Kvo AS FLOAT)) - должно сработать
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение pupsik » 22.04.2015 20:50:53

Колонка с цифровой (NUMERIC) средство может содержать значения, используя все пять классов хранения. Когда текстовые данные вставляются в числовой столбец, класс хранения текста преобразуется в целое или вещественное (в порядке предпочтения), если такое преобразование без потерь и обратимым. Для преобразования между текстовыми и реальных классов хранения, SQLite считает переход на без потерь и обратимым, если первые 15 значащих десятичных цифры номера сохраняются. Если преобразование без потерь текст, чтобы целого или вещественного невозможно, то значение сохраняется с использованием класса хранения TEXT. Никакая попытка не сделана, чтобы преобразовать NULL или BLOB значения.

Взято из: https://www.sqlite.org/datatype3.html

Если я правильно понимаю в sqilte есть только 3 типа поля:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
и то довольно витиевато. Мне особенно понравилось хранение даты. Черт ногу сломит :)
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение Снег Север » 23.04.2015 09:12:41

sqilte ИМХО даже чрезмерно либерален в сохранении данных всевозможных типов. Для несерверной базы, рассчитанной на работу с единственным приложением, это приемлемо, конечно. Оборотной стороной является перекладывание на программиста работы по правильной интерпретации данных.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение tria » 23.04.2015 09:25:24

Проблема в Лазаре. Тот же самый запрос в SQL админе выдает правильные цифири.
Задание типа поля до/после выполнения запроса тоже ничего не дало.
Код: Выделить всё
  qs.FieldDefs.Add('kvo', ftFloat);
  qs.FieldDefs[2].Precision:=3;
  qs.FieldDefs[2].Size:=13;

  qS.Open;

  qs.FieldDefs[2].DataType:=ftFloat;
  qs.FieldDefs[2].Precision:=3;
  ShowMessage(IntToStr(qs.FieldDefs[2].Precision));
  qs.FieldDefs[2].Size:=13;


Обращение к полю .AsFloat тоже возвращает целое...
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение Снег Север » 23.04.2015 09:57:35

Изменение поля в лазарусе и не может ничего вам дать. Или измените тип поля в таблице на REAL, или используйте в запросе CAST.
Тип NUMERIC - это, фактически, текстовое поле, вывод из которого преобразуется по загадочным законам кармы :)
Так что следите за результатом сами.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение pupsik » 23.04.2015 11:43:16

1.
Если в выборке первая запись kvo целое, то во всех остальных записях оно округляется до целого.

2. Я специально выделил:
(в порядке предпочтения)
.

Т.о. если первое число целое то и остальные будут считаться целым. Дык что странного в этом нет. Все согласно их вики :)

п.с.
Насчет бага в лазаре. Кто его знает что считать багом. То ли то что sqlite так сложен, то ли то что разрабы не сделали "исключение". Попробуйте зеос или мсе...
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: Ошибка с SQLite (округляет числа в выборке)

Сообщение tria » 24.04.2015 12:35:38

Помогло приведение к Real:
Код: Выделить всё
CAST(sum(A.Kvo) as Real)  kvo  FROM DocsStr A

Приведение к Numeric не помогало.
Большое спасибо Снег Север!
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 231

Рейтинг@Mail.ru