select 语句中的 Apex 5 和 PL/SQL 错误

Apex 5 and PL/SQL error in select statements

我有这个 PL/SQL 代码,它从 Table 执行 select 并在找到完全匹配时插入临时 Table,但在单独的如果找到,视图应显示所有匹配项。因此,假设我有一个名为 SKU001 的零件号并在字段中键入它,它应该在一个字段中显示并插入另一个字段 table。当我只输入 SKU 时,它不应该插入另一个 table,而只显示所有匹配项,如 SKU001、SKU002、SKU003 等。代码工作正常,但我不断收到错误,这对我来说没有意义弥补错误。

所以让我试着分解一下。 假设我有一个名为 TABLENAME 的 table,其中包含以下内容:

NAME  | STOCKCODE | PRICE | other columns ...
Item1 | SKU001    | 12.99
Item2 | SKU002    | 13.99
Item3 | SKU003    | 14.99

临时 table 只有 NAME、STOCKCODE 和 PRICE 列。

为了获取数据,我有 2 个运行以下命令的表格。

select * from TABLENAME where regexp_like(NAME, :P4_SEARCH, 'i') or regexp_like(BARCODE, :P4_SEARCH, 'i') or regexp_like(STOCKCODE, :P4_SEARCH, 'i');

对于 TEMPTABLE,Apex 页面 SQL 是。

select STOCKCODE, NAME, PRICE TEMPTABLE where SESSION_USER=:P4_USER


DECLARE
l_stock VARCHAR2(200);
l_name VARCHAR2(200);
l_price VARCHAR2(200);
BEGIN
select STOCKCODE, NAME, PRICE
into l_stock, l_name, l_price
from TABLENAME where (NAME=:P4_SEARCH) or (BARCODE=:P4_SEARCH) or (STOCKCODE=:P4_SEARCH);
insert into TEMPTABLE (STOCKCODE, NAME, PRICE) 
 values (l_stock, l_name, l_price);
     exception
when too_many_rows then
select STOCKCODE, NAME, PRICE
into l_stock, l_name, l_price
from TABLENAME where regexp_like(NAME, :P4_SEARCH, 'i') or regexp_like(BARCODE, :P4_SEARCH, 'i') or regexp_like(STOCKCODE, :P4_SEARCH, 'i');
when no_data_found then
select STOCKCODE, NAME, PRICE
into l_stock, l_name, l_price
from TABLENAME where regexp_like(NAME, :P4_SEARCH, 'i') or regexp_like(BARCODE, :P4_SEARCH, 'i') or regexp_like(STOCKCODE, :P4_SEARCH, 'i');
END;

当我只有这个:

BEGIN
select STOCKCODE, NAME, PRICE
into l_stock, l_name, l_price
from TABLENAME where regexp_like(NAME, :P4_SEARCH, 'i') or regexp_like(BARCODE, :P4_SEARCH, 'i') or regexp_like(STOCKCODE, :P4_SEARCH, 'i');
END;

每次都完美运行。

如果我只执行这个:

BEGIN
select STOCKCODE, NAME, PRICE
into l_stock, l_name, l_price
from TABLENAME where (NAME=:P4_SEARCH) or (BARCODE=:P4_SEARCH) or (STOCKCODE=:P4_SEARCH);
insert into TEMPTABLE (STOCKCODE, NAME, PRICE)
END;

但是当 运行 整个 PL/SQL 脚本像上面一样时,我得到这样的错误: 当我搜索SKU001时,它会显示Search item并将其添加到TEMPTABLE中,但是当我搜索SKU时它会报错:

ORA-01422: exact fetch returns more than requested number of rows 
ORA-06512: at line 23 
ORA-01403: no data found

注意!!由于我浏览器的格式问题,此处显示的第23行不是上面代码中的第23行,第23行如下:

22 ->     when no_data_found then
23 -> select STOCKCODE, NAME, PRICE into stock, name, price from TABLENAME where regexp_like(NAME, :P4_SEARCH, 'i') or regexp_like(BARCODE, :P4_SEARCH, 'i') or regexp_like(STOCKCODE, :P4_SEARCH, 'i');

同时,如果我清除或重置会话,它显示:

