如何在 Oracle PL/SQL 中动态地从行参数中获取命名列?

Posted

技术标签:

【中文标题】如何在 Oracle PL/SQL 中动态地从行参数中获取命名列?【英文标题】:How to fetch named column from row parameter dynamically in Oracle PL/SQL? 【发布时间】:2009-08-17 18:37:24 【问题描述】:

我有这样的程序:

PROCEDURE foo(
  p_field_name IN VARCHAR2,
  p_record IN table%rowtype )
IS
  v_value VARCHAR2(100);
BEGIN
  EXECUTE IMMEDIATE 'SELECT p_record.' || p_field_name || ' FROM dual' INTO v_value;
END

Oracle 抱怨 p_record.my_field_name 是一个无效的标识符,这让我相信立即执行是在其他上下文中运行的。

是否可以做我上面想做的事情?

【问题讨论】:

人们所说的实际上是正确的。你不能这样做。如果您愿意,请发布“全局”问题或随时发送给我。 【参考方案1】:

您在 EXECUTE IMMEDIATE 中所做的事情在任何情况下都应该是可行的。你的例子不适合这个,因为它在你的程序之外是不可行的。

一种可能的解决方法 - 传递 ID 而不是整行并从表中选择该单列。虽然如果经常使用这可能会降低性能。

【讨论】:

您的评论回复:执行即时上下文正如我所怀疑的那样,尽管我开始怀疑是否可以使用 sys_context() 一起破解某些东西......并且回复:通过 ID 的解决方法,在一个例如,该函数将在循环中每行调用一次,遍历 700k 行映射文本文件。另一个选择可能并不酷,尽管我承认我没有对其进行分析。感谢您的回复。【参考方案2】:

IF/ELSIF 有什么问题

IF    p_field_name = 'COL1' THEN v_value := p_record.col1
ELSIF p_field_name = 'COL2' THEN v_value := p_record.col2
...
END IF;

您可以从 ALL_TAB_COLUMNS 中的 SELECT 事件中生成它。它可能不漂亮,但它会起作用。

【讨论】:

只是更难维护。说实话,我可能不会把它留在生产代码中——我想我必须找到一种不同的方法来做到这一点。不过感谢您的回答。【参考方案3】:

我认为您尝试做的事情是不可能的。 立即执行命令是动态 SQL 执行。创建“foo”过程时不解析 sql 语句,而是在运行时解析。 对于 oracle,它是“选择 p_record”。 || p_field_name || 'from dual' 是一个 varchar,p_record 也是。所以这解释了为什么你有这个错误。 解决方案是编写类似 if/elsif/... 或 case/when。

【讨论】:

以上是关于如何在 Oracle PL/SQL 中动态地从行参数中获取命名列?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Oracle (PL/SQL) 动态 sql 将数据查询到 %rowtype 变量中

如何使用 pl sql 过程从结构仅在运行时知道的 oracle 表中动态获取数据?

Oracle:使用 SQL 或 PL/SQL 查找动态 SQL 中的错误位置

Oracle_PL/SQL 动态sql

Oracle pl/sql:在事务中执行动态删除

PL/SQL:clob 字符串中的动态查询。如何打开游标?