【问题标题】:sql error generated生成sql错误
【发布时间】:2018-12-05 06:37:22
【问题描述】:

错误从命令的第 254 行开始 -

错误报告:

ORA-06550:Ligne 2,colonne 21:PLS-00103:符号“DECLARE” rencontré à la place d'un des symbols suivants :

开始函数pragma过程子类型类型
当前游标删除存在 先前的符号“开始”一个 été substitué à “DECLARE” 倒继续。 ORA-06550:Ligne 66,colonne 34:PLS-00103:符号“(”rencontréà la place d'un des symbols suivants :

ORA-06550:Ligne 68,colonne 34:PLS-00103:符号“(” rencontré à la place d'un des symbols suivants :

ORA-06550: Ligne 71, Colonne 27: PLS-00103: 符号 "文件结尾" rencontré à la place d'un des symbols suivants :

( 开始 case 声明结束异常退出 goto if loop mod
null pragma raise return select update while with

【问题讨论】:

  • 你必须打开光标然后循环然后在循环中你打开第二个光标并循环,顺便说一下你使用oracle的方式应该是数字而不是numeirc和varchar2而不是varchar
  • 你为什么要这样做?您应该编写一个 SELECT 语句来获取您之后的行,然后您可以在 INSERT 语句中使用它。比遍历两个游标并执行逐行(又名逐行)插入更高效、更高效。
  • @Boneist - 好点,做得好。这看起来像是在尝试将 SQL Server 代码移植到 Oracle 中,而只做最少的更改。 MSSQL 是另一个国家,他们在那里做的事情不同;-)

标签: sql oracle plsql oracle-sqldeveloper


【解决方案1】:

我注意到您使用了一些 sql server 语法(例如 numeric、varchar、deallocate),我更正了它们并添加了一些 cmets。我也用另一种方式写游标。 请检查代码并告诉我是否产生错误。

DECLARE
  CUR_ID_AUTORISATION NUMBER(2); -- it should be number instead and specific the size of the datatype
  CUR_OPERATION       VARCHAR(100); -- it should be varchar2 instead and specific the size 

  CURSOR CURAUTORISATIONS IS
    SELECT AUT.ID_AUTORISATION
      FROM PP3_AUTORISATION AUT
     WHERE AUT.ID_PLAN IN (SELECT PDP.ID_PLAN
                             FROM PP3_PLAN_DE_PREVENTION PDP
                            WHERE PDP.ID_PLAN = 3059)
       AND AUT.NUM_REVISION_PLAN =
           (SELECT MAX(NUM_REVISION_PLAN)
              FROM PP3_AUTORISATION
             WHERE ID_PLAN = 3059);

  CURSOR CUROPERATIONS IS
    SELECT OPE.OPERATION
      FROM PP4_OPERATION ope
     WHERE ID_AUTORISATION IN
           (select id_autorisation
              from pp3_autorisation AUT
             WHERE AUT.ID_PLAN = 3059
               AND AUT.NUM_REVISION_PLAN =
                   (SELECT MAX(NUM_REVISION_PLAN) - 1
                      FROM pp3_autorisation
                     WHERE ID_PLAN = 3059));

  -- OPEN CURAUTORISATIONS;
  -- OPEN CUR_OPERATION;
  --BEGIN

BEGIN
  -- Open first cursor
  for CUR_ID_AUTORISATION in CURAUTORISATIONS -- USING for loop cursor loop instead of open, and here you already fetched the data.
   LOOP
      EXIT WHEN CUROPERATIONS%NOTFOUND; 

    dbms_output.put_line('Hi');
    -- Open second cursor
    for CUR_OPERATION in CUROPERATIONS LOOP
      dbms_output.put_line('Hi second time');
      -- remove the comment.
          INSERT INTO PP4_OPERATION
           VALUES
             (1, CUR_OPERATION.OPERATION, CUR_ID_AUTORISATION.ID_AUTORISATION);

    end loop;
    --close CURAUTORISATIONS;
  --close CUROPERATIONS;
  --DEALLOCATE(CURAUTORISATIONS); -- there is not deallocate in oracle 
  --DEALLOCATE(CUROPERATIONS); -- there is not deallocate in oracle 

  end loop;

end;
/

【讨论】:

  • 它正确显示值,但是当我取消注释这部分时:INSERT INTO PP4_OPERATION VALUES (SEQ2_Operation.NextVal, CUR_OPERATION, CUR_ID_AUTORISATION);它生成: apport d'erreur - ORA-06550:Ligne 44,colonne 54:PLS-00382:表达式 du mauvais 类型 ORA-06550:Ligne 44,colonne 39:PLS-00382:表达式 du mauvais 类型 06550.00000 -“第 %s 行,第 %s 列:\n%s" *原因:通常是 PL/SQL 编译错误。 *行动:
  • 事实上,我不需要循环内的循环,因为它给出了(需要的行数 * 需要的行数),例如:如果我有 3 行,我将获得 9结果为行
  • @Soufiane 好吧,我实际上不知道你在做什么,我只是在帮助解决错误你可以调整任何你想要的,请在插入部分找到我的编辑,删除数字 1 并添加你的序列.
  • 光标FOR循环会自动退出,所以你可以删除EXIT WHEN CUROPERATIONS%NOTFOUND;
【解决方案2】:

你不能在声明部分打开一个CURSOR,错误属于那个。 您不需要为每个声明使用 DECLARE,它应该每个块只使用一次。 在这里,我将那些光标 OPEN 移到了执行部分,它现在应该可以工作了。

DECLARE
CUR_ID_AUTORISATION NUMERIC;
CUR_OPERATION VARCHAR;

CURSOR CURAUTORISATIONS IS 
SELECT  AUT.ID_AUTORISATION 
FROM   PP3_AUTORISATION AUT
WHERE AUT.ID_PLAN IN
        ( SELECT  PDP.ID_PLAN
            FROM   PP3_PLAN_DE_PREVENTION PDP
            WHERE  PDP.ID_PLAN = 3059     )
 AND    AUT.NUM_REVISION_PLAN = 
        (  SELECT MAX(NUM_REVISION_PLAN)       
             FROM  PP3_AUTORISATION 
             WHERE  ID_PLAN = 3059 );
CURSOR CUROPERATIONS IS
     SELECT  OPE.OPERATION 
        FROM PP4_OPERATION ope 
        WHERE ID_AUTORISATION IN
        (select id_autorisation 
            from pp3_autorisation AUT 
            WHERE AUT.ID_PLAN = 3059 
            AND AUT.NUM_REVISION_PLAN =   (
                             SELECT   MAX(NUM_REVISION_PLAN) - 1      
                             FROM pp3_autorisation
                             WHERE ID_PLAN = 3059) );    
BEGIN       
    OPEN CURAUTORISATIONS; 
    OPEN CUR_OPERATION;

   LOOP
        FETCH CURAUTORISATIONS INTO CUR_ID_AUTORISATION;
        EXIT WHEN CURAUTORISATIONS%NOTFOUND;
        FETCH CUROPERATIONS INTO CUR_OPERATION;
        EXIT WHEN CUROPERATIONS%NOTFOUND;

        INSERT INTO PP4_OPERATION 
        VALUES ( SEQ2_Operation.NextVal ,
                 CUR_OPERATION , 
                 CUR_ID_AUTORISATION );
    END LOOP;

    CLOSE CURAUTORISATIONS ;
    CLOSE CUROPERATIONS ;    
END;

【讨论】:

  • 注意:在 Oracle PL/SQL 中 DEALLOCATE 不是必需的(并且无效)。
【解决方案3】:

DECLARE 在 PL/SQL 中是一个完整的块,不像例如在 T-SQL 中。您不能有多个 DECLARE 语句,但在 BEGIN ... END 之前的那个块中声明多个变量。

DECLARE
  CUR_ID_AUTORISATION NUMERIC;
  CUR_OPERATION VARCHAR;
BEGIN
  ...
END;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    相关资源
    最近更新 更多