是的,终于有了 :) SQL标准2016定义了多态表函数
SQL:2016引入了多态表函数(PTF),它们不需要事先指定结果类型。相反,它们可以提供一个描述组件过程,在运行时确定返回类型。PTF的作者和用户都不需要事先声明返回的列。按照SQL:2016描述的方式,PTF尚未在任何经过测试的数据库中使用。感兴趣的读者可以参考ISO发布的免费技术报告“SQL中的多态表函数”。以下是报告中讨论的一些示例:CSVreader,它读取CVS文件的标题行以确定返回列的数量和名称;Pivot(实际上是unpivot),它将列组转换为行(例如:phonetype,phonenumber)--我:不再有硬编码的字符串 :);TopNplus,它通过每个分区传递N行和一行额外的总计行。
Oracle 18c
实现了这个机制。
18c Skip_col Polymorphic Table Function Example Oracle Live SQL 和
Skip_col Polymorphic Table Function Example。
本示例展示了如何根据名称/特定数据类型跳过数据。
CREATE PACKAGE skip_col_pkg AS
FUNCTION skip_col(tab TABLE, col columns)
RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg;
FUNCTION describe(tab IN OUT dbms_tf.table_t,
col dbms_tf.columns_t)
RETURN dbms_tf.describe_t;
FUNCTION skip_col(tab TABLE,
type_name VARCHAR2,
flip VARCHAR2 DEFAULT 'False')
RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg;
FUNCTION describe(tab IN OUT dbms_tf.table_t,
type_name VARCHAR2,
flip VARCHAR2 DEFAULT 'False')
RETURN dbms_tf.describe_t;
END skip_col_pkg;
和正文:
CREATE PACKAGE BODY skip_col_pkg AS
FUNCTION describe(tab IN OUT dbms_tf.table_t,
col dbms_tf.columns_t)
RETURN dbms_tf.describe_t
AS
new_cols dbms_tf.columns_new_t;
col_id PLS_INTEGER := 1;
BEGIN
FOR i IN 1 .. tab.column.count() LOOP
FOR j IN 1 .. col.count() LOOP
tab.column(i).pass_through := tab.column(i).description.name != col(j);
EXIT WHEN NOT tab.column(i).pass_through;
END LOOP;
END LOOP;
RETURN NULL;
END;
FUNCTION describe(tab IN OUT dbms_tf.table_t,
type_name VARCHAR2,
flip VARCHAR2 DEFAULT 'False')
RETURN dbms_tf.describe_t
AS
typ CONSTANT VARCHAR2(1024) := upper(trim(type_name));
BEGIN
FOR i IN 1 .. tab.column.count() LOOP
tab.column(i).pass_through :=
CASE upper(substr(flip,1,1))
WHEN 'F' THEN dbms_tf.column_type_name(tab.column(i).description)
!=typ
ELSE dbms_tf.column_type_name(tab.column(i).description)
=typ
END ;
END LOOP;
RETURN NULL;
END;
END skip_col_pkg;
并且样例使用:
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number');
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number', flip => 'True')
SELECT *
FROM skip_col_pkg.skip_col(scott.emp, columns(comm, hiredate, mgr))
WHERE deptno = 20;
我强烈建议阅读整个示例(创建独立函数而不是包调用)。
例如,您可以轻松地重载跳过方法:跳过不以特定前缀/后缀开头/结尾的列。
相关链接:
db<>fidde演示
相关文章:
如何通过Chris Saxon动态更改SQL查询中的列。