循环问题

时间:2017-04-02 18:38:03

标签: sql sql-server tsql

希望有人可以提供一些帮助,我目前正在处理一段似乎有问题的代码。不幸的是,我无法发布基础数据,但会尝试解释。

代码当前循环选择kpi并根据当前时间以及是否需要运行单个kpi来计算是否需要运行某些内容。目前,如果我硬编码了一些kpi,那么代码工作正常,但是如果我让它循环遍历所有kpi,那么那些不应该运行的代码被告知要运行,同样在选择中定义@Period这样的东西,当我让它运行所有KPI时,它设置@Period不正确,当它不应该运行但是当它意味着运行它设置好了。

总的来说,我认为有两个问题,我认为这些问题与KPI的运行有关,当它们不打算运行时以及何时运行它们并不意味着它们以错误的方式选择错误的时间段。我认为正在发生的事情就是当我让它一直在KPI中运行时,我们已经看到了这种情况发生了混乱,但是在我发疯之前,任何帮助都会很好。

正如你从我的代码中看到的那样,有2个@current_timestamps,当它设置为23.45.18.873时,它不应该运行一些kpi,但无论如何它都运行它们而21.45.18.873意味着它们可以运行

declare @job_current_time_minute float,
        @job_current_date_time_minute as datetime,
        @current_timestamp as datetime



SET @job_current_time_minute = 52--cast(datepart(minute, getdate()) as float)
SET @job_current_date_time_minute =  getdate()
--SET @current_timestamp = cast('2017-04-02 23:45:18.873' as datetime)
SET @current_timestamp = cast('2017-04-02 21:45:18.873' as datetime)
--Run: 88 6 0 52 5 5 5
--Run: 88 1 10 52 5 5 5

declare 
    @kpi_id int,
    @kpi_parent_id int,  
    @sql nvarchar(max), 
    @kpi_last_result nvarchar(100), 
    @kpi_last_runtime datetime,
    @kpi_params nvarchar(max),
    @kpi_current_time_minute float,
    @schedulue_minute float,
    @reoccurrence float,
    @result float,
    @kpi2 int,

    -- Email Variables
    @kpi_name nvarchar(150),
    @kpi_desc nvarchar(150),
    @kpi_report_link nvarchar(150),
    @kpi_email_subject nvarchar(150),
    @kpi_email_body nvarchar(300),
    @kpi_email_query nvarchar(max),
    @kpi_sms_msg nvarchar(300);


SET @kpi_params = N'@retvalOUT varchar(max) OUTPUT';

select @kpi_id = min(kpi_id) from KPI where KPI_Active = 1; --and kpi_id in (86, 88)

    while @kpi_id is not null

        begin

            select
            @kpi_parent_id = kpi_parent_id, 
            @sql = kpi_Script, 
            @schedulue_minute = datepart(minute,s.Schedule_Start), 
            @reoccurrence = s.Reoccurrence,
            @result = cast((@job_current_time_minute - datepart(minute,s.Schedule_Start)) / s.Reoccurrence as decimal(18,2)),
            @kpi_name = kpi_name,
            @kpi_desc = kpi_desc,
            @kpi_report_link = kpi_report_link,
            @kpi_email_subject = kpi_email_subject,
            @kpi_email_body = kpi_email_body,
            @kpi_email_query = kpi_email_query,
            @kpi_sms_msg = kpi_sms_msg,
            @kpi_current_time_minute = 60*DATEPART(HOUR, GETDATE())+DATEPART(MINUTE,GETDATE()),
            @kpi2 = KPI_ID
            from EWI..KPI
            inner join EWI..Schedule s on KPI.Schedule_ID = s.Schedule_ID where kpi_id = @kpi_id--order by kpi_id asc

            --set @sql = 'select @retvalOUT= (' + @sql + ')'

if floor(@result) <> ceiling(@result)

        begin

            PRINT 'Not Time to Run: ' + ' ' + cast(@kpi_id as varchar(11)) + ' ' + cast(@result as varchar(11))

        end

else

        begin

                    declare 
                    @ThresholdID int,
                    @PeriodID int,
                    @Threshold_value int,
                    @Threshold_PosNeg nvarchar(5)

            select @ThresholdID = Threshold_ID, @PeriodID = Period_ID, @Threshold_value = Threshold_value, @Threshold_PosNeg = Threshold_PosNeg from (
            --  select * from (
                select * from (
                        select KPI_ID, t.Threshold_ID, p.Period_ID, t.Threshold_Value, t.Threshold_PosNeg, p.DayStartTime, p.DayEndTime, Period_desc, [Day] 
                        from EWI..Threshold t join 
                                    EWI..Period p on t.Period_ID = p.Period_ID where KPI_ID = @kpi_id
                ) x where (case when [Day] = datename(dw,getdate()) then Period_id
                    when [Day] = choose(datepart(dw, getdate()), 'WEEKEND','Weekday','Weekday','Weekday','Weekday','Weekday','WEEKEND') then Period_ID
                    when [Day] = 'All' then Period_ID end) is not null
            ) y where case when datediff(second,DayStartTime,DayEndTime) > 0 then 
            case when convert(time(0), @current_timestamp) >= DayStartTime and convert(time(0), @current_timestamp) < DayEndTime then 1 else 0 end
            else case when convert(time(0), @current_timestamp) >= DayStartTime or convert(time(0), @current_timestamp) < DayEndTime then 1 else 0 end
            end = 1


select 'Run: ' + cast(@kpi_id as varchar(11)) + ' ' + cast(@PeriodID as varchar(11)) + ' ' + 
cast(@Threshold_value as varchar(11)) + ' ' + cast(@job_current_time_minute as varchar(11))  + ' ' + 
cast(@result as varchar(11))  + ' ' + 
cast(ceiling(@result) as varchar(11))+ ' ' +cast(floor(@result) as varchar(11))

    end


    select @kpi_id = min(kpi_id) from KPI where KPI_Active = 1 and kpi_id > @kpi_id;


end

1 个答案:

答案 0 :(得分:1)

看看这个rextester demo。你是否同意这个模型再现问题?似乎将ceiling(@result)floor(@result)进行比较确实会给所有地方true

在我们讨论之后,在我看来,测试应该是: if (@result - datepart(minute, Schedule_Start)) % @reoccurrence = 0 或类似的东西。但这假设 @reoccurence是一个整数