1

MS SQL 関数を Oracle に変換しようとしていますが、問題が発生しています。彼らは、関数内に一時テーブルを作成して徐々に追加することを理由にしています。一時テーブルをカーソルに置き換えて徐々に追加することはできないようです。Oracle でこれを記述する方法を誰かがよく考えている必要があります。

ALTER FUNCTION [dbo].[F_GetDateIntervalTable]
(
@OccurredFrom datetime,
@OccurredTo datetime,
@Interval decimal
)
RETURNS @Tbl table
(
[Dts] datetime
)
AS
BEGIN
    DECLARE @Count int
    --DECLARE @Tbl table([Dts] datetime)
    DECLARE @Dts datetime
    DECLARE @SeedDts datetime

SET @Count = 1
SET @Dts = DATEADD(MINUTE, FLOOR(DATEDIFF(MINUTE,0,@OccurredFrom)/@Interval)*@Interval, 0);
SET @SeedDts = DATEADD(MINUTE, FLOOR(DATEDIFF(MINUTE,0,@OccurredFrom)/@Interval)*@Interval, 0);
SET @OccurredTo = DATEADD(MINUTE, -@Interval, @OccurredTo);
WHILE (@SeedDts < @OccurredTo)
BEGIN
    SET @SeedDts = DATEADD(MINUTE, @Interval*(@Count-1), @Dts)
    INSERT INTO @Tbl(Dts) VALUES(@SeedDts)
    SET @Count = (@Count + 1)
END

RETURN

END

出力は次のようになります (パラメータを指定):

@OccurredFrom = '2013-01-01',
@OccurredTo = '2013-01-02',
@Interval = 60



2013-01-01 00:00:00.000
2013-01-01 01:00:00.000
2013-01-01 02:00:00.000
2013-01-01 03:00:00.000
2013-01-01 04:00:00.000
2013-01-01 05:00:00.000
2013-01-01 06:00:00.000
2013-01-01 07:00:00.000
2013-01-01 08:00:00.000
2013-01-01 09:00:00.000
2013-01-01 10:00:00.000
2013-01-01 11:00:00.000
2013-01-01 12:00:00.000
2013-01-01 13:00:00.000
2013-01-01 14:00:00.000
2013-01-01 15:00:00.000
2013-01-01 16:00:00.000
2013-01-01 17:00:00.000
2013-01-01 18:00:00.000
2013-01-01 19:00:00.000
2013-01-01 20:00:00.000
2013-01-01 21:00:00.000
2013-01-01 22:00:00.000
2013-01-01 23:00:00.000

どんなアイデアでも大歓迎です!

4

1 に答える 1

1

単純に SQL クエリを記述するのではなく、関数を使用する必要があると仮定する

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select date '2013-01-01' start_date,
  3           date '2013-01-02' end_date,
  4           60 interval
  5      from dual
  6  )
  7  select start_date + numtodsinterval( interval * (level-1), 'minute' )
  8    from x
  9* connect by level <= (end_date - start_date)*24*60/interval
SQL> /

START_DATE+NUMTODSI
-------------------
2013-01-01 00:00:00
2013-01-01 01:00:00
2013-01-01 02:00:00
2013-01-01 03:00:00
2013-01-01 04:00:00
2013-01-01 05:00:00
2013-01-01 06:00:00
2013-01-01 07:00:00
2013-01-01 08:00:00
2013-01-01 09:00:00
2013-01-01 10:00:00
2013-01-01 11:00:00
2013-01-01 12:00:00
2013-01-01 13:00:00
2013-01-01 14:00:00
2013-01-01 15:00:00
2013-01-01 16:00:00
2013-01-01 17:00:00
2013-01-01 18:00:00
2013-01-01 19:00:00
2013-01-01 20:00:00
2013-01-01 21:00:00
2013-01-01 22:00:00
2013-01-01 23:00:00

24 rows selected.

パイプライン化されたテーブル関数を作成できます

SQL> create type tbl_date as table of date;
  2  /

Type created.

SQL> create or replace function get_date_interval( p_start_date in date,
  2                                                p_end_date   in date,
  3                                                p_interval   in number )
  4    return tbl_date
  5    pipelined
  6  is
  7    l_return_dt date := p_start_date;
  8  begin
  9    while( l_return_dt < p_end_date )
 10    loop
 11      pipe row( l_return_dt );
 12      l_return_dt := l_return_dt + numtodsinterval( p_interval, 'minute' );
 13    end loop;
 14    return;
 15  end;
 16  /

Function created.

SQL> select *
  2    from table( get_date_interval( date '2013-01-01',
  3                                   date '2013-01-02',
  4                                   60 ));

COLUMN_VALUE
-------------------
2013-01-01 00:00:00
2013-01-01 01:00:00
2013-01-01 02:00:00
2013-01-01 03:00:00
2013-01-01 04:00:00
2013-01-01 05:00:00
2013-01-01 06:00:00
2013-01-01 07:00:00
2013-01-01 08:00:00
2013-01-01 09:00:00
2013-01-01 10:00:00
2013-01-01 11:00:00
2013-01-01 12:00:00
2013-01-01 13:00:00
2013-01-01 14:00:00
2013-01-01 15:00:00
2013-01-01 16:00:00
2013-01-01 17:00:00
2013-01-01 18:00:00
2013-01-01 19:00:00
2013-01-01 20:00:00
2013-01-01 21:00:00
2013-01-01 22:00:00
2013-01-01 23:00:00

24 rows selected.
于 2013-01-24T17:08:19.533 に答える