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

Вниз

Несовместимость типов Float в InterBase и типа Real в Delphi   Найти похожие ветки 

 
АТ   (2003-06-28 02:10) [0]

Скажем я пытаюсь выполнить динамический запрос:
INSERT INTO balance (IDBalance, VALUEBALANCE)
VAlUES(33, "12,2")

тип поля VALUEBALANCE - FLOAT

В результате такого добавления я получаю
поле VALUEBALANCE = 122,000

Если в запросе стоит точка:
INSERT INTO balance (IDBalance, VALUEBALANCE)
VAlUES(33, "12 .2")

то в результате добавления получаю
поле VALUEBALANCE = 12,2

Проблема в том, что мне надо получать число 12,2 через функцию FloatToStr а она в случае если в Windows в качестве десятичного разделителя проставлена запятая и поставит запятую. Т.е. выполнение запроса(где VarBalance:Real и равна 12,2):
"INSERT INTO balance (IDBalance, VALUEBALANCE)"+
"VAlUES(33, ""+FloatToStr(VarBalance)+"")"
приведет к неправильному добавлению данных.

Как разрешить эту ситуацию?
Я предполагаю, что приложение возможно будет стоять на машинах с запятой в качестве десятичного разделителя.


 
Zacho ©   (2003-06-28 10:30) [1]

Разрешить эту ситуацию можно двумя способами, и оба очень простые.
1. Почитать в хелпе про переменную DecimalSeparator
2. Вместо динамического формирования запроса использовать параметризированный запрос.
И еще - а ты уверен, что нужен именно FLOAT а не DOUBLE PRECISION или NUMERIC ?


 
KDS ©   (2003-06-28 12:26) [2]

>VAlUES(33, "12,2")

Если тип поля VALUEBALANCE - FLOAT
то зачем тогда 12,2 брать в двойные кавычки как строчный параметр?
Так его и передавай в БД как 12.2
используй функцию типа этой для замены запятой на точку
function ValidatePrice(const textPr:AnsiString):AnsiString;
begin
Result:=Trim(textPr);
if Result="" then Result:="0";
if DecimalSeparator="," // то менять на точку
then Result:=AnsiReplaceStr(Result,",",".")
end;

или вообще в конце модуля главной формы напиши конкретно:
initialization
DecimalSeparator:=".";
DateSeparator:=".";
ShortDateFormat:="dd.mm.yyyy";
end.

и теперь не будешь зависеть от настроек виндовз (MusdDie)


 
NDeu ©   (2003-06-28 17:02) [3]


> KDS © (28.06.03 12:26)


> ... не будешь зависеть от настроек виндовз


Неуважение юзера :(


 
kaif ©   (2003-06-29 04:02) [4]

1. В IB6.0 и его клонах в таких таблицах лучше использовать тип DECIMAL(18,2), а не FLOAT

2. В IB 5.* для денежных сумм никогда не надо использовать FLOAT - только DOUBLE PRECISION. Иначе столкнешься один день с большой проблемой потери точности при SELECT SUM()

3. Запросы должны быть параметризованными и в них никогда не следует передавать данные таким способом, как ты делаешь:

"INSERT INTO balance (IDBalance, VALUEBALANCE)"+
"VAlUES(33, ""+FloatToStr(VarBalance)+"")"


Правильно:

Q.SQL.Text := "INSERT INTO balance (IDBalance, VALUEBALANCE)"+
"VAlUES(:IDBalance, :ValueBalance)"
Q.PartamByName("IDBalance").AsInteger := 33;
Q.PartamByName(ValueBalance).AsCurrency := 12.2;
Q.ExecSQL;

где Q - компонент запроса.

Особенно опасен твой способ при работе с датами. Достаточно изменить настройку форматирования даты в Windows с dd.mm.yy на mm/dd/yy и у тебя все полетит к черту.


 
Zacho ©   (2003-06-30 00:15) [5]


> KDS © (28.06.03 12:26)

Ну и зачем лишний IF ? Все гораздо проще:
function ValidatePrice(const textPr:AnsiString):String;
begin
Result:=AnsiReplaceStr(textPr,DecimalSeparator,".")
end;

Вот и вся функция :-)
А насчет:
> или вообще в конце модуля главной формы напиши конкретно:
Далее SKIP ...

