Oracle PL/SQL Procedure/function 创建包含列的视图

Oracle PL/SQL Procedure/function to create view with columns

我之前有过类似的要求,但现在我得到了一个需要实施的明确方法。

我需要编写一个过程(最好)/函数,它将基于作为参数传递的 app_id,更改列 headers 以在动态视图中旋转相应的值。

第 headers 列的 table 是 DATA_HEADER。

值为table的DATA_VALUE。

列 headers 和值需要按顺序旋转。

两个 table 都有 app_id 的共同点。因此,对于 app_id=1,DATA_HEADER 中的标签将用于 DATA_VALUE 中的值。但是,这些值仅基于 PID 发生变化,因此它们将保持不变,每个应用程序 ID 仅 headers 会发生变化。

当app_id传入proc/funct时,预期的视图应该是:

所以基本上,每个 app_id 的 headers 变化,并且 列 headers 的最大数量将是 20。因此,数字或名称应与 table DATA_HEADER 中的不同。 这些值是根据 pid 唯一标识的。

列 headers 的顺序将按照 DATA_HEADER 中的 seq 列。 类似地,值的顺序将按照数据值中的 seq 列,因此必须遵循顺序并相应地旋转。

P.S。最后的应用程序是调用 proc/function 的 Oracle 顶点。

Oracle 版本:12.1

一个选项是创建如下所示的函数,然后从 SQLPlus、SQLcl 或您正在使用的任何其他工具调用游标。如果您使用 Java 或 APEX,您可以使用 refcursor 或什至只使用 l_sql 中的值来获取您需要的 select 语句。

函数

CREATE OR REPLACE FUNCTION get_data (p_app_id data_header.app_id%type)
    RETURN SYS_REFCURSOR
IS
    TYPE headers_t IS TABLE OF data_header.label%TYPE;
    l_headers    headers_t;
    l_cur        SYS_REFCURSOR;
    l_sql        VARCHAR2 (32767);
BEGIN
      SELECT label
        BULK COLLECT INTO l_headers
        FROM data_header
       WHERE app_id = p_app_id
    ORDER BY seq;

    l_sql := 'select * FROM (SELECT *
          FROM data_value
         WHERE app_id = ' || p_app_id || ')
       PIVOT (MIN (VALUE) FOR seq IN (';

    FOR i IN 1 .. l_headers.COUNT
    LOOP
        l_sql :=
               l_sql
            || i
            || ' as "'
            || l_headers (i)
            || CASE WHEN i < l_headers.COUNT THEN '", ' ELSE '"' END;
    END LOOP;

    l_sql := l_sql || '))';

    OPEN l_cur FOR l_sql;

    RETURN l_cur;
END;
/

SQLPlus 或 SQLcl

你可以这样使用光标

SQL> variable l_cursor refcursor;
SQL> begin                                                                                                                                                                                                                                     
  2    :l_cursor := get_data(1);                                                                                                                                                                                                               
  3  end;
  4  /

PL/SQL procedure successfully completed.

SQL> print l_cursor;

更新

由于您的终端 UI 是 APEX,因此可以构建此查询以在 APEX 中运行。通过返回 l_sql 中的值,您可以使用该查询创建经典报告。我已经构建了一个 demo application on apex.oracle.com 表明这是可能的。