TSQL正常运行,但作为一个函数或过程,它没有

时间:2013-12-03 15:03:09

标签: sql-server tsql stored-procedures ssis user-defined-functions

使用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
)

它的时钟

0 个答案:

没有答案