【问题标题】:Assistance needed for a first timer in package creation第一次创建包时需要帮助
【发布时间】:2012-08-12 09:44:42
【问题描述】:

这将是一个很难回答的问题,这就是为什么我在这个包(我的第一个包)上工作了 3 天来一直犹豫要问。

下面是我的包的规格和正文的布局。在你看之前,这是我想要完成的。我即将完成,所以不必担心这个问题不值得你花时间。

你也可以在代码中看到我的一些个人笔记。

我的代码不完整,目前没有编译,但在它停止编译之前,我可以告诉你它也没有工作。 DROP 和 CREATE 过程起作用。无需触摸这些。我的主要问题是 LOG_PROC、我的例外、我的 ARCHIVE_ALL_TABLES……据我所知

这是我想要做的:

创建一个包,可用于将新创建的表“归档”到“TEST_TABLE_A_13AUG2012”格式的归档表中。这个包将使用我创建的名为 VW_TEST_TABLES 的视图,其中包含以下数据:

TEST_TABLE_A
TEST_TABLE_B
TEST_TABLE_C
TEST_TABLE_D

此软件包需要先删除所有以前归档的表,然后再创建新表。因此,我的包中需要同时包含 DROP_ARCHIVE_TABLES 和 CREATE_ARCHIVE_TABLES 过程。除了 DROP 和 CREATE 过程之外,我的包还有一个主过程,称为 ARCHIVE_ALL_TABLES。这是需要调用(例如由调度程序)并执行实际归档的过程。我需要在这些过程中加入适当的异常处理。 (例如,当我删除它时,不要关心该表是否不存在)。

最后,为了正确跟踪每次归档运行,我想构建一个日志记录机制。为此,我在我的模式中构建了一个名为 TEST_PACKAGE_LOG_TBL 的表。此表应具有以下列:ARCHIVE_DATE (DATE)、TABLE_NAME (VARCHAR2(30))、STATUS_CODE(VARCHAR2(1))、COMMENTS (VARCHAR2(4000))。对于我归档的每个表,我想记录日期、表名,“S”表示成功或“E”表示错误,如果在删除或创建表时遇到错误,SQLERRM 应该是什么显示出来。

最后,我的 ARCHIVE_ALL_TABLES 过程应在完成时检查此日志表,以确定是否有任何表未正确归档。我创建了一个函数 ERRORS_FOUND(返回布尔值),它接受一个 IN 参数(今天的日期)并检查日志表是否有错误。如果此函数返回 true,我的 ARCHIVE_ALL_TABLES 过程应该考虑这一点并“通知管理员”(现在我将保持不变,但最终它会简单地用一条评论说明这​​一点,说明我将通知管理员并放置 NULL;在if then 结束块。)

总而言之,我的包结构必须包含(至少)以下过程:

ARCHIVE_ALL_TABLES, DROP_ARCHIVE_TABLE, CREATE_ARCHIVE_TABLE, ERRORS_FOUND(函数)

--package specification
CREATE OR REPLACE PACKAGE PKG_TEST_TABLES IS

          -- Author  : 
          -- Created : 8/14/2012 8:40:18 AM
          -- Purpose : For storing procedures to drop, create, and archive new tables

          /* Package specification*/
          PROCEDURE ARCHIVE_ALL_TABLES;
          PROCEDURE DROP_ARCHIVE_TABLES; --2nd
          PROCEDURE CREATE_ARCHIVE_TABLES; --1st and call both from archive tables first assuming it works
          PROCEDURE LOG_PROC
          (
                        P_PROCESS_START_TIMESTAMP TIMESTAMP
                       ,P_ARCHIVE_DATE DATE
                       ,P_TABLE_NAME VARCHAR2
                       ,P_STATUS_CODE VARCHAR2
                       ,P_COMMENTS VARCHAR2
          );
          PROCEDURE W(STR VARCHAR2);

          FUNCTION ERRORS_FOUND(P_JOB_RUN_TIMESTAMP TIMESTAMP) RETURN BOOLEAN;

END PKG_TEST_TABLES;


--package body
CREATE OR REPLACE PACKAGE BODY PKG_TEST_TABLES IS
          /* Package body*/

          -------------------------------------------------------------------------------------------------------------------------------------------------------------------
          -------------------------------------------------------------------------------------------------------------------------------------------------------------------

          /* Procedure 'W' is a wrapper for DBMS output. Placed at top of package to make globally available*/
          PROCEDURE W(STR VARCHAR2) IS
                        L_STRING VARCHAR2(4000);
          BEGIN

                        L_STRING := STR;
                        DBMS_OUTPUT.PUT_LINE(STR);
          END;

          -------------------------------------------------------------------------------------------------------------------------------------------------------------------
          -------------------------------------------------------------------------------------------------------------------------------------------------------------------

          PROCEDURE DROP_ARCHIVE_TABLES AS

                        /* Purpose: For dropping previously archived tables so that new ones can be created */

                        L_NO_TABLES_TO_DROP EXCEPTION;
              BEGIN
                        /* Will drop previously archived tables not current ones*/
                            FOR STMT IN (SELECT 'DROP TABLE mySchema.' || TABLE_NAME AS STR
                                     FROM VW_TEST_TABLES
                                     WHERE REGEXP_LIKE(TABLE_NAME, '.+[0...9]'))
                        LOOP
                                      EXECUTE IMMEDIATE STMT.STR; --so that I don't need ';' at the end of each dynamically created SQL

                        END LOOP;

                        W('Done'); --put the W back in here when in package scope

          EXCEPTION
                        WHEN L_NO_TABLES_TO_DROP THEN
                                      NULL;

          END;

          -------------------------------------------------------------------------------------------------------------------------------------------------------------------
          -------------------------------------------------------------------------------------------------------------------------------------------------------------------

          PROCEDURE CREATE_ARCHIVE_TABLES AS
          /* purpose: setting variable to equal the creation of my 4 tables. Recreating the archive tables */

          L_NO_TABLES_TO_CREATE EXCEPTION;
          L_TABLES_NOT_SUCCESSFULLY_CREATED EXCEPTION;

BEGIN

          FOR STMT IN (SELECT 'CREATE TABLE ' || TABLE_NAME || '_' || TO_CHAR(SYSDATE, 'ddMONyyyy') || ' AS SELECT * FROM ' || TABLE_NAME AS STR
                       FROM VW_TEST_TABLES)
          --LOG_PROC( ,TO_CHAR(SYSDATE, 'ddMONyyyy')  , TABLE_NAME  ,'E' ,'TABLE ARCHIVED SUCCESSFULLY')

          LOOP
                        --DBMS_OUTPUT.PUT_LINE(STMT.STR); --want to do a dbms output first before using 'execute immediate'. Hit test, and run it
                        EXECUTE IMMEDIATE STMT.STR; --so that I don't need ';' at the end of each dynamically created SQL

          END LOOP;

--  DBMS_OUTPUT.PUT_LINE('Done'); --put the W back in here when in package scope

EXCEPTION
              WHEN L_NO_TABLES_TO_CREATE THEN
                            NULL; --logging can go here
              --can call logging procedure here for dml don't need execute immediate, just use    insert into
              WHEN L_TABLES_NOT_SUCCESSFULLY_CREATED THEN
                            NULL; --W('ERROR: ' || SQLERRM);
END;

--PROCEDURE IS NOT CREATING TABLES YET

-------------------------------------------------------------------------------------------------    ------------------------------------------------------------------
-------------------------------------------------------------------------------------------------    ------------------------------------------------------------------
PROCEDURE LOG_PROC(P_PROCESS_START_TIMESTAMP TIMESTAMP, P_ARCHIVE_DATE DATE, P_TABLE_NAME     VARCHAR2, P_STATUS_CODE VARCHAR2, P_COMMENTS VARCHAR2) AS

PRAGMA AUTONOMOUS_TRANSACTION;

/* variables */

L_PROCESS_START_TIMESTAMP TIMESTAMP; L_ARCHIVE_DATE DATE; L_TABLE_NAME VARCHAR2(4000);     L_STATUS_CODE VARCHAR2(1); L_COMMENTS VARCHAR2(4000);

BEGIN

L_PROCESS_START_TIMESTAMP := P_PROCESS_START_TIMESTAMP; L_ARCHIVE_DATE := P_ARCHIVE_DATE;     L_TABLE_NAME := P_TABLE_NAME; L_STATUS_CODE := P_STATUS_CODE; L_COMMENTS := P_COMMENTS;

INSERT INTO TEST_PACKAGE_LOG_TBL(PROCESS_START_TIMESTAMP, ARCHIVE_DATE, TABLE_NAME, STATUS_CODE,     COMMENTS) VALUES(L_PROCESS_START_TIMESTAMP, L_ARCHIVE_DATE, L_TABLE_NAME, L_STATUS_CODE, L_COMMENTS);

RETURN;
END;

-------------------------------------------------------------------------------------------------    ------------------------------------------------------------------
-------------------------------------------------------------------------------------------------    ------------------------------------------------------------------

FUNCTION ERRORS_FOUND(P_JOB_RUN_TIMESTAMP TIMESTAMP) RETURN BOOLEAN IS
L_JOB_RUN_TIMESTAMP TIMESTAMP; ERROR_COUNT NUMBER; ERROR_BOOL BOOLEAN;
BEGIN
L_JOB_RUN_TIMESTAMP := P_JOB_RUN_TIMESTAMP;

SELECT COUNT(*) INTO ERROR_COUNT FROM TEST_PACKAGE_LOG_TBL WHERE STATUS_CODE = 'E' AND     PROCESS_START_TIMESTAMP = L_JOB_RUN_TIMESTAMP; IF ERROR_COUNT > 0 THEN ERROR_BOOL := TRUE; ELSE     ERROR_BOOL := FALSE;
END IF;

RETURN ERROR_BOOL;
END;
-------------------------------------------------------------------------------------------------    ------------------------------------------------------------------
-------------------------------------------------------------------------------------------------    ------------------------------------------------------------------

PROCEDURE ARCHIVE_ALL_TABLES AS

/*
                            Original Author: 
                            Created Date: 13-Aug-2012
                            Purpose: To drop all tables before recreating and archiving newly     created tables
                            NOTE: in package - do not use create or replace and 'as' would be     alternative to 'is'
                            */

/*variables*/
L_DROP_ARCHIVE_TABLES VARCHAR2(4000); L_SQL_CREATE_ARCHIVED_TABLES VARCHAR2(4000);     L_PREVENT_SQL_INJECTION
EXCEPTION
;
--L_NOTIFY_ADMINISTRATOR VARCHAR(4000); --TO BE DONE AT A LATER TIME

BEGIN

RETURN;

EXCEPTION

WHEN L_PREVENT_SQL_INJECTION THEN NULL;

WHEN OTHERS THEN W('ERROR: ' || SQLERRM);

END;

-------------------------------------------------------------------------------------------------    ------------------------------------------------------------------
-------------------------------------------------------------------------------------------------    ------------------------------------------------------------------

BEGIN
-- Initialization
/*archive all tables is like my 'driver' that calls drop then create while logging to the table.     Pragma_auto prevents a rollback which would prevent table logging
              FIRST: This package will need to drop all previously archived tables before it   creates new ones. call drop func first*/

/* calling  ARCHIVE_ALL_TABLES */
BEGIN
-- Call the function
NULL;

END;

RETURN;
END PKG_TEST_TABLES;

【问题讨论】:

    标签: database oracle plsql oracle11g packages


    【解决方案1】:
    1. 您的LOG_PROC 是一个自治事务,因此您需要一个COMMIT

    2. 您定义了许多异常,但您不会在代码中的任何地方引发它们。例如,我猜你需要这样的东西:

      PROCEDURE CREATE_ARCHIVE_TABLES AS
        L_NO_TABLES_TO_CREATE EXCEPTION;
        l_count number := 0;
      BEGIN
        FOR STMT IN (SELECT ...)
          LOOP
            l_count := l_count + 1;
            EXECUTE IMMEDIATE STMT.STR;
          END LOOP;
        IF l_count = 0 THEN
          RAISE L_NO_TABLES_TO_CREATE;
        END IF;
      EXCEPTION
            WHEN L_NO_TABLES_TO_CREATE THEN
                          NULL; --logging can go here
      END;
      

    【讨论】:

    • 非常感谢您的提示
    • 我会听取您的建议并尝试一下
    猜你喜欢
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 1970-01-01
    • 2011-08-02
    • 2013-12-08
    相关资源
    最近更新 更多