【问题标题】:PLS-00428 INTO clause expected error in PLSQL ProcedurePLS-00428 PLSQL 过程中的 INTO 子句预期错误
【发布时间】:2021-11-05 04:21:42
【问题描述】:

我在 PLSQL 中有一个过程。我在编译时遇到了这些错误:

PROCEDURE FCBSADM.EXTRACT_MONTHLY_DATA 的编译错误

错误:PLS-00428:此 SELECT 语句中应有一个 INTO 子句 行:11 文本:SELECT DISTINCT intl_prod_id,bill_date

错误:提示:参数 'pid_billdate' 已声明但从未用于 'extract_monthly_data' 行:1 文本:创建或替换过程 extract_monthly_data(pid_billdate DATE) 是

此外,如何在pid_billdate 和ab.bill_date 之间建立连接?我愿意接受建议。从现在开始谢谢你。

    create or replace procedure extract_monthly_data(pid_billdate DATE) is
v_cnt      NUMBER;
TYPE prod_ids_t IS TABLE OF apld_bill_rt.intl_prod_id%TYPE INDEX BY PLS_INTEGER; -- whatever the table is 
l_prod_ids   prod_ids_t;  
begin

   execute immediate 'truncate table gpu';
                  
   v_cnt := 0;
   
   SELECT DISTINCT intl_prod_id,bill_date

      FROM apld_bill_rt abr,
           acct_bill ab
      WHERE     abr.cdate > SYSDATE - 1000 
          AND abr.CHRG_TP = 'INSTALLMENT'
          AND abr.TAX_CATG_ID = 'NOTAX'
          AND abr.acct_bill_id = ab.acct_bill_id
          ORDER BY bill_date;
    
    FOR indx IN 1 .. l_prod_ids.COUNT
    loop  
      INSERT INTO GPU
         SELECT AB.ACCT_BILL_ID,
                AB.BILL_NO,
                AB.INV_ID,
                AB.BILL_DATE,
                ba2.bill_acct_id,
                ba1.bill_acct_id parent_bill_acct_id,
                AB.DUE_DATE,
                PG.CMPG_ID,
                ABR.NET_AMT,
                AB.DUE_AMT,
                P.PROD_NUM,
                pds.DST_ID,
                ABR.DESCR,
                p.intl_prod_id 
           FROM apld_bill_rt abr,
                acct_bill ab,
                prod p,
                FCBSADM.PROD_DST pds,
                bill_acct_prod bap,
                bill_acct ba1, 
                bill_acct ba2, 
                prod_cmpg pg
          WHERE ab.intl_bill_acct_id = ba1.intl_bill_acct_id 
                AND AB.ACCT_BILL_ID = ABR.ACCT_BILL_ID 
                AND ba1.intl_bill_acct_id = ba2.parent_bill_acct_id
                AND ba2.intl_bill_acct_id = bap.intl_bill_acct_id  
                AND bap.intl_prod_id = abr.intl_prod_id 
                AND ABR.CHRG_TP = 'INSTALLMENT' 
                AND abr.cdate > SYSDATE - 5
                AND ABR.intl_prod_id = l_prod_ids(indx)
                AND bap.intl_prod_id = pds.intl_prod_id
                AND bap.intl_prod_id = p.intl_prod_id
                AND p.intl_prod_id = pg.intl_prod_id(+);                    

      v_cnt := v_cnt + 1;

      IF MOD (v_cnt, 1000) = 0
      THEN
         COMMIT;
      END IF;
  
    end loop;
    COMMIT;

end;

这是它的最后一个版本

    create or replace procedure extract_monthly_data(pid_billdate DATE) is
v_cnt      NUMBER;
TYPE prod_ids_t IS TABLE OF apld_bill_rt.intl_prod_id%TYPE INDEX BY PLS_INTEGER; -- whatever the table is 
l_prod_ids   prod_ids_t;  
begin

   execute immediate 'truncate table gpu';
                  
   v_cnt := 0;
   
   SELECT DISTINCT abr.intl_prod_id, ab.bill_date BULK COLLECT INTO l_prod_ids
      FROM apld_bill_rt abr,
           acct_bill ab
      WHERE     abr.cdate > SYSDATE - 1000 
          AND abr.CHRG_TP = 'INSTALLMENT'
          AND abr.TAX_CATG_ID = 'NOTAX'
          AND abr.acct_bill_id = ab.acct_bill_id
          ORDER BY bill_date;
    
    FOR indx IN 1 .. l_prod_ids.COUNT
    loop  
      INSERT INTO GPU
      SELECT AB.ACCT_BILL_ID,
            AB.BILL_NO,
            AB.INV_ID,
            AB.BILL_DATE,
            ba2.bill_acct_id,
            ba1.bill_acct_id parent_bill_acct_id,
            AB.DUE_DATE,
            PG.CMPG_ID,
            ABR.NET_AMT,
            AB.DUE_AMT,
            P.PROD_NUM,
            pds.DST_ID,
            ABR.DESCR,
            p.intl_prod_id 
       FROM apld_bill_rt abr
            JOIN acct_bill ab ON AB.ACCT_BILL_ID = ABR.ACCT_BILL_ID 
            JOIN FCBSADM.PROD_DST pds ON 
            JOIN bill_acct_prod bap ON bap.intl_prod_id = abr.intl_prod_id 

                AND bap.intl_prod_id = pds.intl_prod_id 
                AND bap.intl_prod_id = p.intl_prod_id
            JOIN prod p ON bap.intl_prod_id = p.intl_prod_id
            JOIN bill_acct ba1 ON ab.intl_bill_acct_id = ba1.intl_bill_acct_id 
            JOIN bill_acct ba2 ON ba1.intl_bill_acct_id = ba2.parent_bill_acct_id 
                AND ba2.intl_bill_acct_id = bap.intl_bill_acct_id  
            LEFT OUTER JOIN prod_cmpg pg ON p.intl_prod_id = pg.intl_prod_id
            WHERE ABR.CHRG_TP = 'INSTALLMENT' 
            AND abr.cdate > SYSDATE - 5
            AND ABR.intl_prod_id =ANY (
              SELECT intl_prod_id -- no DISTINCT, no ORDER BY
              FROM apld_bill_rt abr
                JOIN acct_bill ab ON abr.acct_bill_id = ab.acct_bill_id
              WHERE abr.cdate > SYSDATE - 1000 
                AND abr.CHRG_TP = 'INSTALLMENT'
                AND abr.TAX_CATG_ID = 'NOTAX'
              );                    

      v_cnt := v_cnt + 1;

      IF MOD (v_cnt, 1000) = 0
      THEN
         COMMIT;
      END IF;
  
    end loop;
    COMMIT;

end;

这是要插入的表

    create table GPU
(
  acct_bill_id        NUMBER(16),
  bill_no             VARCHAR2(30 CHAR),
  inv_id              VARCHAR2(20 CHAR),
  bill_date           DATE,
  bill_acct_id        NUMBER(38),
  parent_bill_acct_id NUMBER(38),
  due_date            DATE,
  cmpg_id             NUMBER,
  net_amt             NUMBER(16,2),
  due_amt             NUMBER(16,2),
  prod_num            VARCHAR2(32 CHAR),
  dst_id              NUMBER(22) not null,
  descr               VARCHAR2(100 CHAR),
  intl_prod_id        NUMBER(14) not null
);

【问题讨论】:

    标签: database oracle plsql rdbms


    【解决方案1】:

    必须是这样的:

    SELECT DISTINCT intl_prod_id
    BULK COLLECT INTO l_prod_ids
    FROM ...
    

    甚至更好的是,使用现代 ANSI 连接语法并且不使用任何循环。会是这样的:

    create or replace procedure extract_monthly_data AS
    BEGIN
       execute immediate 'truncate table gpu';
    
       INSERT INTO GPU
         SELECT AB.ACCT_BILL_ID,
                AB.BILL_NO,
                AB.INV_ID,
                AB.BILL_DATE,
                ba2.bill_acct_id,
                ba1.bill_acct_id parent_bill_acct_id,
                AB.DUE_DATE,
                PG.CMPG_ID,
                ABR.NET_AMT,
                AB.DUE_AMT,
                P.PROD_NUM,
                pds.DST_ID,
                ABR.DESCR,
                p.intl_prod_id 
           FROM apld_bill_rt abr
                JOIN acct_bill ab ON AB.ACCT_BILL_ID = ABR.ACCT_BILL_ID 
                JOIN FCBSADM.PROD_DST pds ON 
                JOIN bill_acct_prod bap ON bap.intl_prod_id = abr.intl_prod_id 
                    AND bap.intl_prod_id = pds.intl_prod_id 
                    AND bap.intl_prod_id = p.intl_prod_id
                JOIN prod p ON bap.intl_prod_id = p.intl_prod_id
                JOIN bill_acct ba1 ON ab.intl_bill_acct_id = ba1.intl_bill_acct_id 
                JOIN bill_acct ba2 ON ba1.intl_bill_acct_id = ba2.parent_bill_acct_id 
                    AND ba2.intl_bill_acct_id = bap.intl_bill_acct_id  
                LEFT OUTER JOIN prod_cmpg pg ON p.intl_prod_id = pg.intl_prod_id
          WHERE ABR.CHRG_TP = 'INSTALLMENT' 
                AND abr.cdate > SYSDATE - 5
                AND ABR.intl_prod_id =ANY (
                  SELECT intl_prod_id -- no DISTINCT, no ORDER BY
                  FROM apld_bill_rt abr
                    JOIN acct_bill ab ON abr.acct_bill_id = ab.acct_bill_id
                  WHERE abr.cdate > SYSDATE - 1000 
                    AND abr.CHRG_TP = 'INSTALLMENT'
                    AND abr.TAX_CATG_ID = 'NOTAX'
                  );   
        COMMIT;
    END;
    

    不明白你的第二个问题,也许你在找

           AND (ABR.intl_prod_id, pid_billdate) =ANY (
                  SELECT intl_prod_id, bill_date
                  FROM apld_bill_rt abr
                  ...
                  )
    

    【讨论】:

    • 您好,谢谢您的回答。我收到此错误:PROCEDURE FCBSADM.EXTRACT_MONTHLY_DATA 的编译错误错误:PL/SQL:ORA-00920:无效的关系运算符行:40 文本:JOIN bill_acct_prod bap ON bap.intl_prod_id = abr.intl_prod_id 错误:PL/SQL:SQL 语句忽略行:22 文本:INSERT INTO GPU
    • 这是一个过程,我想使用 pid_billdate 作为参数,但是这个数据应该在 ab.bill_date 中匹配(来自 acct_bill 表的别名是 ab)。它应该在代码中的某个地方,但我无法将它们放在常规位置。我正在通过编辑问题添加它的最新版本。
    • 你错过了我的建议。根本没有循环,没有 SELECT 语句——只有一个 INSERT。
    • 你能帮我编辑一下吗?不幸的是,我是 pl/sql 的新手,所以对语法有点挑战。如果我删除循环,我还能使用 BULK COLLECTIONS 吗?顺便说一句,我正在添加我想插入的表格脚本。
    • 查看我的更新。其余的我不清楚你在找什么。 “在 pid_billdate 和 ab.bill_date 之间建立连接”是什么意思? 我的代码不起作用,您不能简单地进行复制/粘贴。我不会做你的工作,但你应该知道它的样子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    相关资源
    最近更新 更多