Oracle LISTAGG()用于查询使用
因此,我试图利用listag函数简单地构建一个逗号分隔的列表,以便在基础查询中使用。列表生成工作正常,我只是出于调试目的应用了一个输出,在这里我可以看到我的列表的原样: 价值观: ‘AB’、‘AZ’、‘BC’、‘CA’、‘CT’、‘DC’、‘FL’、‘FO’、‘GA’、‘IL’、‘KS’、‘MA’、‘MB’、‘ME’、‘MN’、‘MS’、‘MT’、‘NB’、‘NC’、‘NL’、‘NOVA’ SCOTIA’、‘NS’、‘NT’、‘NU’、‘NY’、‘ON’、‘安大略’、‘OR’、‘PE’、‘QC’、‘魁北克’、‘魁北克’、‘萨斯喀彻温’、‘SK’、‘TX’、‘VT’、‘WA’、‘YT’ 当我试图将这个列表变量传递给我的查询时,只是为了看看是否会返回任何内容,什么也不会返回,但是如果我按原样从上面复制/通过省/州列表,而不是在where子句中使用v_Province,我会返回一个结果。我做错了什么Oracle LISTAGG()用于查询使用,oracle,plsql,oracle11g,Oracle,Plsql,Oracle11g,因此,我试图利用listag函数简单地构建一个逗号分隔的列表,以便在基础查询中使用。列表生成工作正常,我只是出于调试目的应用了一个输出,在这里我可以看到我的列表的原样: 价值观: ‘AB’、‘AZ’、‘BC’、‘CA’、‘CT’、‘DC’、‘FL’、‘FO’、‘GA’、‘IL’、‘KS’、‘MA’、‘MB’、‘ME’、‘MN’、‘MS’、‘MT’、‘NB’、‘NC’、‘NL’、‘NOVA’ SCOTIA’、‘NS’、‘NT’、‘NU’、‘NY’、‘ON’、‘安大略’、‘OR’、‘PE’、‘QC’
DECLARE
v_PROVINCE varchar2(500);
v_results varchar2(1000);
BEGIn
dbms_output.enable(1000000);
Select '''' || LISTAGG(STATE, ''',''') WITHIN GROUP (ORDER BY STATE) || '''' PROV
INTO v_PROVINCE
from (Select distinct STATE from ADDRDATA where STATE IS NOT NULL);
DBMS_OUTPUT.PUT_LINE('VALUES: ' || v_PROVINCE);
Select CITY
INTO v_results
from VWPERSONPRIMARYADDRESS
where state in (v_Province)
AND ROWNUM <= 1;
DBMS_OUTPUT.PUT_LINE(v_results);
END;
/
您尝试执行的操作将不起作用,因为IN运算符将逗号分隔的列表视为单个值。理论上,您可以将值收集到单个字符串中,然后将字符串解析为单个值,以便下一个查询能够解释它。然而,这将是一个非常糟糕的主意 更好的方法是使用数组将值列表从第一个查询传递到第二个查询:
create type nt_varchar_50 as table of varchar2(10)
/
DECLARE
v_PROVINCE nt_varchar_50;
v_results varchar2(1000);
cursor cur_provinces is
Select distinct STATE from ADDRDATA where STATE IS NOT NULL;
i pls_integer;
BEGIN
dbms_output.enable(1000000);
open cur_provinces;
fetch cur_provinces bulk collect into v_PROVINCE;
close cur_provinces;
DBMS_OUTPUT.PUT('VALUES: ');
for i in v_PROVINCE.first .. v_province.last loop
if i <> 1 then
DBMS_OUTPUT.PUT(', ');
end if;
DBMS_OUTPUT.PUT(v_PROVINCE(i));
end loop;
DBMS_OUTPUT.PUT_LINE();
Select CITY
INTO v_results
from VWPERSONPRIMARYADDRESS
where state in (select * from table(v_Province))
AND ROWNUM <= 1;
DBMS_OUTPUT.PUT_LINE(v_results);
END;
/
当然,即使是这样,也比一开始就使用一条SQL语句的效率要低得多。实际上,如果您需要在两个查询之间执行某种不适合SQL的处理,或者可能需要多次使用第一个结果集,则只应使用这种技术。首先,如果可能的话,在一条语句中执行所有操作几乎总是更有效的 第二个查询不起作用,因为将所有内容返回到单个字符串中。这不是IN语句所需的逗号分隔列表 不过,有一个小技巧可以绕过这个问题。假设您在两个SELECT语句之间使用字符串,您可以使用它将字符串转换为可用的内容 像这样的事情会奏效
select city
from vwpersonprimaryaddress
where state in (
select regexp_substr(v_province,'[^'',]+', 1, level)
from dual
connect by regexp_substr(v_province, '[^'',]+', 1, level) is not null
)
变量v_province必须更改为引用两次,例如'AB,AZ,BC',才能起作用
这是一张谢谢!!我知道oracle解释列表值的方式可能有问题,但我不确定为什么。。。我从未使用过regexp_substr函数,但我将进一步探讨它,因为它似乎可以实现这个功能。。。