如何使用 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 的免费云中测试了它。
我在 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 的免费云中测试了它。