У меня, например, такая программа быстро окажется в корзине.


 
АТ   (2003-06-30 17:11) [6]

>Zacho
>У меня, например, такая программа быстро окажется в корзине.

Почему?


 
Zacho ©   (2003-06-30 19:57) [7]


> АТ (30.06.03 17:11)

Потому что программа не должна быть "умнее" пользователя, и ни в коем случае не должна менять пользовательские настройки системы. Если у меня разделитель целой и дробной части стоит "," (или " " например) - значит так мне нужно, а если автор какой-то там программы думает, что лучше меня знает, что мне нужно - этой программе прямая дорога в корзину.


 
venoel   (2003-07-02 23:38) [8]

>> Zacho
5 баллов.


 
kaif ©   (2003-07-03 02:13) [9]

2 Zacho © (30.06.03 19:57)
Кстати, Zacho, вот Вы - мыслящий человек. Скажите мне, пожалуйста, почему в Windows 2000 и Windows XP в русских региональных стандартах разделитель тысячных вовсе не пробел (32), а какая-то хрень (160). Я на днях столкнулся с очень большими проблемами при DDE обмене с Excel, в котором разделитель тысячных - нормальный пробел. Когда я локализовал проблему и обнаружил, что ThousandSeparator не равен chr(32), а равен chr(160), хоть и выглядит в Control Panel как пробел, я зашел в Control Panel, забил тот "пробел", что там был и вставил норамьныхй пробел. Все заработало.
Проблема в том, что мне сейчас это приходится делать на всех клинтских компьютерах заказчика...
И я не уверен, что действую верно. Ведь должно быть какое-то научное объяснение у этого парадокса (160 вместо 32)?
Я понимаю, что это off-topic, но просто раз уж зашла речь о региональных настройках...


 
Alexandr ©   (2003-07-03 07:07) [10]

может быть это "неразрывный пробел"
что-то такое я в word видел...


 
Zacho ©   (2003-07-03 09:00) [11]


> kaif © (03.07.03 02:13)

Насчет chr(160) - ничего сказать не могу, не знаю.
Хочу немного уточнить свое высказывание от (30.06.03 19:57).
Программа не должна менять пользовательские настройки, но она должна их учитывать. И если для работы программы необходимо, чтобы DecimalSeparator был ".", то сделать AnsiReplaceStr(MyVar,DecimalSeparator,".") - прямая обязанность программиста.


 
kaif ©   (2003-07-03 18:57) [12]

2 Alexandr © (03.07.03 07:07)
Спасибо большое! Это действительно неразрывный пробел #160 :(
см.
http://www.iro.yar.ru:8101/partners/peresl/sidorov/nzam17.htm
Но как так получается, что в русских Региональных Настройках он установлен в качестве разделителя тычсяч, а Microsoft Excel его не понимает и хочет в форматах видеть обычный пробел?
видно мне придется еще исследовать Office поподробнее и я пока не уверен, что найду оптимальное решение...


 
Alexandr ©   (2003-07-04 06:24) [13]

1)
тут надо версии смотреть...
какой ОС, какой эксель...
2) DDE тоже может повлиять...
3) ReplaceStr не поможет?



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

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

Наверх




Память: 0.5 MB
Время: 0.014 c
14-91824
Soft
2003-07-10 14:44
2003.07.28
Как на С, не C++ полуить место, занимаемое структурой?


14-91884
MishaS
2003-07-11 18:22
2003.07.28
Где найти сайты посвящённые программированию на C++ Builder


3-91621
Step[B.M.]
2003-07-04 08:51
2003.07.28
Как организовать цикл по записям в процедуре InterBase


14-91820
XobBIT
2003-07-10 13:50
2003.07.28
Мастера подскажите, откуда берете иконки для программ


8-91777
БРУТЪ
2003-04-03 14:57
2003.07.28
Преобразование