oracle 函数调用作为insert values语句中的参数

ie3xauqp  于 2023-06-05  发布在  Oracle
关注(0)|答案(2)|浏览(264)

我正在尝试将数据插入到forall循环中。对于这种情况,我不能使用临时变量并预先设置函数的结果。
该函数只是将一个数字Map到一个字符串:

create or replace function GetInvoiceStatus(status number)
    return nvarchar2
as
begin
    case status
        when 0 then return 'New';
        when 200 then return 'Sent';
        when 300 then return 'Accepted';
        end case;

    return '';
end;

当我调用这个函数时,就像:

select GetInvoiceStatus(200) from dual;

我得到了适当的结果。
但是,当我尝试插入数据时,我得到了错误。forall插入:

forall i in 1.. INVOICE_DATA.COUNT
insert into "InvoiceAudit"
("PropertyName", "OldValue", "NewValue" (
            VALUES ('Status', (GetInvoiceStatus(invoice_data(i).status)),
                    ((GetInvoiceStatus((select "Status" from "Invoice" where "InvoiceId" = invoice_data(i).invoiceId)))));

但是,我得到以下错误:
[2023-06-01 15:02:57] [65000][6592] [2023-06-01 15:02:57] ORA-06592:执行CASE语句时未找到CASE [2023-06-01 15:02:57] ORA-06512:在“公共.GETINVOICESTatus”,第9行[2023-06-01 15:02:57] ORA-06512:在“公共发票”,第63行[2023-06-01 15:02:57]位置:5
我已经仔细检查过了,invoice_data(i).Status和另一个select值的结果都是有效的参数(并且涵盖了它们的情况),当在存储过程之外调用时,返回适当的字符串。
语法是不是哪里错了?如果可能的话,我想继续使用forall,因为它比常规的for循环快得多。

laximzn5

laximzn51#

此错误意味着参数值(status)不是case表达式中的case之一(0,200,300)。
如果你执行这个代码select GetInvoiceStatus(555) as dd from dual,你会得到同样的错误。因此,添加ELSE子句如下:

create or replace function GetInvoiceStatus(status number)
    return nvarchar2
as
begin
    case status
        when 0 then return 'New';
        when 200 then return 'Sent';
        when 300 then return 'Accepted';
        else return '';
    end case;
end;
tcbh2hod

tcbh2hod2#

CASE用作PL/SQL表达式(而不是SQL中常用的返回结果的函数)必须做一些事情。如果你的条件都不匹配,它就没有任何关系:

DECLARE
  var_test integer := 1;
BEGIN
  CASE var_test 
    WHEN 2 THEN null; 
  END CASE;
END;

抛出ORA-06592错误。要解决这个问题,添加一个ELSE来捕获任何不满足其他WHEN条件的内容。

DECLARE
  var_test integer := 1;
BEGIN
  CASE var_test 
    WHEN 2 THEN null; 
    ELSE null; 
  END CASE;
END;

工作正常。再次注意,此要求仅适用于用作PL/SQL表达式的CASE..END CASE。大多数时候我们看到的CASE是一个函数,不需要像这样的ELSE(如果没有WHEN子句匹配,它将返回NULL)。但是PL/SQL表达式是另一回事。
我还想补充一点,你不应该为此使用用户定义的函数。只需在SQL中直接使用SQL函数CASE甚至DECODE来执行转换。

相关问题