Oracle包错误

时间:2017-04-26 11:43:21

标签: oracle plsql package

我有一个包将删除某些表中的数据。我创建了一个包,它具有在另一个表中审计的功能和具有初始化逻辑的过程。我停止了奇怪的Ora错误。也许你知道这里有什么不妥。

这是规范:

CREATE OR REPLACE PACKAGE CLIENT_DELETE_PACKAGE
IS
  deletion_results VARCHAR2(200);
  deletedEntries     NUMBER;
  min_date           DATE;
  max_date           DATE;
  -- Enable/disable logging
  Enable_Audit_Trail BOOLEAN := True;
  -- Enable Safe Mode
  Enable_Safe_Mode BOOLEAN := True;
  PROCEDURE AUDIT_TRAIL(
      MyTYPE       IN VARCHAR2,
      MyDATA       IN VARCHAR2,
      MyDatasource IN VARCHAR2,
      MyResultData IN VARCHAR2);
  -- ECHO Check that the package is available.
  FUNCTION ECHO(
      MyDATA IN VARCHAR2)
    RETURN VARCHAR2;
  -- JOB_REQUEST
  FUNCTION DEL_WLM_ALERT(
      MyAlertKey IN NUMBER)
    RETURN VARCHAR2;
  PROCEDURE INIT;
END CLIENT_DELETE_PACKAGE;
/

身体:

CREATE OR REPLACE PACKAGE BODY CLIENT_DELETE_PACKAGE
AS
  -- Auditing
  PROCEDURE AUDIT_TRAIL(
      MyTYPE       IN VARCHAR2,
      MyDatasource IN VARCHAR2,
      MyResultData IN VARCHAR2)
  AS
    --allow to keep the entry even if a roll-back occurs in the other procedure.
    pragma autonomous_transaction;
  BEGIN
    /*ID: provided by sequence
    EVENT_TIME: default value SysDate
    TYPE: DELETED/LOCKED ITEM
    DATASOURCE_NAME: datasource name
    RESULT_DATA: data link to type
    */
    IF (Enable_Audit_Trail) THEN
      INSERT INTO CLIENT_DELETION_AUDIT
        ( id, TYPE, DATASOURCE_NAME, RESULT_DATA
        )
      SELECT SEQ_AUDIT_TRAIL.NEXTVAL, MyTYPE, MyDatasource, MyResultData FROM dual;
      COMMIT;
    END IF;
  END AUDIT_TRAIL;
-- -------------------------------------------------------------------------
-- Echoing function
-- -------------------------------------------------------------------------
  FUNCTION ECHO(
      MyDatasource IN VARCHAR2)
    RETURN VARCHAR2
  AS
  BEGIN
    /*check if the package is available */
    RETURN 'i am here';
  END ECHO;