ORA-01403: no data found
ORA-06512: at line 23
ORA-01403: no data found

我觉得很奇怪,因为我为 no_data_foundtoo_many_lines

添加了 exception

我在这里做错了什么?我希望我在这里提供了足够的信息以使其有意义。

最后一记!条形码是搜索的一部分,不会被插入,以防有人询问。搜索基于名称、条形码或股票代码,但名称、价格和股票代码根据搜索显示。 P4_USER 是我单独构建的会话用户,它只执行 select 以仅显示用户的插入内容,而不显示其他用户数据。

尝试INSERT..SELECT

insert into TEMPTABLE (STOCKCODE, NAME, PRICE)
select STOCKCODE, NAME, PRICE
from TABLENAME
where (NAME=:P4_SEARCH) or (BARCODE=:P4_SEARCH) or (STOCKCODE=:P4_SEARCH);

"no_data_found"可能是Oracle自身造成的。 找不到合适的消息给你看。

但是你有没有把"no_data_found"异常放在异常处理程序中?

declare
  ...
begin
  ...
exception
  when no_data_found
  then
    select STOCKCODE, NAME, PRICE 
    into stock, name, price 
    from TABLENAME 
    where regexp_like(NAME, :P4_SEARCH, 'i') 
    or regexp_like(BARCODE, :P4_SEARCH, 'i') 
    or regexp_like(STOCKCODE, :P4_SEARCH, 'i');

  when others
  then
     ...
end;

在我看来你发现了两个例外。

当您搜索 SKU 时,您在执行查询时捕捉到异常 no_data_found

select STOCKCODE, NAME, PRICE
into l_stock, l_name, l_price
from TABLENAME where (NAME=:P4_SEARCH) or (BARCODE=:P4_SEARCH) or (STOCKCODE=:P4_SEARCH)

然后从 when no_data_found 部分执行新查询:

select STOCKCODE, NAME, PRICE
into l_stock, l_name, l_price
from TABLENAME where regexp_like(NAME, :P4_SEARCH, 'i') or regexp_like(BARCODE, :P4_SEARCH, 'i') or regexp_like(STOCKCODE, :P4_SEARCH, 'i');

但是这个查询引发了 new 异常 too_many_rows。是的,这个查询可以用 regexp_like(STOCKCODE, 'SKU', 'i') 条件返回多行。但是当您使用 into 子句时,您必须确信您的查询只会返回一条记录。为避免 too_many_rows 异常,您可以尝试在异常部分更改查询,正如@sagi 所建议的那样:

when no_data_found then
    insert into TEMPTABLE (STOCKCODE, NAME, PRICE)
    select STOCKCODE, NAME, PRICE
    from TABLENAME where regexp_like(NAME, :P4_SEARCH, 'i') or regexp_like(BARCODE, :P4_SEARCH, 'i') or regexp_like(STOCKCODE, :P4_SEARCH, 'i');

第一个查询不会引发 too_many_rows 异常,除非您有重复的 barcode stockcodename

只是为 no_data_found 引发异常,因为第一个查询需要完全匹配,将引发未找到的数据,然后 运行 第二个查询。

DECLARE
L_STOCK VARCHAR2(200);
L_BARCODE VARCHAR2(200);
L_NAME VARCHAR2(200);
L_PRICE VARCHAR2(200);
BEGIN
select STOCKCODE, NAME, PRICE
into l_stock, l_name, l_price
from TABLENAME 
where (:P4_SEARCH=NAME) or (:P4_SEARCH=BARCODE) or (:P4_SEARCH=STOCKCODE);
insert 
into TEMPTABLE (STOCKCODE, NAME, PRICE)
values (l_stock, l_name, l_price);
exception
when no_data_found 
then
select STOCKCODE, NAME, PRICE
into stock, name, price
from TABLENAME 
where regexp_like(NAME, :P4_SEARCH, 'i') or regexp_like(BARCODE, :P4_SEARCH, 'i') or regexp_like(STOCKCODE, :P4_SEARCH, 'i');
end;

这应该会在第一个查询中为您提供 SKU001 的以太匹配并插入到 TEMPTABLE 中,或者如果部分匹配仅显示最后一个查询的结果。