我有一个我多次重复使用的元组:
with ICC_DATA_REQS AS
(
select ml_tran_id, tran_type, msg_type, icc_data as icc_data_req from TRANEMV2G where msg_type = 'CQ' and (BUSINESS_DT, ML_TRAN_ID) IN (
SELECT BUSINESS_DT, ML_TRAN_ID
FROM TRANRSP2G
WHERE SETTLE_FILE_ID = -1)
),
ICC_DATA_RESP AS
(
select ml_tran_id, tran_type, msg_type, icc_data as icc_data_rsp from TRANEMV2G where msg_type = 'CS' and (BUSINESS_DT, ML_TRAN_ID) IN (
SELECT BUSINESS_DT, ML_TRAN_ID
FROM TRANRSP2G
WHERE SETTLE_FILE_ID = -1)
),
ICC_DATA_ADVC AS
(
select ml_tran_id, tran_type, msg_type, orig_ml_tran_id, icc_data as icc_data_adv from TRANEMV2G where msg_type = 'CA' and (BUSINESS_DT, ORIG_ML_TRAN_ID) IN (
SELECT BUSINESS_DT, ML_TRAN_ID
FROM TRANRSP2G
WHERE SETTLE_FILE_ID = -1)
)
我想做的是:
SELECT BUSINESS_DT, ML_TRAN_ID INTO vpairs
FROM TRANRSP2G
WHERE SETTLE_FILE_ID = -1
然后在其他查询中使用vpairs。这可能吗?我一直遇到未知的变量错误。
另外,我这样做的原因是表TRANEMV2G有3条记录,我需要3条记录中的数据作为3列。我找不到更好的办法。
答案 0 :(得分:3)
您可以在另一个CTE中检索它们:
with p2g as
(
select business_dt, ml_tran_id
from tranrsp2g
where settle_file_id = -1
),
icc_data_reqs as
(
select v2g.ml_tran_id, tran_type, msg_type, icc_data as icc_data_req
from p2g
join tranemv2g v2g
on v2g.business_dt = p2g.business_dt
and v2g.ml_tran_id = p2g.ml_tran_id
where v2g.msg_type = 'CQ'
),
icc_data_resp as
(
select v2g.ml_tran_id, tran_type, msg_type, icc_data as icc_data_rsp
from p2g
join tranemv2g v2g
on v2g.business_dt = p2g.business_dt
and v2g.ml_tran_id = p2g.ml_tran_id
where v2g.msg_type = 'CS'
),
icc_data_advc as
(
select v2g.ml_tran_id, tran_type, msg_type, orig_ml_tran_id, icc_data as icc_data_adv
from p2g
join tranemv2g v2g
on v2g.business_dt = p2g.business_dt
and v2g.orig_ml_tran_id = p2g.ml_tran_id
where v2g.msg_type = 'CA'
)
或
with p2g as
(
select business_dt, ml_tran_id
from tranrsp2g
where settle_file_id = -1
),
icc_data_reqs as
(
select ml_tran_id, tran_type, msg_type, icc_data as icc_data_req
from tranemv2g
where msg_type = 'CQ'
and (business_dt, ml_tran_id) in (select business_dt, ml_tran_id from p2g)
),
icc_data_resp as
(
select ml_tran_id, tran_type, msg_type, icc_data as icc_data_rsp
from tranemv2g
where msg_type = 'CS'
and (business_dt, ml_tran_id) in (select business_dt, ml_tran_id from p2g)
),
icc_data_advc as
(
select ml_tran_id, tran_type, msg_type, orig_ml_tran_id, icc_data as icc_data_adv
from tranemv2g
where msg_type = 'CA'
and (business_dt, orig_ml_tran_id) in (select business_dt, ml_tran_id from p2g)
)
不确定是否比你拥有的要好得多。
如果你想要一个PL / SQL变量,那么因为你想在SQL上下文中使用它,它需要是一个SQL级别的类型:
create type t_tuple as object (business_dt date, ml_tran_id number)
/
create type t_tuple_tab as table of t_tuple
/
declare
v_tuples t_tuple_tab;
begin
select t_tuple(business_dt, ml_tran_id)
bulk collect into v_tuples
from tranrsp2g
where settle_file_id = -1;
with icc_data_reqs as
(
select ml_tran_id, tran_type, msg_type, icc_data as icc_data_req
from tranemv2g
where msg_type = 'CQ'
and (business_dt, ml_tran_id) in
(select business_dt, ml_tran_id from table(v_tuples))
),
...
或加入表集合表达式。除非您将在代码中稍后重新使用元组列表,否则这似乎并没有超过您的原始代码或使用额外的CTE。
但是,如果我理解你在做什么,你可以查询一次表并转动结果,至少如果你是11g或以上:
select * from
(
select v2g.ml_tran_id, tran_type, msg_type, orig_ml_tran_id, icc_data
from tranrsp2g p2g
join tranemv2g v2g
on v2g.business_dt = p2g.business_dt
and ((v2g.msg_type in ('CQ', 'CS') and v2g.ml_tran_id = p2g.ml_tran_id)
or (v2g.msg_type = 'CA' and v2g.orig_ml_tran_id = p2g.ml_tran_id))
where p2g.settle_file_id = -1
)
pivot (max(icc_data) for (msg_type) in ('CQ' as req, 'CS' as rsp, 'CA' as adv))
答案 1 :(得分:1)
如果这些是常量值,那么您可以将它们存储在包中:
CREATE TABLE TRANRSP2G (
BUSINESS_DT DATE,
ML_TRAN_ID INT,
SETTLE_FILE_ID INT
);
CREATE TYPE TRANRSP2G_PAIR IS OBJECT(
BUSINESS_DT DATE,
ML_TRAN_ID INT
);
/
CREATE TYPE TRANRSP2G_PAIR_TABLE IS TABLE OF TRANRSP2G_PAIR;
/
CREATE PACKAGE TRANRSP2G_DATA AS
FUNCTION getData RETURN TRANRSP2G_PAIR_TABLE;
END;
/
CREATE PACKAGE BODY TRANRSP2G_DATA AS
pairs TRANRSP2G_PAIR_TABLE;
FUNCTION getData RETURN TRANRSP2G_PAIR_TABLE
IS
BEGIN
RETURN pairs;
END;
BEGIN
SELECT TRANRSP2G_PAIR( BUSINESS_DT, ML_TRAN_ID )
BULK COLLECT INTO pairs
FROM TRANRSP2G
WHERE SETTLE_FILE_ID = -1;
END;
/
(注意:加载包时将填充pairs
集合,并且存储的数据将保持静态[即使基础表发生更改],因此您不应将此方法用于非静态数据。)
然后你可以这样做:
WITH ICC_DATA_REQS AS
(
select ml_tran_id, tran_type, msg_type, icc_data as icc_data_req
from TRANEMV2G
where msg_type = 'CQ'
and TRANRSP2G_PAIR(BUSINESS_DT, ML_TRAN_ID)
MEMBER OF TRANRSP2G_DATA.getData()
),
...
答案 2 :(得分:0)
如果在连接时TRANRSP2G(对于SETTLE_FILE_ID = -1)的值不是太大,则可以在其他地方使用该列表。
LISTAGG是一个选项。 (或此处描述的其他方法:https://oracle-base.com/articles/misc/string-aggregation-techniques)
SELECT LISTAGG(BUSINESS_DT || '_p_' || ML_TRAN_ID, ';')
WITHIN GROUP (ORDER BY BUSINESS_DT || '_x_' || ML_TRAN_ID)
INTO vpairs
FROM TRANRSP2G
WHERE SETTLE_FILE_ID = -1;
然后vpairs可以与INSTR一起使用
select ml_tran_id, tran_type, msg_type, icc_data as icc_data_req
from TRANEMV2G where msg_type = 'CQ'
and INSTR(vpairs, BUSINESS_DT || '_x_' || ML_TRAN_ID) <> 0