-- -------------------------------------------------------------------------
-- Delete WLM Alert Data
-- -------------------------------------------------------------------------
  FUNCTION DEL_WLM_ALERT(
      MyAlertKey IN NUMBER)
    RETURN VARCHAR2
  AS
    countLookUp       NUMBER;
    countTotalEntries NUMBER;
    deletedEntries    NUMBER;
    dataSourceToCheck VARCHAR2(200);
    numberOfAlertLeft NUMBER;
    alert_trx_id      NUMBER;
    trx_group_id      NUMBER;
    large_str_id      NUMBER;
  BEGIN
    countTotalEntries:=0;
    deletedEntries   :=0;
    ---Get transaction ID for usage later---
    SELECT TRANSACTION_ID
    INTO alert_trx_id
    FROM WLM_RULE_ALERT WRA
    JOIN WLM_ALERT_HEADER WAH
    ON WAH.ALERT_IDENTIFIER = WRA.ALERT_IDENTIFIER
    WHERE wah.alert_key     = MyAlertKey
    AND rownum              =1;
    ---Get transaction GRoup ID for usage later---
    SELECT TRANSACTION_GROUP_ID
    INTO trx_group_id
    FROM ALERTING_TRANSACTION AT
    JOIN WLM_RULE_ALERT WRA
    ON WRA.TRANSACTION_ID = AT.ID
    JOIN WLM_ALERT_HEADER WAH
    ON WAH.ALERT_IDENTIFIER = WRA.ALERT_IDENTIFIER
    WHERE wah.alert_key     = MyAlertKey
    AND rownum              =1;
    ---Get LargeString ID for usage later---
    SELECT MIN(tg.largestring_id)
    INTO large_str_id
    FROM transaction_group tg
    WHERE tg.ID = trx_group_id
    AND rownum  =1;
    -- deleted from ALERT_MATCH_DATA --
    DELETE
    FROM ALERT_MATCH_DATA AMD
    WHERE ALERT_MATCH_ID IN
      (SELECT AM.ID
      FROM ALERT_MATCH AM
      JOIN WLM_RULE_ALERT WRA
      ON WRA.id = AM.WLM_RULE_ALERT_ID
      JOIN WLM_ALERT_HEADER WAH
      ON WAH.ALERT_IDENTIFIER = WRA.ALERT_IDENTIFIER
      WHERE wah.alert_key     = MyAlertKey
      );
    -- deleted from ALERT_MATCH --
    DELETE
    FROM ALERT_MATCH AM
    WHERE AM.WLM_RULE_ALERT_ID IN
      (SELECT WRA.id
      FROM WLM_RULE_ALERT WRA
      JOIN WLM_ALERT_HEADER WAH
      ON WAH.ALERT_IDENTIFIER = WRA.ALERT_IDENTIFIER
      WHERE wah.alert_key     = MyAlertKey
      );
    deletedEntries      :=deletedEntries+SQL%ROWCOUNT;
    IF(numberOfAlertLeft =0) THEN
      -- deleted from DATA_SOURCE_CUSTOMER --
      DELETE
      FROM DATA_SOURCE_CUSTOMER DSC
      WHERE ID       = alert_trx_id;
      deletedEntries:=deletedEntries+SQL%ROWCOUNT;
      -- deleted from DATA_SOURCE_SWIFT --
      DELETE
      FROM DATA_SOURCE_SWIFT DSC
      WHERE ID       = alert_trx_id;
      deletedEntries:=deletedEntries+SQL%ROWCOUNT;
      -- deleted from ALERTING_TRANSACTION --
      DELETE
      FROM ALERTING_TRANSACTION AT
      WHERE AT.ID                = alert_trx_id
      OR AT.TRANSACTION_GROUP_ID = trx_group_id;
      deletedEntries            :=deletedEntries+SQL%ROWCOUNT;
      IF( countLookUp            = 1 ) THEN
        -- deleted from TRANSACTION_GROUP --
        DELETE
        FROM TRANSACTION_GROUP AT
        WHERE AT.ID    = trx_group_id;
        deletedEntries:=deletedEntries+SQL%ROWCOUNT;
        -- deleted from LARGESTRING_PART --
        DELETE
        FROM LARGESTRING_PART
        WHERE LARGESTRING_ID                IN large_str_id;
        deletedEntries       :=deletedEntries+SQL%ROWCOUNT;
        -- deleted from LARGESTRING --
        DELETE
        FROM LARGESTRING
        WHERE id       = large_str_id;
        deletedEntries:=deletedEntries+SQL%ROWCOUNT;
      END IF;
    END IF;
    countTotalEntries:=countTotalEntries+countLookUp;
    -- deleted from WLM_RULE_ALERT --
    DELETE
    FROM WLM_RULE_ALERT WRA
    WHERE WRA.ALERT_IDENTIFIER IN
      (SELECT WAH.ALERT_IDENTIFIER
      FROM WLM_ALERT_HEADER WAH
      WHERE wah.alert_key= MyAlertKey
      );
    deletedEntries:=deletedEntries+SQL%ROWCOUNT;
    -- deleted from WLM_CUSTOMER_MATCH_DETAILS --
    DELETE
    FROM WLM_CUSTOMER_MATCH_DETAILS
    WHERE ALERT_KEY= MyAlertKey;
    deletedEntries:=deletedEntries+SQL%ROWCOUNT;
    -- deleted from WORKFLOW_ACTION_LOG --
    DELETE
    FROM WORKFLOW_ACTION_LOG
    WHERE WORKFLOW_WORKITEM_ID IN
      (SELECT id
      FROM WORKFLOW_WORKITEM
      WHERE ENTITY_KEY=TO_CHAR(MyAlertKey)
      AND ENTITY_NAME ='WLM Alert'
      );
    deletedEntries:=deletedEntries+SQL%ROWCOUNT;
    -- deleted from WORKFLOW_WORKITEM_LINK --
    DELETE
    FROM WORKFLOW_WORKITEM_LINK
    WHERE ENTITY_KEY=MyAlertKey
    AND ENTITY_NAME ='WLM Alert';
    deletedEntries :=deletedEntries+SQL%ROWCOUNT;
    -- deleted from WORKFLOW_WORKITEM --
    DELETE
    FROM WORKFLOW_WORKITEM
    WHERE ENTITY_KEY= TO_CHAR(MyAlertKey)
    AND entity_name ='WLM Alert';
    deletedEntries :=deletedEntries+SQL%ROWCOUNT;
    -- deleted from WLM_ALERT_HEADER --
    DELETE
    FROM WLM_ALERT_HEADER
    WHERE alert_key = MyAlertKey;
    deletedEntries :=deletedEntries+SQL%ROWCOUNT;
  END DEL_WLM_ALERT;
