- 001
- 002
- 003
- 004
- 005
- 006
- 007
- 008
- 009
- 010
- 011
- 012
- 013
- 014
- 015
- 016
- 017
- 018
- 019
- 020
- 021
- 022
- 023
- 024
- 025
- 026
- 027
- 028
- 029
- 030
- 031
- 032
- 033
- 034
- 035
- 036
- 037
- 038
- 039
- 040
- 041
- 042
- 043
- 044
- 045
- 046
- 047
- 048
- 049
- 050
- 051
- 052
- 053
- 054
- 055
- 056
- 057
- 058
- 059
- 060
- 061
- 062
- 063
- 064
- 065
- 066
- 067
- 068
- 069
- 070
- 071
- 072
- 073
- 074
- 075
- 076
- 077
- 078
- 079
- 080
- 081
- 082
- 083
- 084
- 085
- 086
- 087
- 088
- 089
- 090
- 091
- 092
- 093
- 094
- 095
- 096
- 097
- 098
- 099
- 100
ALTER PROCEDURE [dbo].[prodam_Получить_Начисления_По_ЛС]
@кодЛС uniqueidentifier,
@дата date,
@источникНачислений nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
IF @источникНачислений = 'AccountCharge_Lain'
BEGIN
SELECT
CAST(MONTH(@дата) as nvarchar(2))+'.'+CAST(YEAR(@дата) as nvarchar(4)) as 'Расчетный период'
,ach.ID as 'Начисление'
,suc.Title as 'Услуга'
,ach.[Formula] as 'Формула'
,ach.[FormulaWithValues] as 'Формула со значениями'
,CAST(ach.[SumOfPaymentEnteredTheLastMonth] as decimal(19,2)) as 'Оплаты поступившие в предыдущем месяце (руб.)'
,CAST(ach.[SumOfRecalculationForTheLastMonth]as decimal(19,2)) as 'Перерасчет за предыдущий период (руб.)'
,CAST(ach.[SumOfDebtOrOverpayment]as decimal(19,2)) as 'Долг (+), переплата (-) (руб.)'
,um.Title as 'Единица измерения (по нормативу / приборам учета)'
,CAST(ach.[SumOfTariffForUnitOfService]as decimal(19,2)) as 'Тариф за единицу услуги (руб.)'
,CAST(ach.[SumOfChargeForMonthUnderTheTariff]as decimal(19,2)) as 'Начислено за месяц по тарифу (руб.)'
,CAST(ach.[SumOfShortShipmentOfService]as decimal(19,2)) as 'Сумма недопоставки (руб.)'
,CAST(ach.[SumOfPaymentInViewOfShortShipment]as decimal(19,2)) as 'Начислено к оплате с учетом недопоставки (руб.)'
,CAST(ach.[AmountOfDaysOfShortShipmentOfService]as decimal(19,2)) as 'Недопоставка услуг (дней)'
,suc.ID as 'ID'
FROM
[RegionDBNew].[dbo].Account acc
INNER JOIN [RegionDBNew].[dbo].[AccountCharge_Lain] ach ON
ach.CalculationYear = YEAR(@дата) AND
ach.CalculationMonth = MONTH(@дата) AND
ach.AccountID = acc.ID
LEFT JOIN [RegionDBNew].[dbo].UnitOfMeasure um ON ach.[UnitOfMeasureID] = um.ID
LEFT JOIN [RegionDBNew].[dbo].[ServiceUnderAccount] suc ON suc.ID = ach.ServiceUnderAccountID
WHERE
acc.ID = @кодЛС
ORDER BY
suc.Title;
END
ELSE IF @источникНачислений = 'AccountCharge_Prodam'
BEGIN
SELECT
CAST(MONTH(@дата) as nvarchar(2))+'.'+CAST(YEAR(@дата) as nvarchar(4)) as 'Расчетный период'
,ach.ID as 'Начисление'
,suc.Title as 'Услуга'
,ach.[Formula] as 'Формула'
,ach.[FormulaWithValues] as 'Формула со значениями'
,CAST(ach.[SumOfPaymentEnteredTheLastMonth] as decimal(19,2)) as 'Оплаты поступившие в предыдущем месяце (руб.)'
,CAST(ach.[SumOfRecalculationForTheLastMonth] as decimal(19,2)) as 'Перерасчет за предыдущий период (руб.)'
,CAST(ach.[SumOfDebtOrOverpayment] as decimal(19,2)) as 'Долг (+), переплата (-) (руб.)'
,um.Title as 'Единица измерения (по нормативу / приборам учета)'
,CAST(ach.[SumOfTariffForUnitOfService] as decimal(19,2)) as 'Тариф за единицу услуги (руб.)'
,CAST(ach.[SumOfChargeForMonthUnderTheTariff] as decimal(19,2)) as 'Начислено за месяц по тарифу (руб.)'
,CAST(ach.[SumOfShortShipmentOfService] as decimal(19,2)) as 'Сумма недопоставки (руб.)'
,CAST(ach.[SumOfPaymentInViewOfShortShipment] as decimal(19,2)) as 'Начислено к оплате с учетом недопоставки (руб.)'
,CAST(ach.[AmountOfDaysOfShortShipmentOfService] as decimal(19,2)) as 'Недопоставка услуг (дней)'
,suc.ID as 'ID'
FROM
[RegionDBNew].[dbo].Account acc
INNER JOIN [RegionDBNew].[dbo].[AccountCharge_Prodam] ach ON
ach.CalculationYear = YEAR(@дата) AND
ach.CalculationMonth = MONTH(@дата) AND
ach.AccountID = acc.ID
LEFT JOIN [RegionDBNew].[dbo].UnitOfMeasure um ON ach.[UnitOfMeasureID] = um.ID
LEFT JOIN [RegionDBNew].[dbo].[ServiceUnderAccount] suc ON suc.ID = ach.ServiceUnderAccountID
WHERE
acc.ID = @кодЛС
ORDER BY
suc.Title;
END
ELSE IF @источникНачислений = 'AccountCharge'
BEGIN
SELECT
CAST(MONTH(@дата) as nvarchar(2))+'.'+CAST(YEAR(@дата) as nvarchar(4)) as 'Расчетный период'
,ach.ID as 'Начисление'
,suc.Title as 'Услуга'
,ach.[Formula] as 'Формула'
,ach.[FormulaWithValues] as 'Формула со значениями'
,CAST(ach.[SumOfPaymentEnteredTheLastMonth] as decimal(19,2)) as 'Оплаты поступившие в предыдущем месяце (руб.)'
,CAST(ach.[SumOfRecalculationForTheLastMonth] as decimal(19,2)) as 'Перерасчет за предыдущий период (руб.)'
,CAST(ach.[SumOfDebtOrOverpayment] as decimal(19,2)) as 'Долг (+), переплата (-) (руб.)'
,um.Title as 'Единица измерения (по нормативу / приборам учета)'
,CAST(ach.[SumOfTariffForUnitOfService] as decimal(19,2)) as 'Тариф за единицу услуги (руб.)'
,CAST(ach.[SumOfChargeForMonthUnderTheTariff] as decimal(19,2)) as 'Начислено за месяц по тарифу (руб.)'
,CAST(ach.[SumOfShortShipmentOfService] as decimal(19,2)) as 'Сумма недопоставки (руб.)'
,CAST(ach.[SumOfPaymentInViewOfShortShipment] as decimal(19,2)) as 'Начислено к оплате с учетом недопоставки (руб.)'
,CAST(ach.[AmountOfDaysOfShortShipmentOfService] as decimal(19,2)) as 'Недопоставка услуг (дней)'
,suc.ID as 'ID'
FROM
[RegionDBNew].[dbo].Account acc
INNER JOIN [RegionDBNew].[dbo].[AccountCharge] ach ON
ach.CalculationYear = YEAR(@дата) AND
ach.CalculationMonth = MONTH(@дата) AND ach.CalculationMonth = MONTH(@дата) AND
ach.AccountID = acc.ID
LEFT JOIN [RegionDBNew].[dbo].UnitOfMeasure um ON ach.[UnitOfMeasureID] = um.ID
LEFT JOIN [RegionDBNew].[dbo].[ServiceUnderAccount] suc ON suc.ID = ach.ServiceUnderAccountID
WHERE
acc.ID = @кодЛС
ORDER BY
suc.Title;
END
guest 08.02.2013 11:58 # +1
sciner 08.02.2013 12:54 # 0
3.14159265 08.02.2013 15:34 # +2
- "мкей", отвечали они и продолжали ебошить.
Даже не смешно.
>ach.CalculationMonth = MONTH(@дата) AND ach.CalculationMonth = MONTH(@дата) AND
АдЪ.
eth0 08.02.2013 19:35 # 0
Ну и упоротые алиасы, тоже сурово.
RaZeR 09.02.2013 15:44 # 0
Не продаст. Надеюсь.
DBdev 11.02.2013 17:18 # +1
- архитектура базы хромает, раз за одними и теми же полями надо лазить в 3 разные таблицы
- ужасный нейминг со смесью кириллицы и латиницы
- бизнесс-алиасы полям задаются на уровне хранимы, а не на уровне юзер-интерфейса
Из озвученного выше:
- с запятыми перед полями жить можно и даже для дебага полезно (очень легко поставив -- исключить поле из выборки. Зачем вначале запятые ставить? Чаще изменения случаются с последними элементами, а не первыми)
- 92 строку оптимизатор запросов все-равно преобразует в единое условие
Итого, как заключение - бить надо рахитектора. Разработчик выкрутился, как смог. Если разработчик этого и является рахитектором решения - бить разработчика.
eth0 12.02.2013 19:58 # −1
Отлаживать комментированием - плохая практика.
3.14159265 11.02.2013 17:37 # 0
Безусловно.
> архитектура базы хромает, раз за одними и теми же полями надо лазить в 3 разные таблицы
> Разработчик выкрутился, как смог
Можно было не копипастить - создать сводную временную таблицу или если противник temp table(о ужас!) использовать exec
3.14159265 11.02.2013 17:44 # 0
Или with какой-нибудь. В ms sql давно добавили.
>[dbo].[prodam_Получить_Начисления_По_ЛС]
> @кодЛС uniqueidentifier,
> @дата date,
> @источникНачислений nvarchar(50)
Та это как в быдлоexcelе или 1C.
DBdev 11.02.2013 19:09 # 0
3.14159265 11.02.2013 19:20 # 0
Да. Согласен. С точки зрения производительности оно-то оптимально, но там ошибиться просто негде.
А как такое сопровождать?
Программист оттачивает технику копипаста, и потом 16 раз такое накопировано, 32 раза итд?
>динамика - незакешированный запрос
В большинстве случаев это некритично, доли секунды на компиляцию планов стоят меньше чем труд программиста, которому потом поддерживать.
>отбросим знания with
Не надо. Они тут очень кстати.
DBdev 11.02.2013 19:35 # 0
ЗЫ Я там ошибку допустил - "незакешированный запрос" = "незакешированный план запроса", но меня поняли ;)
ЗЗЫ И все-таки не стоит думать, что все знают динамику и конструкцию with.
3.14159265 11.02.2013 20:01 # 0
Это я понял.
Сборка запросов типична для ситуации когда в процедуру приходит несколько параметров @a,@b,@c,@d и нужна логика, если @a is null, то убрать условие на @a, если @b is null, то убрать джойн на @b.
Тут видится джва выхода
а) "оптимальный" копипаст на всё случаи жизни. в данном примере 16. скомпиленые планы и скорость прилагаются. проблемы возникают когда в процедуру надо добавить @e, а потом и @f.
б) OR со всеми вытекающими union и 16 сканами по таблице (t1.someA=@a or @a is null).
Тут-то на помощь и спешит динамика.
kovyl2404 14.02.2013 22:57 # 0