在嵌套表中搜索并将结果插入到新的嵌套表中!

发布于 2024-10-22 01:53:00 字数 2737 浏览 2 评论 0原文

如何将 WITH SELECT 的结果插入到其中的嵌套数组(具有两个属性)中?

以下是 DDL 和 DML SQL;

不用担心 NUMBER( 8 )


CREATE OR REPLACE TYPE DATE_RANGE IS OBJECT ( start_date NUMBER( 8 ), end_date NUMBER( 8 ) );

CREATE OR REPLACE TYPE DATE_RANGE_ARR IS TABLE OF DATE_RANGE;

DECLARE
   g_splited_range_arr   DATE_RANGE_ARR := DATE_RANGE_ARR( );
   g_travel_range        DATE_RANGE := DATE_RANGE( '20110101', '99991231' );
   g_bo_arr              DATE_RANGE_ARR := DATE_RANGE_ARR( DATE_RANGE( '20110312', '20110317' ), DATE_RANGE( '20110315', '20110329' ) );

   FUNCTION split_date_sql( pr_travel_date_range    DATE_RANGE,
                            pr_bo_arr               DATE_RANGE_ARR )
      RETURN DATE_RANGE_ARR
   IS
      l_splited_range_arr   DATE_RANGE_ARR;
   BEGIN
      SELECT start_date, end_date
        INTO l_splited_range_arr(start_date, end_date)
        FROM (WITH all_dates
                      AS (SELECT tr_start_date AS a_date, 0 AS black_out_val FROM TABLE( pr_travel_date_range )
                          UNION ALL
                          SELECT tr_end_date, 0 FROM TABLE( pr_travel_date_range )
                          UNION ALL
                          SELECT bo_start_date - 1, 1 FROM TABLE( pr_bo_arr )
                          UNION ALL
                          SELECT bo_end_date + 1, -1 FROM TABLE( pr_bo_arr )),
                   got_analytics
                      AS (SELECT a_date AS start_date,
                                 LEAD( a_date ) OVER (ORDER BY a_date, black_out_val) AS end_date,
                                 SUM( black_out_val ) OVER (ORDER BY a_date, black_out_val) AS black_out_cnt
                            FROM all_dates)
                SELECT start_date, end_date
                  FROM got_analytics
                 WHERE black_out_cnt = 0 AND start_date < end_date
              ORDER BY start_date);

      RETURN l_splited_range_arr;
   END;
BEGIN

    g_splited_range_arr := split_date_sql(g_travel_range,g_bo_arr);

    FOR index_g_splited_range_arr IN g_splited_range_arr .FIRST .. g_splited_range_arr .LAST LOOP        
        DBMS_OUTPUT.PUT_LINE('g_splited_range_arr[' || index_g_splited_range_arr || ']: ' || g_splited_range_arr(index_g_splited_range_arr).start_date || '-'  || g_splited_range_arr(index_g_splited_range_arr).end_date );
    END LOOP;

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      NULL;
   WHEN OTHERS
   THEN
      NULL;
END;

或者我可以创建一个包含嵌套数组参数的视图,这样我就可以简单地调用

SELECT  *
  BULK COLLECT INTO g_splited_range_arr
  FROM view_split_date(g_travel_range,g_bo_arr);

How can I insert result of an WITH SELECT into a Nested Array (with two attributes) in it?

Here are the DDL and DML SQLs;

Don't worry about the NUMBER( 8 )


CREATE OR REPLACE TYPE DATE_RANGE IS OBJECT ( start_date NUMBER( 8 ), end_date NUMBER( 8 ) );

CREATE OR REPLACE TYPE DATE_RANGE_ARR IS TABLE OF DATE_RANGE;