-- initialization procedure
  PROCEDURE INIT
  AS
    CURSOR alert_id
    IS
    WITH alerts AS
      (SELECT wah.ALERT_KEY                                                     AS alert_key,
        ds.NAME                                                                 AS datasource_name,
        NVL(el.ENTITY_ID,0)                                                     AS alert_key_locked,
        MIN(EVENT_DATE) OVER (PARTITION BY DATASOURCE_NAME order by EVENT_DATE) AS min_date,
        MAX(EVENT_DATE) OVER (PARTITION BY DATASOURCE_NAME order by EVENT_DATE) AS max_date
      FROM WLM_ALERT_HEADER wah
      LEFT JOIN WORKFLOW_WORKITEM ww
      ON wah.ALERT_KEY=ww.ENTITY_KEY
      LEFT JOIN DATA_SOURCE ds
      ON wah.AT_DATASOURCE_ID=ds.ID
      LEFT JOIN CLIENT_DELETION_SETTINGS rds
      ON ds.NAME =rds.DATASOURCE_NAME
      LEFT JOIN ENTITY_LOCKS el
      ON el.ENTITY_ID  =wah.ALERT_KEY
      WHERE EVENT_DATE < (sysdate - rds.PERIOD)
    UNION ALL
    SELECT wah.ALERT_KEY                                                      AS alert_key,
      ds.NAME                                                                 AS datasource_name,
      NVL(el.ENTITY_ID,0)                                                     AS alert_key_locked,
      MIN(EVENT_DATE) OVER (PARTITION BY DATASOURCE_NAME order by EVENT_DATE) AS min_date,
      MAX(EVENT_DATE) OVER (PARTITION BY DATASOURCE_NAME order by EVENT_DATE) AS max_date
    FROM WLM_ALERT_HEADER wah
    LEFT JOIN WORKFLOW_WORKITEM ww
    ON wah.ALERT_KEY=ww.ENTITY_KEY
    LEFT JOIN
      (SELECT ID, NAME
      FROM DATA_SOURCE
      WHERE NAME NOT IN
        (SELECT DATASOURCE_NAME FROM CLIENT_DELETION_SETTINGS
        )
      ) ds
    ON wah.AT_DATASOURCE_ID=ds.ID
    LEFT JOIN CLIENT_DELETION_SETTINGS rds
    ON ds.NAME =rds.DATASOURCE_NAME
    LEFT JOIN ENTITY_LOCKS el
    ON el.ENTITY_ID  = wah.ALERT_KEY
    WHERE EVENT_DATE < (sysdate -
      (SELECT period FROM CLIENT_deletion_settings WHERE datasource_name='DEFAULT'
      ))
      )
    SELECT *
    FROM CLIENT_DELETION_SETTINGS rbs
    LEFT JOIN alerts al
    ON al.datasource_name=rbs.datasource_name;

  BEGIN
    FOR x IN alert_id
    LOOP
      IF (x.alert_key_locked > 0) THEN
        AUDIT_TRAIL('LOCKED', x.datasource_name, x.alert_key);
        COMMIT;
      ELSE
        -- execute deletion for each alert_id
        deletion_results:=DEL_WLM_ALERT(x.alert_key);
        COMMIT;
      END IF;
      AUDIT_TRAIL('DELETED', x.datasource_name, deletedEntries || ' | ' || MIN(min_date) || ' -- ' || MAX(max_date));
    END LOOP;
