如何使用 apex_200100.www_flow_t_varchar2 作为 int 或 char

how to use apex_200100.www_flow_t_varchar2 as int or char

我在 Apex 应用程序中有这个 sql 查询

select num_fac, id_fac
from fac
where id_fac in
(select result from (SELECT apex_string.split(id_facs,':') result
                     FROM proc
                     where id_contract=:p50_id_contract))

我的问题是数据类型不一样,因为 id_fac 是一个 INT,结果是 apex_200100.www_flow_t_varchar2 类型,每一行都是这样的

apex_200100.www_flow_t_varchar2('122')
apex_200100.www_flow_t_varchar2('123')
apex_200100.www_flow_t_varchar2('145')
apex_200100.www_flow_t_varchar2('13')

我尝试使用 SUBSTR 和 INSTR,但收到此消息错误

ora-00932 inconsistent datatypes expected char got apex_200100

有什么建议或解决方案吗?

您可以使用 TABLE() 将类型 return 由 apex_string 转换为伪 table。

SELECT column_value
FROM TABLE (SELECT apex_string.split('122:123:145:13',':') result
            FROM dual)

完整的查询应该是这样的:

select num_fac, id_fac
from fac
where id_fac in
(SELECT TO_NUMBER(column_value)
  FROM TABLE (SELECT apex_string.split(id_facs,':') result
              FROM proc
              WHERE id_contract=:p50_id_contract));

如果 id_contract 不是唯一键,那么您可以使用 LISTAGG 和相同的分隔符 ::

将这些行聚合成一个字符串
with fac as (
  select 'a' as num_fac, 1 as id_fac from dual
  union all select 'b' as num_fac, 1 as id_fac from dual
  union all select 'c' as num_fac, 1 as id_fac from dual
  union all select 'd' as num_fac, 2 as id_fac from dual
  union all select 'e' as num_fac, 2 as id_fac from dual
  union all select 'f' as num_fac, 3 as id_fac from dual
  union all select 'g' as num_fac, 4 as id_fac from dual
  union all select 'h' as num_fac, 5 as id_fac from dual),
proc as (
  select 100 as id_contract, '1:2' as id_facs from dual
  union all select 200 as id_contract, '3' as id_facs from dual
  union all select 200 as id_contract, '4:5' as id_facs from dual)
--
select num_fac, id_fac
from fac
where id_fac in
(SELECT TO_NUMBER(column_value)
  FROM TABLE (SELECT apex_string.split(LISTAGG(id_facs,':') WITHIN GROUP (ORDER BY id_facs) ,':') result
              FROM proc
              WHERE id_contract=:p50_id_contract));

只要apex_string.split的输出是一个apex_t_varchar2(看起来像varchar2的table),你需要将它转换成一个结果集来做 in 检查。这可以通过版本 12c 及更高版本提供的横向连接来完成。

/*Sample data*/
create table t as
select
  level as id,
  mod(level, 5) as val
from dual
connect by level < 20
;

/*Sample data for filter*/
create table t_filt as
select
  listagg(level, ':') within group(order by 1) as ids,
  mod(level, 4) as grp
from dual
connect by level < 15
group by mod(level, 8), mod(level, 4)
;
/*Perform filtering*/
select *
from t
where id in (
  select flt_exploded.id
  from t_filt flt_base
    /*Expand list for each row*/
    cross join lateral (
        select to_number(column_value) as id
        from table(apex_string.split(flt_base.ids, ':'))
    ) flt_exploded
  where flt_base.grp = 2
)
;


ID VAL 
-- --- 
 2   2 
10   0 
 6   1 
14   4 

或者执行集合成员检查member of:

/*Perform filtering*/
select *
from t
where exists (
  select 1
  from t_filt flt_base
  where flt_base.grp = 2
    and to_char(t.id, 'TM9') member of apex_string.split(flt_base.ids, ':')
)
;

ID VAL 
-- --- 
 2   2 
 6   1 
10   0 
14   4

不幸的是,我找不到合适的 fiddle 和 APEX 函数,所以我在 Oracle 的免费云中测试了它。