匿名块中的 Oracle 游标循环给出 PLS-00103 错误代码

Oracle Cursor Loop in anonymous block giving PLS-00103 Error code

此 SQL 运行良好,它可以执行我希望它执行的所有操作,只是我要求它只输出查询结果。因此,我出于这样做的目的围绕它包装了一些代码。查看下一个区块...

SELECT 
  'NO_PROBLEM' 
FROM 
  DUAL 
WHERE 
  NOT EXISTS (
    SELECT 
      UPPER(VALUE) 
    FROM 
      V$SYSTEM_PARAMETER 
    WHERE 
      UPPER(NAME)= 'O7_DICTIONARY_ACCESSIBILITY' 
      AND UPPER(VALUE) != 'FALSE'
  ) 
UNION ALL 
SELECT 
  'PROBLEM' 
FROM 
  DUAL 
WHERE 
  EXISTS (
    SELECT 
      UPPER(VALUE) 
    FROM 
      V$SYSTEM_PARAMETER 
    WHERE 
      UPPER(NAME)= 'O7_DICTIONARY_ACCESSIBILITY' 
      AND UPPER(VALUE) != 'FALSE'
  )

这是我添加了一些包装的地方

        DECLARE
          v_07_check VARCHAR2(10);
          
            CURSOR c_07_check IS

            SELECT 'NO_PROBLEM'
            FROM   dual
            WHERE  NOT EXISTS
                   (
                          SELECT upper(value)
                          FROM   v$system_parameter
                          WHERE  upper(name)='O7_DICTIONARY_ACCESSIBILITY'
                          AND    upper(value) != 'FALSE' )
            
UNION ALL

            SELECT 'PROBLEM'
            FROM   dual
            WHERE  EXISTS
                   (
                          SELECT upper(value)
                          FROM   v$system_parameter
                          WHERE  upper(name)='O7_DICTIONARY_ACCESSIBILITY'
                          AND    upper(value) != 'FALSE' ) 
    BEGIN OPEN c_07_check;
        
        LOOP
          FETCH c_07_check
          INTO  v_07_check;
          
          EXIT
        WHEN c_07_check%NOTFOUND;
          IF v_07_check = 'PROBLEM' THEN
            dbms_output.put_line('PROBLEM') )
        ELSIF v_07_check = 'NO_PROBLEM' THEN
          dbms_output.put_line('NO_PROBLEM')
        END IF;
        END LOOP;
        CLOSE C_07_CHECK;
        END;
        /

代码输出的错误信息是:

PLS-00103: Encountered the symbol "END" when expecting one of the following:

   := . ( % ;
The symbol ";" was substituted for "END" to continue.
ORA-06550: line 50, column 5:
PLS-00103: Encountered the symbol "CLOSE" 
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

它抱怨的线路是:

CLOSE c_07_check;

我已经检查了oracle 的文档,我不确定这里有什么问题。我尝试将 close 语句移动到块中的不同点,但它没有解决问题。谁能就失败的地方提出任何建议?

3 个地方缺少分号(游标声明末尾,dbms_output.put_line 调用后面),右括号多余。

DECLARE
   v_07_check  VARCHAR2 (10);

   CURSOR c_07_check IS
      SELECT 'NO_PROBLEM'
        FROM DUAL
       WHERE NOT EXISTS
                (SELECT UPPER (VALUE)
                   FROM v$system_parameter
                  WHERE     UPPER (name) = 'O7_DICTIONARY_ACCESSIBILITY'
                        AND UPPER (VALUE) != 'FALSE')
      UNION ALL
      SELECT 'PROBLEM'
        FROM DUAL
       WHERE EXISTS
                (SELECT UPPER (VALUE)
                   FROM v$system_parameter
                  WHERE     UPPER (name) = 'O7_DICTIONARY_ACCESSIBILITY'
                        AND UPPER (VALUE) != 'FALSE');
BEGIN
   OPEN c_07_check;

   LOOP
      FETCH c_07_check INTO v_07_check;

      EXIT WHEN c_07_check%NOTFOUND;

      IF v_07_check = 'PROBLEM'
      THEN
         DBMS_OUTPUT.put_line ('PROBLEM');
      ELSIF v_07_check = 'NO_PROBLEM'
      THEN
         DBMS_OUTPUT.put_line ('NO_PROBLEM');
      END IF;
   END LOOP;

   CLOSE C_07_CHECK;
END;
/

请注意,如果您使用游标 FOR 循环,您可以 缩短 简化 它,例如

BEGIN
   FOR cur_r
      IN (SELECT 'NO_PROBLEM' v_07_check
            FROM DUAL
           WHERE NOT EXISTS
                    (SELECT UPPER (VALUE)
                       FROM v$system_parameter
                      WHERE     UPPER (name) = 'O7_DICTIONARY_ACCESSIBILITY'
                            AND UPPER (VALUE) != 'FALSE')
          UNION ALL
          SELECT 'PROBLEM'
            FROM DUAL
           WHERE EXISTS
                    (SELECT UPPER (VALUE)
                       FROM v$system_parameter
                      WHERE     UPPER (name) = 'O7_DICTIONARY_ACCESSIBILITY'
                            AND UPPER (VALUE) != 'FALSE'))
   LOOP
      DBMS_OUTPUT.put_line (cur_r.v_07_check);
   END LOOP;
END;

因为 - 这样做 - 您不必声明游标变量、打开游标、从中获取数据、注意退出循环和关闭游标 - Oracle 会为您完成。