【问题标题】:how to use apex_200100.www_flow_t_varchar2 as int or char如何使用 apex_200100.www_flow_t_varchar2 作为 int 或 char
【发布时间】:2021-11-05 06:32:16
【问题描述】:

我在 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

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

【问题讨论】:

标签: sql oracle oracle-apex


【解决方案1】:

只要apex_string.split 的输出是apex_t_varchar2(看起来像varchar2 的表),您需要将其转换为结果集以进行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

很遗憾,我找不到合适的 APEX 函数,所以我在 Oracle 的免费云中对此进行了测试。

【讨论】:

    【解决方案2】:

    您可以使用TABLE()将apex_string返回的类型转换为伪表。

    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));
    

    【讨论】:

    • 这是我最初编写查询的方式,但我得到了这个错误``` ORA-01427:单行子查询返回多行```
    • proc 中是否有不止一行的id_contract
    • 是的,显然它返回了一个 apex_t_varchar2 数组
    • id_contractproc 中不是唯一时,我更新了我的答案以提供解决方案
    • 这正是我要找的东西谢谢!!
    猜你喜欢
    • 2017-03-21
    • 1970-01-01
    • 2019-11-15
    • 2013-06-27
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多