Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Представление выдает не те данные что ожидаются  [new]
NG71
Member

Откуда:
Сообщений: 39
Доброе утро.
Cтолкнулся с проблемой и не знаю как объяснить происходящее. Помогите плс в чем может быть дело.
Итак речь пойдет о представлении dbo.V_BudgetItem и его значении поля VATForFinance

вот само представление

CREATE VIEW [dbo].[V_BudgetItem]
AS
SELECT bi.*,
CASE WHEN (le.VATInclusive = 1 AND bi.VATApplicable = 1) THEN 1
ELSE 0 END AS VATApplicableForFinance,
CASE WHEN le.VATInclusive = 0 THEN 0
	ELSE bi.VAT END AS [VATForFinance]
FROM BudgetItem bi
LEFT JOIN LegalEntity le on le.Id = bi.LegalEntityToPayId


Значение поля VATForFinance зависит от le.VATInclusive и от bi.VAT. Поле LegalEntity.VATInclusive bit not null и в БД имеет значения и 0 и 1. Таким образом можно сказать что VATForFinance может принимать значения либо 0 либо bi.VAT

посмотрим все возможные значения в таблице BudgetItem bi

select distinct bi.VAT from BudgetItem bi

VAT
18.00
20.00


итак представление VATForFinance может возвращать значения 0 или 18 или 20

Но есть запрос построенный на основе этого представления

SELECT bi.id, bi.VAT, bi.VATForFinance
FROM  dbo.V_BudgetItem bi
WHERE bi.VATForFinance != 0 AND bi.VATForFinance != bi.VAT


Который возвращает следующее
id VAT VATForFinance
F230C937-5F3F-4687-9616-C7432DB37C01 18.00 847.4576


Вот тут то и вопрос почему VATForFinance = 847.4576 а не 18?

Сам код представления был взят из базы.
Такая ситуация наблюдалась на нескольких локальных машинах разработчиков у которых локально поднята эта база для разработки.. Точна такая же проблема была и на боевом сервере. Но там быстро устранили сие безобразие путем перепроведения того же вью, повторяюсь взятого из той же самой БД.

После этого я забрал бекап у одного из разработчиков и поднял у себя локально. Ситуация воспроизводится.. Но лечится путем перепроведения представления!

Итак если выполнить код самого представления то результат ожидаемый, а если выполнить запрос на основе вью - то результат не ожидаемый. И еще представление не индексированное. В коде представления используются таблицы.
В базе используется только одна схема dbo. Синонимов нет. Проверил на существование "дубликатов" используемых объектов (ну в смысле проверил все названия на отсутствие в них не латинских символов)

Подскажите плс в чем может быть проблема. Что стоит за таким поведением? И Самое главное как избежать этого в дальнейшем?

Локально у меня система такая:
Microsoft SQL Server 2012 - 11.0.2218.0 (X64)
Jun 12 2012 13:05:25
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: )

На бою тоже Microsoft SQL Server 2012 но какой именно релиз пока не знаю
24 мар 15, 10:13    [17423066]     Ответить | Цитировать Сообщить модератору
 Re: Представление выдает не те данные что ожидаются  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
Никогда не пишите в представлениях select *. Потому что происходит у вас, скорее всего, примерно следующее:
use tempdb;
go

create table dbo.t (id int primary key, v1 int, v2 int);
insert into dbo.t values (1, 1, 2);
go

create view dbo.vt
as
select * from dbo.t;
go

select v1 from dbo.vt;
go

drop table dbo.t
create table dbo.t (id int primary key, v2 int, v1 int);
insert into dbo.t values (1, 2, 1);
go

select v1 from dbo.vt;
go

exec sp_refreshview 'dbo.vt';
select v1 from dbo.vt;
go

drop view dbo.vt;
drop table dbo.t;
go
24 мар 15, 10:30    [17423177]     Ответить | Цитировать Сообщить модератору
 Re: Представление выдает не те данные что ожидаются  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21483
У Вас LEFT JOIN. Так что для записей справа, не имеющих записей слева, LegalEntity.VATInclusive всё-таки NULL.
24 мар 15, 10:34    [17423198]     Ответить | Цитировать Сообщить модератору
 Re: Представление выдает не те данные что ожидаются  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21483
Так что лучше перепишите как

CASE WHEN le.VATInclusive = 1 THEN bi.VAT ELSE 0 END AS [VATForFinance]
24 мар 15, 10:36    [17423210]     Ответить | Цитировать Сообщить модератору
 Re: Представление выдает не те данные что ожидаются  [new]
NG71
Member

Откуда:
Сообщений: 39
invm,

Спасибо Большое - вероятнее так и было...
выполнение exec sp_refreshview 'dbo.V_BudgetItem'; привело к ожидаемым результатам
24 мар 15, 10:40    [17423223]     Ответить | Цитировать Сообщить модератору
 Re: Представление выдает не те данные что ожидаются  [new]
NG71
Member

Откуда:
Сообщений: 39
Akina
У Вас LEFT JOIN. Так что для записей справа, не имеющих записей слева, LegalEntity.VATInclusive всё-таки NULL.



Вы вероятно хотели сказать "Так что для записей СЛЕВА, не имеющих записей СПРАВА, LegalEntity.VATInclusive всё-таки NULL"

Но не в этом суть. Для данного случая и для данного ID который появился как не ожидаемый запись в LegalEntity есть и LegalEntity.VATInclusive имеет значение 1

Теперь к примеру рассмотрим если записи в LegalEntity нет - то значение

CASE WHEN le.VATInclusive = 0 THEN 0 ELSE bi.VAT END AS [VATForFinance] будет равным 18
в Вашем же случае
CASE WHEN le.VATInclusive = 1 THEN bi.VAT ELSE 0 END AS [VATForFinance] будет равным 0

Но это уже на откуп Бизнес логики.. Согласен с точки зрения бизнес логики наверное так будет логичней..Но это на откуп разработчикам ... Меня больше беспокоило почему значение было равным 847.4576 а не 18

Кстати как раз среди полей этого вью для этого Id есть поле с другим именем значение которого равно 847.4576
Еще раз всем Спасибо
24 мар 15, 11:04    [17423378]     Ответить | Цитировать Сообщить модератору
 Re: Представление выдает не те данные что ожидаются  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 9155
Используйте create view ... with schemabinding, если хотите гарантий.
24 мар 15, 11:30    [17423538]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить