oracle pl/sql 关于程序执行方式的问题

Posted

技术标签:

【中文标题】oracle pl/sql 关于程序执行方式的问题【英文标题】:oracle pl/sql issue on procedure way of execution 【发布时间】:2017-04-17 19:48:48 【问题描述】:

我有一个场景,我有一个表 t1,它有两个表名,它们是 sanman。现在两个表sanman每个表都有多个表文件名,比如表san有两个文件名(audi.txtmercedes.txt),第二个表man有一个文件名(@987654330 @)。我编写了一个过程,它可以返回相应表中存在的行数以及相应的文件名。流程如下:

:sql 查询

-- for creating t1 table--

CREATE TABLE HR.T1
(
  NAMES       VARCHAR2(20 BYTE),
  MAPPING_ID  VARCHAR2(10 BYTE)
);

SET DEFINE OFF;
Insert into HR.T1
   (NAMES, MAPPING_ID)
 Values
   ('san', '1');
Insert into HR.T1
   (NAMES, MAPPING_ID)
 Values
   ('man', '1');
COMMIT;

-----------sql query for 'san' table----

CREATE TABLE HR.SAN
(
  SRC_FILENAME  VARCHAR2(20 BYTE)
);

SET DEFINE OFF;
Insert into HR.SAN
   (SRC_FILENAME)
 Values
   ('audi.txt');
Insert into HR.SAN
   (SRC_FILENAME)
 Values
   ('mercedes.txt');
COMMIT;

------sql query for man table ----

CREATE TABLE HR.MAN
(
  SRC_FILENAME  VARCHAR2(20 BYTE)
);

SET DEFINE OFF;
Insert into HR.MAN
   (SRC_FILENAME)
 Values
   ('hundai.txt');
COMMIT;

-------package spec -----

CREATE OR REPLACE PACKAGE HR.file_entry

AS

PROCEDURE PKG_PROC_FILES(L_MAPPING_ID NUMBER); 
procedure insert_proc (l_object_name VARCHAR2);
END;

-----package body -----


    CREATE OR REPLACE PACKAGE BODY HR.file_entry
AS

   PROCEDURE PKG_PROC_FILES (L_MAPPING_ID NUMBER)

AS
      V_TABLE_NAME    VARCHAR2 (50);
  V_SCHEMA_NAME   VARCHAR2 (50);

  TYPE CURTYPE IS REF CURSOR;

  V_SCHEMA_NAME   VARCHAR2 (50);


     ----
      CURSOR TARGET_OBJ_CUR
      IS
         SELECT DISTINCT names
           FROM t1
          WHERE MAPPING_ID = L_MAPPING_ID;
   BEGIN

    FOR I IN TARGET_OBJ_CUR
      LOOP
         INSERT_PROC (I.names);
         DBMS_OUTPUT.PUT_LINE ('TARGET_TABLE_NAME= ' || I.names);
      END LOOP;
   END;



PROCEDURE INSERT_PROC (L_OBJECT_NAME VARCHAR2)

   AS

      V_TABLE_NAME       VARCHAR2 (50);
      V_SCHEMA_NAME      VARCHAR2 (50);
      V_QUERY            VARCHAR2 (50);

      TYPE CURTYPE IS REF CURSOR;

      V_SRC_FILE_NAMES   VARCHAR2 (200);
      CUR                CURTYPE;

BEGIN

      V_QUERY := 'select distinct src_filename from ' || L_OBJECT_NAME;
      OPEN CUR FOR V_QUERY;

      LOOP
         FETCH CUR INTO V_SRC_FILE_NAMES;

         DBMS_OUTPUT.PUT_LINE ('SOURCE FILE NAMES 1 = ' || V_SRC_FILE_NAMES);
         COMMIT;

         EXIT WHEN CUR%NOTFOUND;
      END LOOP;

      CLOSE CUR;

   END;

END;
/

执行该过程后,我有多个来自 DB 的名称:

O/P
SOURCE FILE NAMES = mercedes.txt
SOURCE FILE NAMES = audi.txt
SOURCE FILE NAMES = audi.txt
TARGET_TABLE_NAME= san
SOURCE FILE NAMES = hundai.txt
SOURCE FILE NAMES = hundai.txt
TARGET_TABLE_NAME= man

在下面的 O/P 中,我只需要从表中获取不同的源文件名,但我无法理解为什么我会多次获得 audi.txthundai.txt。谁能帮我解决这个问题?我需要在输出中打印一次文件名,例如 mercedes.txt,它在输出中只打印一次。

【问题讨论】:

【参考方案1】:

EXIT WHEN CUR%NOTFOUND; 退出语句需要在INSERT_PROC 过程中的fetch 之后检查,而不是在end loop 之前。以及为什么在dbms_output.put_line 之后使用commit

【讨论】:

以上是关于oracle pl/sql 关于程序执行方式的问题的主要内容,如果未能解决你的问题,请参考以下文章

Oracle Pl sql 登录时提示 “监听程序当前无法识别连接描述符中请求的服务” 。

Oracle11G_PL/SQL

PL/SQL 下邮件发送程序

Oracle PL SQL专家指南 高级PL/SQL解决方安案的设计与开发

Oracle PL/SQL编程

oracle数据库之PL/SQL 块结构和组成元素