DECLARE
   g_splited_range_arr   DATE_RANGE_ARR := DATE_RANGE_ARR( );
   g_travel_range        DATE_RANGE := DATE_RANGE( '20110101', '99991231' );
   g_bo_arr              DATE_RANGE_ARR := DATE_RANGE_ARR( DATE_RANGE( '20110312', '20110317' ), DATE_RANGE( '20110315', '20110329' ) );

   FUNCTION split_date_sql( pr_travel_date_range    DATE_RANGE,
                            pr_bo_arr               DATE_RANGE_ARR )
      RETURN DATE_RANGE_ARR
   IS
      l_splited_range_arr   DATE_RANGE_ARR;
   BEGIN
      SELECT start_date, end_date
        INTO l_splited_range_arr(start_date, end_date)
        FROM (WITH all_dates
                      AS (SELECT tr_start_date AS a_date, 0 AS black_out_val FROM TABLE( pr_travel_date_range )
                          UNION ALL
                          SELECT tr_end_date, 0 FROM TABLE( pr_travel_date_range )
                          UNION ALL
                          SELECT bo_start_date - 1, 1 FROM TABLE( pr_bo_arr )
                          UNION ALL
                          SELECT bo_end_date + 1, -1 FROM TABLE( pr_bo_arr )),
                   got_analytics
                      AS (SELECT a_date AS start_date,
                                 LEAD( a_date ) OVER (ORDER BY a_date, black_out_val) AS end_date,
                                 SUM( black_out_val ) OVER (ORDER BY a_date, black_out_val) AS black_out_cnt
                            FROM all_dates)
                SELECT start_date, end_date
                  FROM got_analytics
                 WHERE black_out_cnt = 0 AND start_date < end_date
              ORDER BY start_date);

      RETURN l_splited_range_arr;
   END;
BEGIN

    g_splited_range_arr := split_date_sql(g_travel_range,g_bo_arr);

    FOR index_g_splited_range_arr IN g_splited_range_arr .FIRST .. g_splited_range_arr .LAST LOOP        
        DBMS_OUTPUT.PUT_LINE('g_splited_range_arr[' || index_g_splited_range_arr || ']: ' || g_splited_range_arr(index_g_splited_range_arr).start_date || '-'  || g_splited_range_arr(index_g_splited_range_arr).end_date );
    END LOOP;

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      NULL;
   WHEN OTHERS
   THEN
      NULL;
END;

Or can I create a VIEW with parameters of Nested Arrays in it so I can simply call

SELECT  *
  BULK COLLECT INTO g_splited_range_arr
  FROM view_split_date(g_travel_range,g_bo_arr);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

何其悲哀 2024-10-29 01:53:00

这是当前的解决方案:

CREATE OR REPLACE TYPE DATE_RANGE IS OBJECT ( start_date NUMBER( 8 ), end_date NUMBER( 8 ) );

CREATE OR REPLACE TYPE DATE_RANGE_ARR IS TABLE OF DATE_RANGE;

DECLARE
   g_splited_range_arr   DATE_RANGE_ARR;
   g_travel_range        DATE_RANGE_ARR := DATE_RANGE_ARR( DATE_RANGE( '20110101', '99991231' ) );
   g_bo_arr              DATE_RANGE_ARR := DATE_RANGE_ARR( DATE_RANGE( '20110312', '20110317' ), DATE_RANGE( '20110315', '20110329' ) );

   FUNCTION split_date_sql( pr_travel_date_range DATE_RANGE_ARR, pr_bo_arr DATE_RANGE_ARR )
      RETURN DATE_RANGE_ARR
   IS
      l_splited_range_arr   DATE_RANGE_ARR := DATE_RANGE_ARR( );
      l_date                DATE_RANGE := DATE_RANGE( NULL, NULL );
   BEGIN

      -- Used cursor for inserting into another Nested Table=l_splited_range_arr
      FOR rec_splited_date
         IN ( WITH 
                   nt_travel AS (SELECT * FROM TABLE( pr_travel_date_range )),   -- Select from Nested Table
                   nt_black_out_dates AS (SELECT * FROM TABLE( pr_bo_arr )),     -- Select from Nested Table
                   all_dates AS (SELECT start_date AS a_date, 0 AS black_out_val FROM nt_travel    -- Used Nested Table in SQL
                                 UNION ALL
                                 SELECT end_date, 0 FROM nt_travel                                 -- Used Nested Table in SQL
                                 UNION ALL
                                 SELECT start_date - 1, 1 FROM nt_black_out_dates                  -- Used Nested Table in SQL
                                 UNION ALL
                                 SELECT end_date + 1, -1 FROM nt_black_out_dates),                 -- Used Nested Table in SQL
                   got_analytics
                      AS (SELECT a_date AS start_date,
                                 LEAD( a_date ) OVER (ORDER BY a_date, black_out_val) AS end_date,
                                 SUM( black_out_val ) OVER (ORDER BY a_date, black_out_val) AS black_out_cnt
                            FROM all_dates)
               SELECT start_date, end_date
                 FROM got_analytics
                WHERE black_out_cnt = 0 AND start_date < end_date
             ORDER BY start_date )
      LOOP
         l_date.start_date := rec_splited_date.start_date;
         l_date.end_date := rec_splited_date.end_date;
         -- Inserting into another Nested Table=l_splited_range_arr from cursor=rec_splited_date
         l_splited_range_arr.EXTEND;
         l_splited_range_arr( l_splited_range_arr.LAST ) := l_date;
      END LOOP;

      RETURN l_splited_range_arr;
   END;
