Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Работа с деньгами


Автор: Alca 17.8.2010, 12:44
C++Builder 2010, ODBC

Создаю таблицу:
Код

-- t_products.sql

CREATE TABLE t_products (
    f_product_id                SERIAL      NOT NULL,
    f_product_name              VARCHAR(32) NOT NULL,
    f_product_brand             VARCHAR(32) NOT NULL,
    f_product_size              VARCHAR(32) NOT NULL,
    f_product_measurement_units VARCHAR(32) NOT NULL,
    f_product_price             MONEY       NOT NULL,

    CONSTRAINT pk_product_id PRIMARY KEY(f_product_id)
);


Начинаю заполнять DBGrid. Когда в поле f_product_price вношу значение 55,55, получаю мсжбокс с такой ошибкой:
Цитата

ERROR: column "f_product_price" is of type money but expression is of type double precision;
Error while executing the query.

Как это лечиться?

Автор: azesmcar 17.8.2010, 13:03
Цитата(Alca @  17.8.2010,  12:44 Найти цитируемый пост)
55,55

может 55.55?

Автор: Alca 17.8.2010, 13:12
Цитата

может 55.55?

В данное поле точка вообще не пробивается

Автор: azesmcar 17.8.2010, 13:17
Цитата(Alca @  17.8.2010,  13:12 Найти цитируемый пост)
В данное поле точка вообще не пробивается 

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

Автор: Alca 17.8.2010, 13:30
Цитата

попробуй настроить Grid, какой разделитель он использует? 

Как я настрою DBGrid? ))) 

Цитата

возможно разделитель на клиенте и на PosgreSQL различаются.

клиент и сервер на одной машине

Точка пробивается, если поменять в настройках локали запятую на точку
(Панель управления \  Язык и региональные стандарты \ разделитель целой и дробной части), 
тогда вводиться с точкой, но ошибка таже

Добавлено через 2 минуты
Здесь http://www.postgresql.org/docs/8.3/static/datatype-money.html че-то написано - я не могу въехать 

Автор: azesmcar 17.8.2010, 13:32
Alca

А можно взглянуть на SQL запрос?

Автор: Alca 17.8.2010, 13:35
Цитата

А можно взглянуть на SQL запрос?

Код

SELECT * FROM t_products
  smile 

Автор: azesmcar 17.8.2010, 13:37
Если это 
Цитата(Alca @  17.8.2010,  12:44 Найти цитируемый пост)
ERROR: column "f_product_price" is of type money but expression is of type double precision;
Error while executing the query.

выдается при запуске запроса
Цитата(Alca @  17.8.2010,  13:35 Найти цитируемый пост)
SELECT * FROM t_products

тогда это не лечится.

Автор: skyboy 17.8.2010, 13:40
Цитата(azesmcar @  17.8.2010,  12:32 Найти цитируемый пост)
А можно взглянуть на SQL запрос? 

DBGrid - это такая негибкая хрештука, которая берет на себя формирование запросов. Их вообще проблемно выяснить. Т.е. добраться до уровня INSERT/UPDATE - сложная задача.
Думаю, есть смысл закинуть тему в C++: БАзы данных. Ибо решение может оказаться в настройке ODBC-подключения.

Добавлено через 1 минуту и 42 секунды
Alca, неужели ты думаешь, что при вставке значения в DBGrid для записи в базу используется SELECT запрос?  smile 

Автор: azesmcar 17.8.2010, 13:43
Цитата(skyboy @  17.8.2010,  13:40 Найти цитируемый пост)
DBGrid - это такая негибкая хрештука, которая берет на себя формирование запросов. Их вообще проблемно выяснить. Т.е. добраться до уровня INSERT/UPDATE - сложная задача.

Проблема может быть еще до этапа форматирования, для начала надо бы взглянуть на то, что можно а если не найдется - тогда смотреть на сгенерированный запрос через какой нибудь SQL monitor.

Добавлено через 57 секунд
Цитата(skyboy @  17.8.2010,  13:40 Найти цитируемый пост)
решение может оказаться в настройке ODBC-подключения.

вполне smile 

Автор: Alca 17.8.2010, 13:44
Цитата

выдается при запуске запроса

Нет. Мсжбокс вылазит при вставке данных. Т.е. я заношу данные в грид, делаю Post и потом ошибка. 

Автор: azesmcar 17.8.2010, 13:47
Цитата(Alca @  17.8.2010,  13:44 Найти цитируемый пост)
Нет. Мсжбокс вылазит при вставке данных. Т.е. я заношу данные в грид, делаю Post и потом ошибка.

я знаю, потому и написал

Цитата(azesmcar @  17.8.2010,  13:37 Найти цитируемый пост)
это не лечится

 smile 

покажи insert (update) запрос.

Автор: Alca 17.8.2010, 13:47
Коннекшн стринг:
Цитата

