Pregunta

I have a procedure like below, but when I tried to running it using sqlplus its gave me error

BEGIN IB_ARCHIVE_FDS('FDS_LOG', 'TIME_REQUEST', 5, 6); END;

ERROR at line 1: ORA-01722: invalid number ORA-06512: at "NIAGA.IB_ARCHIVE_FDS", line 10 ORA-06512: at line 1

and I'm using Oracle 9i

CREATE OR replace PROCEDURE Ib_archive_fds(table_name     VARCHAR2,
                                           column_name    VARCHAR2,
                                           success_period NUMBER,
                                           active_period  NUMBER)
IS
  TYPE fds_tabs
    IS TABLE OF ib_fds_log%ROWTYPE INDEX BY PLS_INTEGER;
  TYPE fds_message_id
    IS TABLE OF ib_fds_log.message_id%TYPE INDEX BY PLS_INTEGER;
  v_fds_log    FDS_TABS;
  v_message_id FDS_MESSAGE_ID;
BEGIN
    SELECT *
    bulk   collect INTO v_fds_log
    FROM   ib_fds_log2
    WHERE  direction = 0
           AND status_fds_message = 0
           AND time_request < Trunc(SYSDATE - ' || SUCCESS_PERIOD || ' - 1);

    FOR i IN 1 .. v_fds_log.last LOOP
        V_message_id(i) := V_fds_log(i).message_id;
    END LOOP;

    forall indx IN 1 .. v_fds_log.count
      INSERT INTO ib_fds_log3
      VALUES V_fds_log(indx);

    COMMIT;

    forall indx IN 1 .. v_fds_log.count
      DELETE FROM ib_fds_log2
      WHERE  message_id = V_message_id(indx);

    COMMIT;
END; 

can somebody help me to solve my problem here.

¿Fue útil?

Solución

While I agree with David's analysis of the shortcomings of your implementation the actual cause of that error message is this bug:

time_request < trunc(sysdate - ' || SUCCESS_PERIOD || '- 1);

SUCCESS_PERIOD is a parameter and you presumably want to use it in your date calculation. However you have coded it as a string; a string is not a number and so we cannot use in in a substraction.

I'm not quite sure what arithmetic you're trying to achieve, but I think you want either this ...

time_request < trunc(sysdate - ( SUCCESS_PERIOD - 1));

... or this ...

time_request < trunc(sysdate - ( SUCCESS_PERIOD + 1) );

... depending on how you want to modify the value of SUCCESS_PERIOD.

Otros consejos

This code should almost certainly avoid the cursors completely and just use SQL statements -- something along the lines of ...

procedure ib_archive_fds(
  table_name     varchar2,
  column_name    varchar2,
  success_period number  ,
  active_period  number  )
is
  time_request_limit date;
begin
  time_request_limit := trunc(sysdate - success_period - 1)

  insert into
    ib_fds_log3
  select
    *
  from
    ib_fds_log2
  where
    direction          = 0 and
    status_fds_message = 0 and
    time_request       < ib_archive_fds.time_request_limit;

  delete from
    ib_fds_log2
  where
    direction          = 0 and
    status_fds_message = 0 and
    time_request       < ib_archive_fds.time_request_limit;
end;

Various enhancements would be possible if the result set of the query is not constant when this is executed, but all of the PL/SQL is just asking for errors and performance problems.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top