【问题标题】:SQL Procedure error exact fetch returns more than requested number of rowsSQL 过程错误精确提取返回超过请求的行数
【发布时间】:2014-02-11 23:45:08
【问题描述】:

我有下面的 SQL 过程,当从 SQL DEveloper 运行时显示下面的错误

ERROR Message: 
    ORA-01422: exact fetch returns more than requested number of rows



PROCEDURE SP_ENABLE_CONST(P_ARCH_BATCH_ID VARCHAR) IS


TABLELIST VARCHAR2(100);
SQL_QUERY VARCHAR2(4000);
RESULT_COL INT;
RESULT_CONST_COL VARCHAR2(1000);


BEGIN
/*LOOP will return three tables designated in table_name */
FOR TEMP2_VAR_TEST IN (SELECT TABLE_NAME FROM SYS.ALL_TABLES WHERE TABLE_NAME LIKE 'TEST%')
 
/*each loop the table_name returned will be used in SQL_QUERY */
  LOOP

      SQL_QUERY := 'SELECT CONSTRAINT_NAME FROM USER_CONS_COLUMNS WHERE TABLE_NAME = :1';
     
      DBMS_OUTPUT.PUT_LINE(SQL_QUERY); 

/*select statement will return more than one row containing table constraints*/
**ERROR on this part since RESULT_CONST_COL cannot contain more than one row
      EXECUTE IMMEDIATE SQL_QUERY INTO RESULT_CONST_COL USING TEMP2_VAR_TEST.TABLE_NAME;
      
      DBMS_OUTPUT.PUT_LINE('CONSTRAINT_NAME' || RESULT_CONST_COL);
          
  END LOOP;     
  END SP_ENABLE_CONST;
END PK_ARCHIVE_PROCESS_TEST;

我了解该错误是由 VARCHAR2 类型的 result_const_col 引起的,但我不确定使用什么来存储从执行立即命令返回的多行。我已阅读有关光标并尝试使用它但仍然出现错误。提前致谢。

更新 1

按照您的建议修改了我的代码,但仍然遇到错误。

TYPE RESULT_CONST_COL IS TABLE OF VARCHAR2(1000);
VAR_OF_RESULT_CONST RESULT_CONST_COL;

TBL_CONSTRAINTS VARCHAR2(100);
TABLELIST VARCHAR2(100);
SQL_QUERY VARCHAR2(4000);
RESULT_COL INT;


BEGIN

FOR TEMP2_VAR_TEST IN (SELECT TABLE_NAME FROM SYS.ALL_TABLES WHERE TABLE_NAME LIKE 'TEST%')
 
  LOOP      
      SQL_QUERY := 'SELECT CONSTRAINT_NAME FROM USER_CONS_COLUMNS WHERE TABLE_NAME = :1';          
      DBMS_OUTPUT.PUT_LINE(SQL_QUERY); 

/*ERROR line 92*/
        EXECUTE IMMEDIATE SQL_QUERY USING TEMP2_VAR_TEST.TABLE_NAME
          RETURNING BULK COLLECT INTO VAR_OF_RESULT_CONST;      
  
        FOR I IN 1 .. VAR_OF_RESULT_CONST.COUNT LOOP
          DBMS_OUTPUT.PUT_LINE(VAR_OF_RESULT_CONST(i));
        END LOOP;       
  END LOOP;

当我尝试运行上面的代码时遇到了这个错误

ORA-06547: RETURNING clause must be used with INSERT, UPDATE, or DELETE statements
**ORA-06512: at "HSNIAPP.PK_ARCHIVE_PROCESS_TEST", line 92**
ORA-06512: at line 6
SELECT CONSTRAINT_NAME FROM USER_CONS_COLUMNS WHERE TABLE_NAME = :1

【问题讨论】:

    标签: sql stored-procedures oracle-sqldeveloper


    【解决方案1】:

    您必须将RESULT_CONST_COL 声明为集合:

    RESULT_CONST_COL IS TABLE OF VARCHAR2(1000);
    

    然后使用BULK COLLECT INTO返回多行:

    EXECUTE IMMEDIATE SQL_QUERY BULK COLLECT INTO RESULT_CONST_COL
     USING TEMP2_VAR_TEST.TABLE_NAME;
    

    然后遍历集合中返回的结果来处理所有的值:

    FOR i IN 1 .. RESULT_CONST_COL.COUNT LOOP
     DBMS_OUTPUT.PUT_LINE(RESULT_CONST_COL(i));
     EXECUTE IMMEDIATE 'ALTER TABLE '|| TEMP2_VAR_TEST ||
      ' DISABLE CONSTRAINT ' || RESULT_CONST_COL(i);
    END LOOP;
    

    【讨论】:

    • 嗨 yaroslav 感谢您的帮助...当我尝试遵循您的建议时遇到错误。表达式 RESULT_CONST_COL 不适合作为赋值语句的左侧......必须声明另一个错误组件 COUNT。我现在正在尝试解决这个问题。
    • @dimas 要将值分配给集合元素,您必须使用索引:RESULT_CONST_COL(1) := 'some_value'。可以有任何数字代替 1,它小于或等于集合中元素的总数。关于COUNT,您能否发布引发此错误的代码行?
    • 嗨 yaroslav 我已经设法摆脱了关于 result_const_col 的错误显示,但它又出现了另一个错误。请参阅更新 1
    • @dimas 抱歉代码中的错误。您只需使用BULK COLLECT INTO。如果您动态执行INSERTUPDATEDELETE 语句,则确实需要RETURNING。我已经相应地更新了我的答案。
    • 这很好 yaroslav,你做的修复很棒。程序现在正在运行。只是一个后续问题,因为结果会给我每张表的外键行。我可以使用 RESULT_CONST_COL 遍历每一行并使用 ALTER 语句禁用外键吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 2017-07-25
    相关资源
    最近更新 更多