Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
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
итак представление 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 Который возвращает следующее
Вот тут то и вопрос почему 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] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9646 |
Никогда не пишите в представлениях 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] Ответить | Цитировать Сообщить модератору |
Akina Member Откуда: Зеленоград, Москва, Россия Сообщений: 20973 |
У Вас LEFT JOIN. Так что для записей справа, не имеющих записей слева, LegalEntity.VATInclusive всё-таки NULL. |
24 мар 15, 10:34 [17423198] Ответить | Цитировать Сообщить модератору |
Akina Member Откуда: Зеленоград, Москва, Россия Сообщений: 20973 |
Так что лучше перепишите какCASE WHEN le.VATInclusive = 1 THEN bi.VAT ELSE 0 END AS [VATForFinance] |
24 мар 15, 10:36 [17423210] Ответить | Цитировать Сообщить модератору |
NG71 Member Откуда: Сообщений: 39 |
invm, Спасибо Большое - вероятнее так и было... выполнение exec sp_refreshview 'dbo.V_BudgetItem'; привело к ожидаемым результатам |
24 мар 15, 10:40 [17423223] Ответить | Цитировать Сообщить модератору |
NG71 Member Откуда: Сообщений: 39 |
Вы вероятно хотели сказать "Так что для записей СЛЕВА, не имеющих записей СПРАВА, 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] Ответить | Цитировать Сообщить модератору |
Владислав Колосов Member Откуда: Сообщений: 8350 |
Используйте create view ... with schemabinding, если хотите гарантий. |
24 мар 15, 11:30 [17423538] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |