Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Странное поведение ХП  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
Добрый день, уважаемые.
Есть процедура синхронизации данных между двумя БД.
В первой БД есть таблица со значением цены товара в рублях, которая должна вставиться во вторую БД в долларах.
Заполняется поле второй БД след. образом:
INSERT INTO BIMain.dbo.TTNSellGoods
          (Id_TTNSellGoods,
           Cost)
        SELECT
          tg.Id_TTNSellGoods,
          ROUND(CAST(ISNULL(tg.Price, 0) AS FLOAT) / dbo.GetCurrencyRateBYR2USD('2013-08-09 00:00:00'), 4)
        FROM   
          TTNSellGoods tg

Функция dbo.GetCurrencyRateBYR2USD возвращает значение курса - тип INT
Обя поля tg.Price и Cost типа MONEY
Значение tg.Price = 3445,00
Функция dbo.GetCurrencyRateBYR2USD('2013-08-09 00:00:00') = 8880
После работы ХП в поле Cost записывается значение 0,3879
При выполнении
SELECT ROUND(CAST(ISNULL(tg.Price, 0) AS FLOAT) / BIMain.dbo.GetCurrencyRateBYR2USD('2013-08-09 00:00:00.000'), 4)

возвращает 0,388 - значение, которое мне и нужно

Далее вручную выполняю:
UPDATE TTNSellGoods
SET	Cost = ROUND(CAST(ISNULL(tg2.Price, 0) AS FLOAT) / BIMain.dbo.GetCurrencyRateBYR2USD('2013-08-09 00:00:00.000'), 4) 
FROM TTNSellGoods tg
JOIN BIBuffer.dbo.TTNSellGoods tg2 ON tg2.Id_TTNSellGoods = tg.Id_TTNSellGoods
AND tg2.Id_CompanyDB = tg.Id_CompanyDB
WHERE tg.Id_TTNSellGoods = 4146658 AND tg.Id_CompanyDB = 12

и получаю заполненное значение 0,388

Так вот вопрос: почему процедура пишет одно значение, а при апдейте - другое?
23 авг 13, 12:55    [14747146]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Glory
Member

