【问题标题】:Create Stored Procedure in Oracle 11g pl/sql using IF and THEN在 Oracle 11g pl/sql 中使用 IF 和 THEN 创建存储过程
【发布时间】:2013-10-07 23:00:53
【问题描述】:

我在创建此存储过程时遇到了问题,并且在执行时遇到了一些错误。错误包括 SQL 语句被忽略和 SQL 命令未正确结束。我认为所有的代码都很干净。

  • 返回总记录并将其插入 TABLE1 表中的 RECORD_COUNT 变量中。

  • 条件以查看 RECORD_COUNT 是否大于零并转储数据以清除 TABLE1 表。

  • 判断 RECORD_COUNT 是否等于 0 的条件,以便从 EXTERNAL_TABLE 表插入到 TABLE1 表中。

请帮忙。

    CREATE OR REPLACE PROCEDURE sp_INSERT
    (RECORD_COUNT OUT NUMBER)
    IS
    BEGIN   

         SELECT COUNT(*) 
             INTO RECORD_COUNT
             FROM TABLE1;   

         IF RECORD_COUNT > 0 THEN 
             EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLE1'
         END IF;     

        IF RECORD_COUNT = 0 THEN 
        INSERT INTO TABLE1
            (
                JOB_ID,                         
                NUM_SP1,              
                NUM_SP2,              
                NUM_SP3,              
                NUM_SP4,                         
            )
            (SELECT JOB_ID,               
                NUM_SP1,              
                NUM_SP2,              
                NUM_SP3,              
                NUM_SP4,              
            FROM EXTERNAL_TABLE)
        COMMIT;
        END IF;
    END;

【问题讨论】:

  • 您好,错误消息应该会有所帮助 - 它们会为您提供行号。您缺少许多分号,TRUNCATE 是 DDL,因此不能在动态 SQL 之外的 PL/SQL 中执行。

标签: stored-procedures plsql oracle11g syntax-error


【解决方案1】:

首先:您需要; 在您的程序中的任何指令的末尾。
第二TRUNCATEDDL命令,DDL命令在plsql中无效,你可以使用DELETE命令 instaed 或者使用EXECUTE IMMEDIATE Statement
第三:对于insert-select statement,请参阅herehere

CREATE OR REPLACE PROCEDURE sp_INSERT
    (RECORD_COUNT OUT NUMBER)
    IS
    BEGIN   
         SELECT NVL(COUNT(*),0) 
             INTO RECORD_COUNT
             FROM TABLE1;    

         IF RECORD_COUNT > 0 THEN 
             EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLE1';
         END IF; 
         -- or
         IF RECORD_COUNT > 0 THEN 
             DELETE TABLE1;
         END IF; 


        IF RECORD_COUNT = 0 THEN 
        INSERT INTO TABLE1
            (
                JOB_ID,                         
                NUM_SP1,              
                NUM_SP2,              
                NUM_SP3,              
                NUM_SP4                         
            )
            SELECT JOB_ID,               
                NUM_SP1,              
                NUM_SP2,              
                NUM_SP3,              
                NUM_SP4              
            FROM EXTERNAL_TABLE;
        COMMIT;
        END IF;
    END;

/*
 VAR N NUMBER;
     EXCE SP_INSERT(:N);
        PRINT N;


             N
         ----------
             0

          INSERT INTO TABLE1 VALUES(1,1,1,1,1);
      INSERT INTO TABLE1 VALUES(1,1,1,1,1);
     INSERT INTO TABLE1 VALUES(1,1,1,1,1);

     COMMIT;
       VAR N NUMBER;
        EXCE SP_INSERT(:N);
        PRINT N;

             N
          -------
             3

      */

【讨论】:

  • 您的意见对我的帮助最大。
【解决方案2】:

创建或替换过程 EMP_INSERT (RECORD_COUNT OUT NUMBER) 是 开始

     SELECT COUNT(*) 
         INTO RECORD_COUNT
         FROM EMPEE1;   
          IF RECORD_COUNT > 0 THEN 
         EXECUTE IMMEDIATE 'TRUNCATE TABLE EMPEE1';
     END IF; 

     SELECT COUNT(*) 
         INTO RECORD_COUNT
         FROM EMPEE1;  

    IF RECORD_COUNT = 0 THEN 
    INSERT INTO EMPEE1
        (
            ENO,                         
            ENAME,              
            DOJ,              
            DEPTNO,              
            SAL,
            AGE                         
        )
        (SELECT ENO,               
            ENAME,              
            DOJ,              
            DEPTNO,              
            SAL,
            AGE              
        FROM EMPEE);

    COMMIT;
    END IF;
    END;

【讨论】:

    【解决方案3】:

    两个答案都朝着好的方向发展。
    这是另一种选择 - 看看表中的卷是否对 DELETE 命令没有问题:

    /* just preparation for test  here */ 
    create table TABLE1( JOB_ID int, num_sp1 int, num_sp2 int, num_sp3 int, num_sp4 int );
    create table external_table as select * from TABLE1; 
    
    CREATE OR REPLACE PROCEDURE sp_INSERT ( RECORD_COUNT OUT NUMBER )
     IS
    BEGIN   
    
      delete TABLE1; 
      record_count := SQL%rowcount; 
    
      INSERT INTO TABLE1
           ( JOB_ID, NUM_SP1, NUM_SP2, NUM_SP3, NUM_SP4  )
      SELECT JOB_ID, NUM_SP1, NUM_SP2, NUM_SP3, NUM_SP4 
      FROM EXTERNAL_TABLE;
      COMMIT;
    END;
    /
    
    show errors
    

    示例输出:

    SQL> var n number
    SQL> exec sp_insert( :n )
    
    PL/SQL procedure successfully completed.
    
    SQL> print n
    
             N                                                                      
    ----------                                                                      
             0                                                                      
    
    SQL> insert into TABLE1 values ( 1, 1, 1, 1, 1 ) ;
    
    1 row created.
    
    SQL> insert into TABLE1 values ( 1, 1, 1, 1, 1 ) ;
    
    1 row created.
    
    SQL> insert into TABLE1 values ( 1, 1, 1, 1, 1 ) ;
    
    1 row created.
    
    SQL> commit;
    
    Commit complete.
    
    SQL> exec sp_insert( :n )
    
    PL/SQL procedure successfully completed.
    
    SQL> print n
    
             N                                                                      
    ----------                                                                      
             3                                                                      
    

    【讨论】:

      【解决方案4】:

      SELECT 语句后缺少分号。你需要类似的东西

      SELECT COUNT(*) 
        INTO RECORD_COUNT
        FROM TABLE1;   
      

      您也不能将 DDL(如 TRUNCATE)作为静态 SQL 放在 PL/SQL 中。您需要使用动态 SQL。该语句的末尾还需要一个分号。

      EXECUTE IMMEDIATE 'TRUNCATE TABLE table1';
      

      发布确切的错误堆栈(包括行号)总是有帮助的——编译器通常比人类阅读论坛帖子更擅长检测语法错误。

      【讨论】:

        猜你喜欢
        • 2017-12-21
        • 1970-01-01
        • 2020-06-15
        • 2017-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-09
        相关资源
        最近更新 更多