oracle 将整个实际行传递给函数

x759pob2  于 2022-11-22  发布在  Oracle
关注(0)|答案(3)|浏览(194)

我想知道是否仍然不可能将实际行作为参数传递给oracle中的函数或过程。我已经看到了一些与此主题相关的问题,但还没有找到适合我的答案。我需要做如下操作:

function my_func(myrow t%rowtype)AS
BEGIN
END;

因此,该函数将获取该行作为参数。

Select 
   t.c1, 
   my_func(t.*) -- where t.* is actual row processed.
from t;

在select语句中,我希望传递一行,这实际上是processed。我希望避免传递许多参数,如果我像这样分别传递它们,就会出现这种情况:

Select 
       t.c1, 
       my_func(t.c1,... t.c10) 
    from t;

我也不想传递一个实际的id,因为我不想在函数中做额外的选择。

laik7k3q

laik7k3q1#

如果 Oracle 能够 按照 您 的 建议 处理 行 类型 , 那 就 太 好 了 。 不幸 的 是 , 它 不能 。 查询 中 的 语法 是 不 允许 的 , 因为 Oracle 的 SQL 不 知道 PL/SQL 的 行 类型 。
我 建议 您 使用 行 的 ROWID , 这样 函数 就 可以 立即 访问 行 。 这 与 使用 行 的 主键 ( 例如 ID ) 不同 , 因为 Oracle 不必 查找 行 。 使用 ROWID , 它 已经 知道 行 的 位置 。

# # 函数

CREATE OR REPLACE FUNCTION my_func(p_rowid urowid) RETURN INTEGER AS
  v_row mytable%ROWTYPE;
BEGIN
  SELECT * INTO v_row FROM mytable WHERE rowid = p_rowid;
  RETURN v_row.some_column + v_row.some_other_column;
END;

中 的 每 一 个

# # 查询

select t.*, my_func(t.rowid)
from mytable t;

格式

mnowg1ta

mnowg1ta2#

我 支持@Thorsten 使用 rowid 的 建议 , 但是 为了 好玩 , 您 可以 通过 将 整 行 转换 为 JSON 来 解决 这个 限制 - - 因为 json_object() 函数 确实 允许 将 t.* 作为 参数 - - 然后 在 函数 中 从 JSON 中 提取 所 需 的 值 。
例如 , 如果 您 的 数据 表 有 数据 行 c2 做为 日期 , 而 您 想要 在 其中 加上 7 天 , 您 可以 执行 下列 动作 :

function my_func(myrow json) return date AS
BEGIN
  return json_value(myrow, '$.C2' returning date) + interval '7' day;
END;
/

中 的 每 一 个
然后 将 其 命名 为 :

select 
   t.c1, 
   my_func(cast(json_object(t.*) as json))
from t;

格式
fiddle 的 最 大 值
与 使用 rowid 进行 重新 查询 相比 , 这 看 起来 并 不 更 直观 , 而且 性能 可能 更 差 ( 因为 数据 无论 如何 都会 被 缓存 , 并且 与 JSON 之间 的 转换 可能 会 有 更 高 的 开销 ) 。
这 两 种 方法 看 起来 都 比 将 列 作为 单独 的 参数 列出 有用 得 多 。 如果 表 定义 改变 了 , 那么 函数 和 调用 将 自动 拾取 添加/删除 的 列 ;但是 如果 函数 需要 引用 添加 的 列 或 停止 引用 删除 的 列 ( 否则 将 导致 错误 ) , 则 仍 需要 修改 该 函数 。

0lvr5msh

0lvr5msh3#

%ROWTYPE语法创建了一个PL/SQL记录数据类型,该数据类型可用于PL/SQL范围(但不能用于SQL范围)。
因此:

Select t.c1, 
       my_func(t.*) -- where t.* is actual row processed.
from   t;

将不起作用,因为(1)语法不受支持,(2)无法在SQL作用域中创建PL/SQL记录类型。
但是,使用PL/SQL时,如果声明函数:

CREATE FUNCTION my_func(myrow t%rowtype) RETURN NUMBER
IS
BEGIN
  DBMS_OUTPUT.PUT_LINE( myrow.id || ', ' || myrow.name );
  RETURN 42;
END;
/

则可以使用PL/SQL块并通过游标循环,将每一行传递给函数:

DECLARE
  unused NUMBER;
BEGIN
  DBMS_OUTPUT.ENABLE;
  FOR i IN (SELECT * FROM t) LOOP
    unused := my_func(i);
  END LOOP;
END;
/

其中,对于示例数据:

CREATE TABLE t (id, name) AS
  SELECT 1, 'Alice' FROM DUAL UNION ALL
  SELECT 2, 'Betty' FROM DUAL UNION ALL
  SELECT 3, 'Carol' FROM DUAL UNION ALL
  SELECT 4, 'Debra' FROM DUAL;

输出:

1, Alice
2, Betty
3, Carol
4, Debra

fiddle

相关问题