END INIT;
END CLIENT_DELETE_PACKAGE;
/

这些是错误:

Error(11,13): PLS-00323: subprogram or cursor 'AUDIT_TRAIL' is declared in a package specification and must be defined in the package body
Error(17,12): PLS-00323: subprogram or cursor 'ECHO' is declared in a package specification and must be defined in the package body
Error(234,9): PL/SQL: Statement ignored
Error(234,33): PLS-00302: component 'DATASOURCE_NAME' must be declared
Error(241,7): PL/SQL: Statement ignoredError(241,32): PLS-00302: component 'DATASOURCE_NAME' must be declared
Error(241,32): PLS-00302: component 'DATASOURCE_NAME' must be declared

2 个答案:

答案 0 :(得分:1)

您已在两个地方声明了过程和函数,但参数不同,因此PL / SQL编译器将它们视为不同的东西。您在规范中声明了一个过程和函数但从未定义过;以及身体私密的程序和功能 - 它们是完全独立的。

您需要更改规范以匹配:

CREATE OR REPLACE PACKAGE CLIENT_DELETE_PACKAGE
IS
  ...
  PROCEDURE AUDIT_TRAIL(
      MyTYPE       IN VARCHAR2,
      -- MyDATA       IN VARCHAR2, -- this isn't in the body version
      MyDatasource IN VARCHAR2,
      MyResultData IN VARCHAR2);
  -- ECHO Check that the package is available.
  FUNCTION ECHO(
      -- MyDATA IN VARCHAR2) -- wrong name
      MyDatasource IN VARCHAR2)
    RETURN VARCHAR2;
  ...

PLS-00302是因为游标查询中有重复的列名。您可以通过简化示例查看内容。如果您运行如下查询:

column dummy format a6

select *
from dual
cross join dual;

DUMMY  DUMMY 
------ ------
X      X     

客户端可以在结果集中显示具有相同标头的两列。例如,如果您尝试基于该查询创建视图,则会获得&#34; ORA-00957:重复列名称&#34;错误,因为视图DDL中的列名必须相同。

这里发生了类似的事情,但是光标隐含地为两列提供了唯一的列别名。正如连接条件ON al.datasource_name=rbs.datasource_name所示,同一列名称同时出现在您加入的表和CTE中,因此select *将获得两次相同的列名。由于两者都是隐式的别名,所以在游标记录类型中没有实际调用datasource_name的列。

您应该将光标查询更改为不使用毯子select *;从表和CTE列出您实际需要的列。无论如何,这通常是可取的。

答案 1 :(得分:0)

您的AUDIT_TRAIL规范未遵循其正文声明。两个“标题”必须相同 - 相同的参数。包括arg名称。

ECHO也一样。

关于DATASOURCE_NAME - 它真的是表CLIENT_DELETION_AUDIT中的一列吗?不是不见了吗?