如何将当前行传递给oracle用户定义的函数

时间:2017-07-03 20:47:21

标签: oracle11g

我想创建一个内联oracle函数,它将引用当前正在获取的行的列值,并根据我的条件返回一个值。我通过将ROWID传递给函数来尝试相同的操作,并且在函数体中,将使用ROWID获取当前行并操纵值。

CREATE FUNCTION CHECK_STATUS(P_ROWID) RETURN VARCHAR2 IS
   V_ROW MY_TBL%TYPE
BEGIN
   SELECT * INTO V_ROW FROM MY_TBL WHERE ROWID=P_ROWID;
   IF V_ROW.COL1 IS NOT NULL AND
       V_ROW.COL2 IS NOT NULL AND 
       V_ROW.COL3 IS NOT NULL THEN

       RETURN 'OK';
   ELSE
      RETURN 'INCOMPLETE';
   END IF;
END;

此功能在各个地方进一步调用为

SELECT A.*,CHECK_STATUS(ROWID) FROM MY_TBL A;

它可以正常工作,但会严重减慢查询速度超过一千条记录,因为在每次获取行时,函数将再次执行select查询以获取列值。我知道这也可以作为

完成
   CREATE FUNCTION CHECK_STATUS(COL1,COL2,COL3) RETURN VARCHAR2 IS

这里的问题是我想要检查函数中的9个列值,并且在函数的每次调用期间写入列名都很奇怪。我怀疑是否有任何方法可以通过参数(THIS.COL1,THIS.COL2,THIS.COL3)接收函数可以引用当前正在获取的行而不接收ROWID / COLUMNS

1 个答案:

答案 0 :(得分:0)

您可以使用案例表达式为此添加virtual column,而根本没有函数:

alter table my_tbl add (status generated always as
  (case when column1 is null or column2 is null or column3 is null
    -- etc., all 9 columns or whatever else you want to check
    then 'INCOMPLETE' else 'OK' end) virtual);

然后您可以使用以下方式查询:

select column1, column2, ..., status from my_tbl

您还可以在虚拟列上添加索引,如果这对您将如何使用它有用。

如果您想要传递所有列值,您仍然可以使用(确定性)函数 - “看起来奇怪”的部分将隐藏在DDL中,因此查询将无法看到它。听起来好像在这种情况下使用函数会增加很多。