У меня есть таблица с именем Budgetline
. Отслеживает строки бюджета для проектов (Гранты).
Схема
BudgetId int
Amount decimal
LoginUser varchar
InsertDate datetime
GrantPhaseID int
BudgetChartID int
Rootdir hierarchyid
OverHead decimal
Столбец Amount
- это бюджетная сумма для строки бюджета. Строка бюджета может иметь суббюджетную линию. У суббюджетной линии может быть другая суббюджетная линия. Иногда может быть до 5 уровней.
Есть еще одна таблица TransactionsDetail
; он отслеживает бюджетные расходы
Схема
TransactionDetailID int
TransactionID int
Amount numeric
ExRateAmount numeric
TransactionDate date
BudgetId int
InsertDate datetime
OverHead decimal
Paid bit
PaidDate datetime
LoginUser varchar
Проекты (Гранты) имеют фазы. Есть еще одна таблица GrantPhase
для отслеживания этого.
Есть еще одна таблица с именем BudgetChart
. Он содержит список Budgetlines. Разные проекты (гранты) могут иметь одинаковые бюджетные линии.
Ниже приведена полная табличная функция для получения строк Sub бюджета (потомков) строки бюджета (Parent).
ALTER FUNCTION [dbo].[getSUBS]
(@BudgetID INT
--,@GrantPhaseID INT
)
RETURNS @Mytable TABLE (CID INT,
[COUNT] INT,
DESCRIPTION VARCHAR(256),
AMOUNT NUMERIC(18,2),
SPENT NUMERIC(18,2),
BALANCE NUMERIC(18,2),
OVERHEAD NUMERIC(18,2)
-- BUDGETLIMIT numeric(18,2)
)
AS
BEGIN
-- get budgetline root level
declare @BudgetIDrootRevel int
SELECT @BudgetIDrootRevel = RootDir.GetLevel() FROM budgetlines WHERE budgetid = @BudgetID
-- GET GRANTPHASEID
DECLARE @GrantPhaseID int=(
select GrantPhaseID from BudgetLines where BudgetId=@BudgetID
)
DECLARE @RootDir HIERARCHYID
SELECT @RootDir = RootDir FROM budgetlines WHERE budgetid = @BudgetID
insert into @Mytable(
CID
, [COUNT]
, DESCRIPTION
, AMOUNT
, SPENT
, BALANCE
, OVERHEAD
--, BUDGETLIMIT
)
SELECT
BudgetId
, ROW_NUMBER() OVER (ORDER BY BudgetID DESC)
, [Description]
, dbo.[getBudgetAmount](BudgetLines.BudgetId) AMOUNT --Sums all transactions made in the TransactionDetails table
, [dbo].[getBudgetSpent](BudgetId) as SPENT
, ISNULL((dbo.[getBudgetAmount](BudgetLines.BudgetId)-[dbo].[getBudgetSpent](BudgetId)),0) as BALANCE
, BudgetLines.OVERHEAD
--, BUDGETLIMIT
FROM BudgetLines INNER JOIN BudgetChart
ON BudgetChart.BudgetChartID = BudgetLines.BudgetChartID
WHERE RootDir.IsDescendantOf(@RootDir)=1
and GrantPhaseID = @GrantPhaseID
and Rootdir.GetLevel()=(@BudgetIDrootRevel+1)
--AND isBudgetline=1
return ;
end
Работает.
- Таблица Budgetline имеет только 252 записи
- В таблице TransactionDetails всего 172 записи
Мой вызов:
Требуется около 10 секунд, чтобы вернуть суббюджетные линии, если эта конкретная бюджетная линия имеет 3 или более подуровней (потомков).
Мой вопрос:
Есть ли лучший способ оптимизировать (переписать) эту функцию, чтобы она могла работать быстрее.
Ниже показано, как выглядит дизайн. Пользователь может просмотреть строки суббюджета, дважды щелкнув строку или нажав кнопку [Переместить вниз].
Как выглядит пользовательский интерфейс
Само собой разумеется: это мой первый пост о всемогущем стеке-потоке.
Извините, если я нарушил какое-либо из правил сообщества. я еще учусь
им.