BEGIN
   g_splited_range_arr := split_date_sql( g_travel_range, g_bo_arr );

   FOR index_g_splited_range_arr IN g_splited_range_arr.FIRST .. g_splited_range_arr.LAST
   LOOP
      DBMS_OUTPUT.PUT_LINE(
              'g_splited_range_arr['
           || index_g_splited_range_arr
           || ']: '
           || g_splited_range_arr( index_g_splited_range_arr ).start_date
           || '-'
           || g_splited_range_arr( index_g_splited_range_arr ).end_date );
   END LOOP;
END;

Here is the current solution:

CREATE OR REPLACE TYPE DATE_RANGE IS OBJECT ( start_date NUMBER( 8 ), end_date NUMBER( 8 ) );

CREATE OR REPLACE TYPE DATE_RANGE_ARR IS TABLE OF DATE_RANGE;

DECLARE
   g_splited_range_arr   DATE_RANGE_ARR;
   g_travel_range        DATE_RANGE_ARR := DATE_RANGE_ARR( DATE_RANGE( '20110101', '99991231' ) );
   g_bo_arr              DATE_RANGE_ARR := DATE_RANGE_ARR( DATE_RANGE( '20110312', '20110317' ), DATE_RANGE( '20110315', '20110329' ) );

   FUNCTION split_date_sql( pr_travel_date_range DATE_RANGE_ARR, pr_bo_arr DATE_RANGE_ARR )
      RETURN DATE_RANGE_ARR
   IS
      l_splited_range_arr   DATE_RANGE_ARR := DATE_RANGE_ARR( );
      l_date                DATE_RANGE := DATE_RANGE( NULL, NULL );
   BEGIN

      -- Used cursor for inserting into another Nested Table=l_splited_range_arr
      FOR rec_splited_date
         IN ( WITH 
                   nt_travel AS (SELECT * FROM TABLE( pr_travel_date_range )),   -- Select from Nested Table
                   nt_black_out_dates AS (SELECT * FROM TABLE( pr_bo_arr )),     -- Select from Nested Table
                   all_dates AS (SELECT start_date AS a_date, 0 AS black_out_val FROM nt_travel    -- Used Nested Table in SQL
                                 UNION ALL
                                 SELECT end_date, 0 FROM nt_travel                                 -- Used Nested Table in SQL
                                 UNION ALL
                                 SELECT start_date - 1, 1 FROM nt_black_out_dates                  -- Used Nested Table in SQL
                                 UNION ALL
                                 SELECT end_date + 1, -1 FROM nt_black_out_dates),                 -- Used Nested Table in SQL
                   got_analytics
                      AS (SELECT a_date AS start_date,
                                 LEAD( a_date ) OVER (ORDER BY a_date, black_out_val) AS end_date,
                                 SUM( black_out_val ) OVER (ORDER BY a_date, black_out_val) AS black_out_cnt
                            FROM all_dates)
               SELECT start_date, end_date
                 FROM got_analytics
                WHERE black_out_cnt = 0 AND start_date < end_date
             ORDER BY start_date )
      LOOP
         l_date.start_date := rec_splited_date.start_date;
         l_date.end_date := rec_splited_date.end_date;
         -- Inserting into another Nested Table=l_splited_range_arr from cursor=rec_splited_date
         l_splited_range_arr.EXTEND;
         l_splited_range_arr( l_splited_range_arr.LAST ) := l_date;
      END LOOP;

      RETURN l_splited_range_arr;
   END;
BEGIN
   g_splited_range_arr := split_date_sql( g_travel_range, g_bo_arr );

   FOR index_g_splited_range_arr IN g_splited_range_arr.FIRST .. g_splited_range_arr.LAST
   LOOP
      DBMS_OUTPUT.PUT_LINE(
              'g_splited_range_arr['
           || index_g_splited_range_arr
           || ']: '
           || g_splited_range_arr( index_g_splited_range_arr ).start_date
           || '-'
           || g_splited_range_arr( index_g_splited_range_arr ).end_date );
   END LOOP;
END;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文