使用SQL Server 2005,2008,2012
这是一个非常奇怪的问题,我不知道如何分类。我将一大块TSQL放入函数中。我使用了一个函数来传递值进行计算。该函数是计算和临时表函数调用等的混合。如果我在函数外部运行SQL,它将在22秒内完成。如果我将它包装在基于表的函数中,它只是时钟。如果我在一个程序中运行它,它会计时。唯一的区别是我在SQL中使用直接临时表,在函数/过程中,我返回一个表。我正在SSMS中完成所有开发工作。没有错误被抛出。
我可以粘贴代码,但它很长。目前,有没有人有任何解决问题的建议?可能会在背景中出现我未被告知的许可问题吗?
以下代码可在22秒内完成
declare @paccall_percent_increase float = .114
declare @monthkey as varchar(6) = '201310'
declare @first_forecast_month varchar(6) = '201311'
declare @business_growth_percent float = .25
declare @auth_percent float = .1564
declare @forecast_duration int = 1
declare @decision varchar(10) = 'baseline'
declare @results table (
PERIOD varchar(8),
[AVAILABILITY] varchar (100),
OFFERING varchar(100),
APPLID varchar(100),
LPAR varchar(100),
ApplicationName varchar (100),
PRODUCT varchar (100),
Catagory varchar (100),
QTY float,
UnitRate float,
[Total-Charge] float,
[Actual QTY] float,
ProcType varchar(100),
[Auth Baseline] float,
[current month auth] float,
[real number of month days] float,
[real days - holidays] float,
[forecast month] varchar(20)
)
declare @model_month_auth_volume as float
declare @forecast_month_auth_volume as float
declare @month_days float
declare @calculated_days float -- actual days - holidays
declare @calculated_pac_calls float
declare @cpu_hour float
-- create calendar table
declare @calendar table(
[datetime] datetime,
Monthkey varchar(6),
NumOfDays float,
Holidays float,
ActualDays float
)
-- load calendar table
insert @calendar (
[datetime],
Monthkey,
NumOfDays,
Holidays,
ActualDays
)
SELECT
[datetime],
Monthkey,
NumOfDays,
Holidays,
ActualDays
FROM (
SELECT
min([DateValue])as [datetime],
LEFT(CalendarId, 6) AS Monthkey,
COUNT(CalendarId) AS NumOfDays,
SUM(USAIsBankHoliday) AS Holidays,
COUNT(CalendarId) - SUM(USAIsBankHoliday) AS ActualDays
FROM
dbo.Calendar
GROUP BY
LEFT(CalendarId, 6)) a
---------------------------------
declare @foundation_table table (
PERIOD varchar(8),
AVAILABILITY varchar(100),
OFFERING varchar(100),
APPLID varchar(100),
LPAR varchar(100),
ApplicationName varchar(100),
PRODUCT varchar(100),
Catagory varchar(100),
UnitRate float,
QTY float,
ProcType varchar(100)
)
insert @foundation_table (
PERIOD,
AVAILABILITY,
OFFERING,
APPLID,
LPAR,
ApplicationName,
PRODUCT,
Catagory,
UnitRate,
QTY,
ProcType
)
SELECT
d.PERIOD+'-P',
d.AVAILABILITY,
d.OFFERING,
d.APPLID,
d.LPAR,
a.ApplicationName,
d.PRODUCT_SET,
c.Catagory,
Max(d.Rate),
Sum(d.QUANTITY),
GTI_mainframe.func_mf_Catagory_lookup(c.Catagory)
from (
[GTI_mainframe].[A-Utility-A-Invoice-Detail] d LEFT JOIN [GTI_mainframe].[AA-JobCatagoryTable] c ON
d.JOBNAME = c.JOB
) LEFT JOIN [GTI_mainframe].[APPLIDTABLE] a ON
d.APPLID = a.APPLID
Where
period = @monthkey
GROUP BY
d.PERIOD,
d.AVAILABILITY,
d.OFFERING,
d.APPLID,
d.LPAR,
a.ApplicationName,
d.PRODUCT_SET,
c.Catagory
-- load variables
declare @counter as float
set @counter=1
WHILE (@counter <= @forecast_duration) begin
set @month_days = (select NumOfDays from @calendar where monthkey=@monthkey)
----------
set @calculated_days = (select ActualDays from @calendar where monthkey=@first_forecast_month)
set @model_month_auth_volume = (select cast(volume as float) from GTI_mainframe.authorization_volume where cast(datepart("year", [date]) as varchar(4))+RIGHT(REPLICATE('00', 2) + LTRIM(RTRIM(datepart("month", [date]))), 2) = @monthkey)
set @forecast_month_auth_volume = (select volume from [GTI_mainframe].[func_mf_forecast_authorizations] (@auth_percent) where ade_month = @first_forecast_month+'-P')
set @calculated_pac_calls = @model_month_auth_volume * @paccall_percent_increase
set @cpu_hour = (select [CPU Hour] from [GTI_mainframe].[func_mf_forecast_paccalls]( @monthkey, @paccall_percent_increase, @business_growth_percent, @auth_percent) where [Projection] = @monthkey + '-P')
insert @results (
PERIOD,
AVAILABILITY,
OFFERING,
APPLID,
LPAR,
ApplicationName,
PRODUCT,
Catagory,
QTY,
UnitRate,
[Total-Charge],
[Actual QTY],
ProcType,
[Auth Baseline],
[current month auth],
[real number of month days],
[real days - holidays],
[forecast month]
)
SELECT
case @decision
when 'baseline' then @monthkey
else @first_forecast_month
end+'-P',
AVAILABILITY,
OFFERING,
APPLID,
LPAR,
ApplicationName,
PRODUCT,
Catagory,
case ProcType
when 'Monthly'
then QTY
when 'Authorizations'
then QTY/@model_month_auth_volume * @forecast_month_auth_volume
when 'Daily'
then (QTY/@month_days)*@calculated_days
when 'PACCALL'
then @cpu_hour
end,
UnitRate,
case ProcType
when 'Monthly'
then QTY * UnitRate
when 'Authorizations'
then QTY/@model_month_auth_volume * @forecast_month_auth_volume * UnitRate
when 'Daily'
then (QTY/@month_days)*(@calculated_days) * UnitRate
when 'PACCALL'
then @cpu_hour * UnitRate
end,
QTY,
ProcType,
@model_month_auth_volume,
@forecast_month_auth_volume,
@month_days,
@calculated_days,
@first_forecast_month
from
@foundation_table
union all
select
case @decision
when 'baseline' then @monthkey
else @first_forecast_month
end+'-P' PERIOD
,'NYD - Mainframe CPU' AVAILABILITY
,'Mainframe CPU' OFFERING
,'CC9' APPLID
,'CC' LPAR
,'MF CPU' ApplicationName
,'OLAUTHSR3' Product
,'PACCALL' Catagory
, @cpu_hour QTY
,(
select
max(rate)
from
GTI_mainframe.MFInvoiceTable
where
availability = 'NYD - Mainframe CPU' and
offering = 'Mainframe CPU'and
product_set = 'MF CPU' and
period = @monthkey
) UnitRate
, (
select
max(rate)
from
GTI_mainframe.MFInvoiceTable
where
availability = 'NYD - Mainframe CPU' and
offering = 'Mainframe CPU'and
product_set = 'MF CPU' and
period = @monthkey
) * @cpu_hour [Total-Charge]
,@calculated_pac_calls [Actual QTY]
,'PACCALL' ProcType
,@model_month_auth_volume
,@forecast_month_auth_volume,
@month_days,
@calculated_days,
@first_forecast_month
--SET @first_forecast_month = (select cast(year(dateadd(month,+1,[datetime])) as char(4))+RIGHT('00000'+ CONVERT(VARCHAR,month(dateadd(month,+1,[datetime]))),2) from @calendar where monthkey = @first_forecast_month)
SET @first_forecast_month = (SELECT
cast(year(dateadd(month,+1,[datetime])) as varchar(4))+RIGHT('00000'+ CONVERT(VARCHAR,month(dateadd(month,+1,[datetime]))),2)
FROM (
SELECT
min([DateValue])as [datetime]
FROM
dbo.Calendar
where LEFT(CalendarId, 6) = @first_forecast_month
GROUP BY
LEFT(CalendarId, 6)) a)
SET @counter = @counter + 1;
end
select * from @results
如果我通过这样做将其转换为函数:
CREATE function [GTI_mainframe].[func_mf_baseline_month](
@paccall_percent_increase float,
@monthkey as char(6),
@first_forecast_month char(6),
@business_growth_percent float,
@auth_percent float,
@forecast_duration int,
@decision varchar(10)
) returns @results table (
... same code
)
它是时钟。如果我通过这样做创建一个过程:
create procedure [GTI_mainframe].[test_proc_baseline_month] (
@paccall_percent_increase float,
@monthkey as char(6),
@first_forecast_month char(6),
@business_growth_percent float,
@auth_percent float,
@forecast_duration int,
@decision varchar(10)
) as
... same code
)
它的时钟