Откуда:
Сообщений: 104751
А почему CAST(ISNULL(tg.Price, 0) AS FLOAT ?
23 авг 13, 13:05    [14747225]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
имхо слишком много преобразований типов

  (Id_TTNSellGoods,
           Cost)
        SELECT
          tg.Id_TTNSellGoods,
          ROUND(CAST(ISNULL(tg.Price, 0) AS FLOAT) / dbo.GetCurrencyRateBYR2USD('2013-08-09 00:00:00'), 4)

3 преобразования money-float-money

SELECT ROUND(CAST(ISNULL(tg.Price, 0) AS FLOAT) / BIMain.dbo.GetCurrencyRateBYR2USD('2013-08-09 00:00:00.000'), 4)

2 преобразования money-float
23 авг 13, 13:14    [14747298]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
а кстати, почему round( ,4) а не round(,3) если
автор
возвращает 0,388 - значение, которое мне и нужно
23 авг 13, 13:21    [14747335]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
Мистер Хенки
а кстати, почему round( ,4) а не round(,3) если
возвращает 0,388 - значение, которое мне и нужно


3445 / 8880 = 0.3879504504504505
Округляем до 4 знаков - получаем 0.3880 = 0.388
Может быть и другое значение, например, 0.9414268, котрое нужно округлить и получить 0.9414

Glory
А почему CAST(ISNULL(tg.Price, 0) AS FLOAT ?

Если ставлю MONEY, то получаю 0.3879, что не есть верно

ROUND(CAST(ISNULL(tg2.Price, 0) AS FLOAT) / BIMain.dbo.GetCurrencyRateBYR2USD('2013-08-09 00:00:00.000'), 4)

возвращает верное значение 0.388
Мне терзает вопрос, почему эта срока находясь в процедуре заносит значение 0.3879? Вот этого не могу понять.
23 авг 13, 13:41    [14747462]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3752
BuKTaP
Функция dbo.GetCurrencyRateBYR2USD возвращает значение курса - тип INT

перформанс не беспокоит?
23 авг 13, 13:41    [14747463]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Glory
Member

Откуда:
Сообщений: 104751
BuKTaP
Glory
А почему CAST(ISNULL(tg.Price, 0) AS FLOAT ?

Если ставлю MONEY, то получаю 0.3879, что не есть верно

И по каким критериям оно не верно ?
деление в калькуляторе дает 0.38795045045045045045045045045045
23 авг 13, 13:43    [14747473]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Glory
Member

Откуда:
Сообщений: 104751
BuKTaP
Мне терзает вопрос, почему эта срока находясь в процедуре заносит значение 0.3879? Вот этого не могу понять.

Потому что вы себе очень примитивно представляете процесс выполнения запроса и вычисления выражений.
Тем более для чисел с плавающей точкой
Любое промежуточное математическое действие и даже конвертирование ведет к измению типа данных
23 авг 13, 13:46    [14747485]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
> Мне терзает вопрос, почему эта срока находясь в процедуре заносит значение 0.3879? Вот этого не могу понять.

не эта строка. или не в этой процедуре.
23 авг 13, 13:47    [14747489]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3752
все дело в типе поля Cost в таблице BIMain.dbo.TTNSellGoods.
23 авг 13, 13:48    [14747496]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
Glory, ну так округление же до 4-х знаков. Или округление и отсечение уже синонимы?
После 0.3879 идёт 5, что даёт нам право увеличить 79 на 1 и получить 0.3880. Или нет?
Есть, конечно, предположение, что из-за того, что типа поля MONEY для него применяется так называетмое "бухгалтерское" округление, когда для 5 значение не увеличивается. Мысль?

Ivan Durak, не беспокоит. В реальности естественно значение функции присваивается переменной типа INT и используется именно она, так что постоянного выполнения функции не происходит. Здесь так написал для краткости.
23 авг 13, 13:49    [14747503]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Glory
Member

Откуда:
Сообщений: 104751
BuKTaP
Glory, ну так округление же до 4-х знаков.

Округление чего ?
Вы считаете, что после CAST(ISNULL(tg2.Price, 0) AS FLOAT) ваш тип данных по-прежнему money с 4 знаками после запятой ?
23 авг 13, 13:50    [14747510]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
BuKTaP
3445 / 8880 = 0.3879504504504505
Округляем до 4 знаков - получаем 0.3880 = 0.388
Может быть и другое значение, например, 0.9414268, котрое нужно округлить и получить 0.9414


выбираете тип для хранения с 4 знаками после запятой, а хотите учитывать 5
23 авг 13, 13:53    [14747517]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
o-o
Guest
увольте float, преобразуйте в явный decimal(19,4)
declare @Price money = 3445,
        @GetCurrencyRateBYR2USD int = 8880,
        @Cost money;
        
select @Cost = ROUND(cast(ISNULL(@Price, 0) as decimal(19,4)) / @GetCurrencyRateBYR2USD, 4);
select @Cost
-----------------------
0.388
23 авг 13, 13:59    [14747566]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
o-o
Guest
BuKTaP
ну так округление же до 4-х знаков. Или округление и отсечение уже синонимы?
После 0.3879 идёт 5, что даёт нам право увеличить 79 на 1 и получить 0.3880. Или нет?
Есть, конечно, предположение, что из-за того, что типа поля MONEY для него применяется так называетмое "бухгалтерское" округление, когда для 5 значение не увеличивается. Мысль?


нет.
просто когда Вы оперируете money + int:

The precision and scale of the numeric data types besides decimal are fixed. If an arithmetic operator has two expressions of the same type, the result has the same data type with the precision and scale defined for that type. If an operator has two expressions with different numeric data types, the rules of data type precedence define the data type of the result. The result has the precision and scale defined for its data type.

т.е. можно было и вовсе не округлять, работая с money, все равно в результате будет money:
declare @Price money = 3445,
        @GetCurrencyRateBYR2USD int = 8880,
        @Cost money;
        
select ISNULL(@Price, 0) / @GetCurrencyRateBYR2USD,
       SQL_VARIANT_PROPERTY(ISNULL(@Price, 0) / @GetCurrencyRateBYR2USD, 'Basetype');
----------------------
0.3879	money



ну и кто сказал, что будет округление? отсечение и будет, так же как и в случае int / int,
Вы же не удивляетесь результату:

select 1 / 2
-----------------
0

результат деления целого на целое тоже целое, но никакого округления не происходит.

другое дело, когда один из типов DECIMAL.
тогда смотрим таблицу высчитывания Precision, Scale, and Length (Transact-SQL)
23 авг 13, 14:29    [14747788]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
Я понимаю, что после CAST(ISNULL(tg2.Price, 0) AS FLOAT) типа MONEY не остаётся.
Но всё-таки INSERT из процедуры
ROUND(CAST(ISNULL(tg.Price, 0) AS FLOAT) / BIMain.dbo.GetCurrencyRateBYR2USD('2013-08-09 00:00:00.000'), 4)

вставляет как 0.3879, а такой же UPDATE в то же поле - 0.388. Почему так?

И опять же вопрос: есть ли вероятность, что тип MONEY, предназначенный для денег и, соответственно, бухгалтерии, округляется по бухгалтерскому методу, а не по математическому???
23 авг 13, 14:56    [14747992]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
o-o
Guest
BuKTaP,

а сделайте одолжение, вставьте ту же (Вашу, с функцией) строку в #tmp
create table #tmp (cost money);


а то у меня все работает а Вашего я не вижу
declare @Price money = 3445,
        @GetCurrencyRateBYR2USD int = 8880,
        @Cost money;
        
create table #tmp (cost money);
        
insert into #tmp(cost) 
select ROUND(CAST(ISNULL(@Price, 0) as float) / @GetCurrencyRateBYR2USD, 4);
       
select *
from #tmp
------------
0.388
23 авг 13, 15:08    [14748122]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
В том и дело, что делал я так и получал нужный результат.
А ХП вставляет неверные данные!
23 авг 13, 15:15    [14748189]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Glory
Member

Откуда:
Сообщений: 104751
BuKTaP
А ХП вставляет неверные данные!

Неверными они являются потому, что ваш код неверен.
Исправляйте свой код.
23 авг 13, 15:22    [14748245]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
Glory, вы несомненно сильны в сиквеле, но в большинстве ваших сообшений я заметил ещё и высокий уровень троллинга. И я не один заметил.
В аттаче скрин, что процедура вставила одно значение, а селект выдаёт другое.
Вроде ж на русском пишу...

К сообщению приложен файл. Размер - 48Kb
23 авг 13, 15:43    [14748365]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
> В аттаче скрин, что процедура вставила одно значение, а селект выдаёт другое.

откуда вы знаете, что это значение вставил именно тот запрос (и в той процедуре), который вы привели?
23 авг 13, 15:46    [14748376]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Glory
Member

Откуда:
Сообщений: 104751
BuKTaP
Glory, вы несомненно сильны в сиквеле, но в большинстве ваших сообшений я заметил ещё и высокий уровень троллинга. И я не один заметил.
В аттаче скрин, что процедура вставила одно значение, а селект выдаёт другое.
Вроде ж на русском пишу...

Вы упорно пытаетесь доказать, что сервер должен производить преобразование типов, округление и усечение по-вашему. В то время, как у сервера для всего этого уже есть методы.
Так что троллите пока вы
23 авг 13, 15:46    [14748378]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
o-o
Guest
инсерт идет кривой только через хп?
или только в эту таблицу?
ручной инсерт туда же правильно вставляет?

если только в эту таблицу, смотрите триггеры, вообще заскриптуйте создание таблицы,
может все же тип другой у поля.
если это хп.
приведите тут ее полный текст.
или сделайте копию хп, где переправьте вставку, сделайте в другую таблицу,
вставьте в новую пустую и расскажите, то же самое делает или нет
23 авг 13, 15:53    [14748414]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
BuKTaP
Member

Откуда:
Сообщений: 132
автор
откуда вы знаете, что это значение вставил именно тот запрос (и в той процедуре), который вы привели?

Потому что это единственная процедура, в которой есть один единственный запрос.

автор
Вы упорно пытаетесь доказать, что сервер должен производить преобразование типов, округление и усечение по-вашему. В то время, как у сервера для всего этого уже есть методы.

Я ничего не пытаюсь доказать. Я пытаюсь выяснить, почему так произошло. Вы можете внятно объяснить, почему вставило одно значение, хотя селект выдаёт другое?
Я понимаю, что воспроизвести это не представляется возможным, т.к. при попытке мы получаем верный результат (при вставке во временную таблицу). Но тот факт, что данные вставились не те, которые возвращает запрос, очевиден.
23 авг 13, 15:53    [14748415]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение ХП  [new]
Glory
Member

Откуда:
Сообщений: 104751
BuKTaP
Я ничего не пытаюсь доказать. Я пытаюсь выяснить, почему так произошло. Вы можете внятно объяснить, почему вставило одно значение, хотя селект выдаёт другое?

Потому что вы, именно вы, написали такой код.
Другой причины нет.

BuKTaP
Я понимаю, что воспроизвести это не представляется возможным, т.к. при попытке мы получаем верный результат (при вставке во временную таблицу). Но тот факт, что данные вставились не те, которые возвращает запрос, очевиден.

Вам на Рен-ТВ надо. В передачу о мистических событиях.
Если вы не можете это воспроизвести, то этого нет.
23 авг 13, 15:56    [14748437]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить