我无法在while循环中创建一个plsql函数。是否可以在while循环中编写plsql函数?

时间:2018-01-29 14:40:09

标签: plsql

        create or replace FUNCTION ACHEHBBDA40(p_sum_date IN VARCHAR2) RETURN NUMBER AS 
          CURSOR BISNES_T_INFO IS
          SELECT  a.TARGETID, a.CLIENTID,b.BSNSID
          FROM CLIENT_XREF_T a
          INNER JOIN BISNES_T b
          ON 
          a.CLIENTID = b.CLIENTID AND      
          a.TYPE = '1' AND               
          b.WORKKBN = '0';

        BEGIN
        DBMS_OUTPUT.PUT_LINE('PGM_NAME');
        LOOP
    BEGIN 
     FETCH BISNES_T_INFO
              INTO  l_compid,l_bsnsid,l_clientid;

      --beginning of nested function in declaration section 
               FUNCTION getClientXref(l_clientid VARCHAR2) RETURN Number AS 

                  CURSOR CLIENT_XREF_T_INFO IS
                  SELECT d.BRNO, d.TRNO
                  FROM CLIENT_XREF_T x INNER JOIN CLIENT_T c ON x.CLIENTID = c.CLIENTID;

                  BEGIN
                  OPEN CLIENT_XREF_T_INFO;
                      FETCH CLIENT_XREF_T_INFO
                      INTO  l_brno,l_trno
                  END;
                  return 1;
                END getClientXref;
    UTL_FILE.PUT_LINE(v_filehandle,l_compid ||CHR(9)|| l_brno ||CHR(9)|| l_trno);

EXCEPTION
 WHEN NO_DATA_FOUND THEN
    -- Close the file after the process is over
                    DBMS_OUTPUT.PUT_LINE('MSGID_ERREND : ' ||commonUtilities.GC_MSGID_ERREND);
                    DBMS_OUTPUT.PUT_LINE('MSG_ERREND : ' ||commonUtilities.GC_MSG_ERREND);
                    DBMS_OUTPUT.PUT_LINE('MSGID_NO_DATA : ' ||commonUtilities.GC_MSGID_NO_DATA);
                    DBMS_OUTPUT.PUT_LINE('MSG_NO_DATA : ' ||commonUtilities.GC_MSG_NO_DATA);
                    RETURN lc_failure;
                EXIT;
          END;


            END LOOP;

当我在while循环中创建嵌套函数getClientXref时,它会抛出编译时错误“Error(213,21):PLS-00103:遇到以下其中一项时遇到符号”GETCLIENTXREF“:=。(@ %;“在sql developer。

3 个答案:

答案 0 :(得分:1)

老实说,我不明白你发布的代码的目的:它从不调用你试图声明的函数......但是,既然你的问题是关于语法,我必须纠正所有其他海报和评论员是什么话说:

您可以在循环中声明过程和函数

以下代码有效!

  begin
     for c in (select * from dict) loop
        DECLARE 
            -- procedure inside a loop
            procedure local_print_current_row is
            begin
               -- here I am even accessing the external 
               -- "c" for loop variable
               dbms_output.put_line(c.table_name || ' -> ' || c.comments);
            end;    

        BEGIN
           local_print_current_row;
        END;
     end loop;
  end;
  1. 当然这只是一个说明语法的“玩具”示例,但是PL / SQL允许您使用declare / begin / exception / end构造几乎在任何地方嵌套声明(不仅仅是变量)。
  2. 在您的代码中编写了注释“ - 在声明部分中嵌套函数的开始”,但您实际上并未定义任何嵌套声明部分。你需要DECLARE关键字。
  3. 很多人都没有意识到在PL / SQL中“开始/结束”与java中的“{”/“}”不同。开始/结束块的完整语法允许所有这些部分:

     DECLARE
        <declarations>
     BEGIN
        <code>
     EXCEPTION
        <exception handlers>
     END
    

    编写“DECLARE”和“EXCEPTION”部分只是可选,但BEGIN / END块实际上是由上述所有部分组成的。

    任何 DECLARE部分中,您可以声明:

    1. 功能和程序
    2. 类型
    3. 游标
    4. 变量
    5. 例外
    6. ...
    7. 并且您在该部分中声明的所有内容仅在相应的begin [/ exception] / end部分中可见。

      此外,您可以在任何可以编写实际“可运行”代码的地方嵌套其他块。这种嵌套可以完成:

      declare
          ...
      begin
            declare
               procedure MyLocalProc is
                  procedure NestedProc is
                  begin
                  end;
               begin
                  .... 
                  declare
                     ...
                  begin
                     ...
                  exception
                     ..
                  end  
                  ... 
               exception
               end    
            begin
               ...
            end 
      
      exception when others then 
            declare
              ...
            begin
              ...  
            end 
      end
      

      P.S.:注意在“procedure is”或“function ... is”之后,“DECLARE”部分是隐式的:这就是为什么你可以在一个过程/函数声明之后立即开始声明东西而不写“declare”。对于触发器不会发生这种情况,如果要添加本地声明,实际上必须编写“声明”。

答案 1 :(得分:0)

我真的不明白为什么你必须在while循环中创建一个函数。功能并不是真正意义上的那种方法。您可以单独创建您的功能,并在每次需要时在while循环内调用它并传递参数。

答案 2 :(得分:-1)

不,你不能在循环中创建函数或过程,你必须使用&#34;声明&#34;之间的空格。并且&#34;开始&#34;或者&#34;之间是#34;或者&#34;开始&#34;去做这个。