如何将值从单个列存储到oracle中的单个变量中?

时间:2019-10-17 07:23:34

标签: oracle plsql collections plsql-package

以下是我的代码:

SELECT
      /*+ parallel (sales 8) */     
      COUNT(1)
    INTO v_datacount_actualtable
    FROM sales
    WHERE processingunitseq=38
    AND (compensationdate BETWEEN TO_DATE(v_startdate,'DD-MON-YYYY') AND TO_DATE(v_enddate,'DD-MON-YYYY')
    OR eventtypeseq IN
      (SELECT EVENTTYPESEQ FROM EPS_FRS_PAYMENTS
      ));

SELECT EVENTTYPESEQ FROM EPS_FRS_PAYMENTS将返回4个值。所以我不能做一个简单的选择入。

我想将SELECT EVENTTYPESEQ FROM EPS_FRS_PAYMENTS的结果存储到变量中,并使代码类似于以下内容,以使子查询不会每次都执行。

SELECT
      /*+ parallel (sales 8) */     
      COUNT(1)
    INTO v_datacount_actualtable
    FROM sales
    WHERE processingunitseq=38
    AND (compensationdate BETWEEN TO_DATE(v_startdate,'DD-MON-YYYY') AND TO_DATE(v_enddate,'DD-MON-YYYY')
    OR eventtypeseq = v_frseventpeseqs );

SELECT EVENTTYPESEQ FROM EPS_FRS_PAYMENTS返回四个值:

1,
2,
3,
4,

我不想在代码中对这些值进行硬编码,因为这是一种不好的做法。需要像v_frseventypeseqs这样的变量。

我该怎么做-将数组/集合/记录/批量收集到其中?

4 个答案:

答案 0 :(得分:0)

创建类型(如果不存在)

CREATE OR REPLACE 
TYPE t_number1 AS TABLE OF NUMBER(8,0)

它是数字数组

并在PL / SQL中使用

declare
v_frseventpeseqs t_number1;
begin
    SELECT EVENTTYPESEQ bulk collect 
    into v_frseventpeseqs 
    FROM EPS_FRS_PAYMENTS;

    for i in (select t.column_value id from table(v_frseventpeseqs) t)
    loop
        dbms_output.put_line(i.id );
    end loop;

end;

仅在(选择t.column_value 来自表(v_frseventpeseqs)t)

答案 1 :(得分:0)

您可以使用WITH子句。优点是重复引用子查询可能更有效,因为可以轻松地从临时表中检索数据,而不是每个引用都可以对其进行查询。

WITH eventtypeseq_query AS 
     (SELECT EVENTTYPESEQ 
      FROM EPS_FRS_PAYMENTS)
SELECT
       /*+ parallel (sales 8) */   
       COUNT(1)
INTO v_datacount_actualtable
FROM sales
WHERE processingunitseq=38
  AND (compensationdate BETWEEN TO_DATE(v_startdate,'DD-MON-YYYY') AND TO_DATE(v_enddate,'DD-MON-YYYY')
        OR eventtypeseq IN eventtypeseq_query);

您可以在此处找到更多信息: https://oracle-base.com/articles/misc/with-clause

答案 2 :(得分:0)

因为

SELECT EVENTTYPESEQ FROM EPS_FRS_PAYMENTS

没有相关性,您在这里不需要任何“优化”-Oracle将只运行一次此子查询。

答案 3 :(得分:0)

与使用EXISTS相比,使用IN总是在性能上更好。 另外,如果您编写此查询以使其在LIVE环境中正常运行,建议不要使用/*+ parallel */之类的HINT。提示仅应用于即席查询。

我已使用EXISTS在下面重新编写了您的查询:

SELECT
    /*+ parallel (sales 8) */     
    COUNT(1)
    INTO v_datacount_actualtable
    FROM sales sl
    WHERE processingunitseq=38
    AND (compensationdate BETWEEN TO_DATE(v_startdate,'DD-MON-YYYY') AND TO_DATE(v_enddate,'DD-MON-YYYY')
    OR EXISTS ( SELECT 1 from EPS_FRS_PAYMENTS efp where s.eventtypeseq = efp.eventtypeseq);