Provider=MSDASQL.1;Persist Security Info=False;User ID=admin;Mode=ReadWrite;Extended Properties="DRIVER={PostgreSQL Unicode};DATABASE=db_sklad;SERVER=127.0.0.1;PORT=5432;UID=admin;SSLmode=disable;ReadOnly=0;Protocol=7.4;FakeOidIndex=0;ShowOidColumn=0;RowVersioning=0;ShowSystemTables=0;ConnSettings=;Fetch=100;Socket=4096;UnknownSizes=0;MaxVarcharSize=255;MaxLongVarcharSize=8190;Debug=0;CommLog=0;Optimizer=0;Ksqo=1;UseDeclareFetch=0;TextAsLongVarchar=1;UnknownsAsLongVarchar=0;BoolsAsChar=1;Parse=0;CancelAsFreeStmt=0;ExtraSysTablePrefixes=dd_;LFConversion=1;UpdatableCursors=1;DisallowPremature=0;TrueIsMinus1=0;BI=0;ByteaAsLongVarBinary=0;UseServerSidePrepare=0;LowerCaseIdentifier=0;XaOpt=1";Initial Catalog=db_sklad


Добавлено через 2 минуты и 6 секунд
Цитата

покажи insert (update) запрос.

его нет, я делаю пост на DBNavigator-e

Автор: azesmcar 17.8.2010, 13:53
Его не может не быть, если ты его не писал - он будет сгенерирован (TableAdapter или как его там?).

Автор: Alca 17.8.2010, 13:58
Цитата

Его не может не быть, если ты его не писал - он будет сгенерирован (TableAdapter или как его там?).

Я ж не спорю. А где его посмотреть можно?

Автор: Alca 17.8.2010, 15:22
http://postgresql.ru.net/manual/datatype-money.html
Цитата

8.2. Денежные типы

Тип money хранит значения валюты с фиксированной дробной частью; см. Table 8-3. Точность дробной части определяется настройкой СУБД lc_monetary. Ввод значений допускается в нескольких разных форматах, включая целые числа и числа с плавающей точкой, также как и значения в типичном для валюты формате, такие как '$1,000.00'. Вывод значений обычно осуществляется в последней форме, но зависит от локали. Числовые значения без кавычек могут быть сконвертированы в тип money с помощью приведения числового значения к типу text, а затем к типу money, например: 
SELECT 1234::text::money;

Не существует простого способа выполнить обратное преобразование независимым от локали манером именованного приведённого значение типа money в какой-либо числовой тип. Если вы знаете какой символ валюты и разделитель тысяч используются, вы можете использовать regexp_replace(): 
SELECT regexp_replace('52093.89'::money::text, '[$,]', '', 'g')::numeric;


Поскольку вывод значений этого типа данных зависит от локали, загрузка данных типа money из одной в базу данных может не работать, если базы данных имеют разные настройки lc_monetary. Чтобы избежать проблем, перед восстановлением дампа в новую базу данных, убедитесь, что значение настроек lc_monetary такое же или эквивалентно значению в той базе данных, где выполнялся данный дамп.

Автор: Alca 17.8.2010, 15:43
Какой тип поля должен быть для хранения денежных величин? Случаем не double?

Автор: Akina 17.8.2010, 16:01
Цитата

Non-quoted numeric values can be converted to money by casting the numeric value to text and then money

Вместе с сообщением об ошибке это говорит о том, что у тебя как раз имеется этот самый "non-quoted numeric", который надо преобразовывать в money ручками.
Как - не скажу, даже не спрашивай. Бо не спец.

Автор: Platov 23.8.2010, 14:49
А что если твои 55.55 прогнать через такую функцию:
Код

//---------------------------------------------------------------------------
AnsiString __fastcall TForm1::ChangeSeparator(AnsiString s,char hs)
{
 AnsiString so=s;
  for(int i=1;i<=so.Length();i++)
   {
    if (so[i]==',' || so[i]=='.')
      {
       if (hs==NULL)
        so[i]=DecimalSeparator;
        else so[i]=hs;

      }
   }

 return so;
}
//---------------------------------------------------------------------------


С ораклом срабатывает.

Автор: mrbrooks 24.8.2010, 07:50
Цитата(Alca @  17.8.2010,  14:47 Найти цитируемый пост)
его нет, я делаю пост на DBNavigator-e 

этот контрол ничего не делает. все операции идут на уровне TXXXTable, через DataSource. Я так понимаю ты сгенирировал TTable (т.е. строго типизированным). Поэтому каждому полю должен соответствовать класс производный от TField. Соответственно для денежного типа должен быть свой. Кури его настройки.
Ты бы ради интереса попробывал INSERT. 
Честно говоря я бы использовал параметризованные запросы. Но это дело вкуса.

Добавлено через 17 секунд
А то и хранимые процедуры!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)