Обратите внимание, что хранимая процедура будет работать медленно не из-за вашего курсора, а из-за подзапросов, которые нужно запускать для каждой строки (11 выбирает + 1 обновление).Просто комбинируя некоторые из этих запросов, вы сможете значительно повысить производительность (например, вычисления для forHcm, budgetHcm и revPlanHcm можно легко объединить в один запрос, поскольку все они являются вычислениями для столбцов базовой таблицы).
ToОтветьте на свой конкретный вопрос о курсоре. Можно удалить курсор, поскольку вам не нужно генерировать выходные значения строк на основе выходных значений для других строк (например, если значение hcmRate для одного fundEntityBaselineId было рассчитано с использованием значений hcmRate для других значений FundEntityBaselineId, тогда было бы очень сложно избежать курсора).Последний запрос без курсора будет немного сложным.
Взяв вашу хранимую процедуру на http://pastebin.ubuntu.com/629888/ и предполагая, что если вы используете COALESCE, мне нужно OUTER JOIN (нет COALESCE, тогда INNER JOIN), здесьВот как должен выглядеть ваш отдельный запрос (чтобы исправить разделы, помеченные как «рефакторинг», мне нужно больше узнать о ваших таблицах):
SELECT fblId,
ForecastAmount * fundAlloc AS foreHCM
hcmRate,
RE_Value * fundAlloc AS reqForeHcm,
PlanAmount * fundAlloc AS budgetHcm
RevisedPlanAmount * fundAlloc AS revPlanHcm,
actualForHcm_pre * fundAlloc AS actualForeCastHcm
FROM
(SELECT b.FundEntityBaselineId AS fblId,
COALESCE(fa.fundAllocation,100)/100 as fundAlloc,
COALESCE(hcmRate1.Usd_Rate,hcmRate2.HCMRate) as hcmRate,
bl.ForecastAmount,
COALESCE(re.Value,0) as RE_Value,
planHcmRate.BudgetHcmRate as planHcmRate,
bl.PlanAmount,
bl.RevisedPlanAmount,
COALESCE(afp_p.actualForHcm_pre,0) as actualForHcm_pre
FROM FundEntityBaseline b
INNER JOIN ProjectDetail pd ON pd.ProjectId = b.fblProjectId
INNER JOIN Baseline bl on bl.BaselineId = b.BaselineId
INNER JOIN ProjectTeam pt ON bl.ProjectTeamId = pt.ProjectTeamId
INNER JOIN SiteTeam st ON pt.SiteTeamId = st.SiteTeamId
INNER JOIN TeamRole tr ON st.TeamRoleId = tr.RoleId
INNER JOIN Team t ON tr.TeamId = t.TeamId
INNER JOIN FundSource fs on fs.FundSourceId = pd.FundSourceId
INNER JOIN (<* refactor*> SELECT r.BudgetHcmRate
FROM Rate r WHERE r.RateName = (SELECT st.RateName
FROM SiteTeam st INNER JOIN ProjectTeam pt
ON st.SiteTeamId = pt.SiteTeamId
INNER JOIN Baseline bl
ON bl.ProjectTeamId = pt.ProjectTeamId
WHERE bl.BaselineId = fblBaselineId
FETCH FIRST 1 ROW ONLY)
ORDER BY r.EffectiveDate
FETCH FIRST 1 ROW ONLY) as planHcmRate,
LEFT OUTER JOIN (SELECT er.Usd_Rate
FROM FundEntity fe
INNER JOIN EntityCustomerRate er
ON fe.FundAux1 = er.EntityCustomerRateId) AS hcmRate1
ON hcmRate1.FundEntityId = b.FundEntityId AND (fs.FundingType IN ('Direct Bill-Single','Direct Bill-Multiple')) AND t.teamType = 'ITDEVMO'
LEFT OUTER JOIN (<* refactor*> SELECT r.HCMRate
FROM Rate r
INNER JOIN SiteTeam st ON r.RateName = st.RateName
INNER JOIN ProjectTeam pt ON st.SiteTeamId = pt.SiteTeamId
WHERE pt.ProjectTeamId = (SELECT bl.ProjectTeamId
FROM Baseline bl
WHERE bl.BaselineId = b.BaselineId)
ORDER BY r.EffectiveDate DESC
FETCH FIRST 1 ROW ONLY) as hcmRate2 ON (fs.FundingType NOT IN ('Direct Bill-Single','Direct Bill-Multiple') OR t.teamType != 'ITDEVMO')
LEFT OUTER JOIN FundAllocation fa on fa.FundSourceId = pd.FundSourceId AND fa.FundEntityId = b.fblFundEntity
LEFT OUTER JOIN Request re on bl.ProjectMonth = re.ProjectMonth AND bl.ProjectTeamId = re.ProjectTeamId AND re.BaselineType = 'Reforecast'
LEFT OUTER JOIN (<*refactor *>SELECT (((SELECT SUM(bl.ForecastAmount)
FROM Baseline bl
WHERE DATE(SUBSTR(bl.ProjectMonth, 5) || '-' ||
(CASE SUBSTR(bl.ProjectMonth, 1, 3)
WHEN 'Jan' THEN '01'
WHEN 'Feb' THEN '02'
WHEN 'Mar' THEN '03'
WHEN 'Apr' THEN '04'
WHEN 'May' THEN '05'
WHEN 'Jun' THEN '06'
WHEN 'Jul' THEN '07'
WHEN 'Aug' THEN '08'
WHEN 'Sep' THEN '09'
WHEN 'Oct' THEN '10'
WHEN 'Nov' THEN '11'
WHEN 'Dec' THEN '12'
END) || '-01') > DATE((SELECT CurrentMonth FROM Pmo)) AND
bl.ProjectTeamId = (SELECT ProjectTeamId FROM Baseline WHERE BaselineId = fblBaselineId))
+
(SELECT SUM(bl.HcmActualAmount)
FROM Baseline bl
WHERE DATE(SUBSTR(bl.ProjectMonth, 5) || '-' ||
(CASE SUBSTR(bl.ProjectMonth, 1, 3)
WHEN 'Jan' THEN '01'
WHEN 'Feb' THEN '02'
WHEN 'Mar' THEN '03'
WHEN 'Apr' THEN '04'
WHEN 'May' THEN '05'
WHEN 'Jun' THEN '06'
WHEN 'Jul' THEN '07'
WHEN 'Aug' THEN '08'
WHEN 'Sep' THEN '09'
WHEN 'Oct' THEN '10'
WHEN 'Nov' THEN '11'
WHEN 'Dec' THEN '12'
END) || '-01') <= DATE((SELECT CurrentMonth FROM Pmo)) AND
bl.ProjectTeamId = (SELECT ProjectTeamId FROM Baseline WHERE BaselineId = fblBaselineId))) as actualForeHcm_pre) AS afh_p
WHERE ProjectId = projId) as T;
Дайте мне знать, если это полезно, или вам нужно больше объяснений.