1

私はストアドプロシージャに書いているこのコードを持っています:

declare @StartTime time
declare @EndTime time
declare @Temp_StartTime time

declare @temp_StartHour int
declare @temp_EndHour int
declare @temp_StartMinute int
declare @temp_EndMinute int

SET @StartTime='22:30:00'
SET @EndTime='00:52:00'
SET @Temp_StartTime=@StartTime

SET @temp_StartHour=DATEPART(HOUR, @StartTime)
SET @temp_EndHour=DATEPART(HOUR, @EndTime)
SET @temp_StartMinute=DATEPART(MI, @StartTime)
SET @temp_EndMinute=DATEPART(MI, @EndTime)

if(@temp_EndMinute>0)
    BEGIN
        SET @temp_EndHour=@temp_EndHour+1
    END

DECLARE @Temp_Table TABLE
(
  StartHour int,
  StartMinute int,
  EndHour int,
  EndMinute int,
  StartTime time,
  EndTime time
)

WHile((@temp_EndHour-@temp_StartHour>=1))
    BEGIN
        INSERT INTO @Temp_Table
        SELECT (DATEPART(HOUR, @Temp_StartTime)) AS StartHour,(DATEPART(MINUTE, @Temp_StartTime)) AS StartMinute,
        @temp_StartHour+1 AS EndHour, 
        0 AS EndMinute, @StartTime as StartTime, @EndTime as EndTime

        SET @temp_StartHour=@temp_StartHour+1
        SET @Temp_StartTime=DATEADD(HOUR,1,@Temp_StartTime)

        if(DATEPART(MI, @Temp_StartTime)!=0)
            BEGIN
                SET @Temp_StartTime=DATEADD(MI,-@temp_StartMinute,@Temp_StartTime)
            END
    END

SELECT * FROM @Temp_Table 

00:52:00 の例以外の時間値を使用すると、うまく機能します。たとえば、EndTime が 23:05 の場合、ストアド プロシージャはうまく機能します。私はDATEPARTについていくつかの調査を行いましたが、軍事時間の真夜中を適切に計算する方法について役立つものは何も見つかりませんでした.

編集:コードが適切に実行されると、開始時刻と終了時刻の間の時間を計算し、1 時間ごとに新しい行を一時テーブルに格納することを考えます (最終的に、これは追跡のために新しいテーブルに保存されます)。時間単位の停止)。21:30 から 22:15 で実行すると、find が機能します。21:00 から 22:00 と 22:00 から 23:00 を反映する 2 つの行を取得します (これが必要なロジックです)。しかし、そこに軍の真夜中を投げると、計算が00を計算しないため、行が返されません。

データベースで、開始時刻が 22:00:0000 で終了時刻が 00:00:00.0000000 で、その逆の例を見つけました。したがって、開始時刻が 00 の場合、一方通行で計算されますが、開始時刻が 21:00:0000 で終了時刻が 00:52:0000 の場合、サイコロはありません。行が返されません。

4

1 に答える 1

1

何も不足していない場合は、ループの代わりに次のことを試すことができます。

DECLARE
  @StartTime time,
  @EndTime   time;

SET @StartTime = '22:30:00';
SET @EndTime   = '00:52:00';

WITH timerange AS (
  SELECT
    StartTime = CAST(@StartTime AS datetime),
    EndTime   = DATEADD(
      DAY,
      CASE WHEN @StartTime > @EndTime THEN 1 ELSE 0 END,
      CAST(@EndTime AS datetime)
    )
),
hourly AS (
  SELECT
    n.number,
    t.StartTime,
    t.EndTime,
    HStart = DATEADD(HOUR, DATEDIFF(HOUR, 0, t.StartTime) + n.number    , 0),
    HEnd   = DATEADD(HOUR, DATEDIFF(HOUR, 0, t.StartTime) + n.number + 1, 0)
  FROM timerange t
    INNER JOIN master..spt_values n
      ON n.number BETWEEN 0 AND DATEDIFF(HOUR, t.StartTime, t.EndTime)
  WHERE n.type = 'P'
),
hourly2 AS (
  SELECT
    number,
    HStart = CASE WHEN StartTime > HStart THEN StartTime ELSE HStart END,
    HEnd   = CASE WHEN EndTime   < HEnd   THEN EndTime   ELSE HEnd   END
  FROM hourly
)
SELECT
  StartHour   = DATEPART(HOUR  , HStart),
  StartMinute = DATEPART(MINUTE, HStart),
  EndHour     = DATEPART(HOUR  , HEnd  ),
  EndMinute   = DATEPART(MINUTE, HEnd  ),
  StartTime   = CAST(HStart AS time),
  EndTime     = CAST(HEnd   AS time)
FROM hourly2
ORDER BY number
;

生成される出力は次のとおりです。

StartHour   StartMinute EndHour     EndMinute   StartTime        EndTime
----------- ----------- ----------- ----------- ---------------- ----------------
22          30          23          0           22:30:00.0000000 23:00:00.0000000
23          0           0           0           23:00:00.0000000 00:00:00.0000000
0           0           0           52          00:00:00.0000000 00:52:00.0000000
于 2012-04-27T05:57:59.513 に答える