Процедура резервного копирования с использованием API Datapump - PullRequest
1 голос
/ 27 февраля 2020

Привет, я пытаюсь создать Oracle процедуру, которая берет резервную копию из пользовательской схемы (POSData) и помещает ее в каталог с именем «Резервные копии», читает грант POSData, записывает в каталог «Резервные копии», используя этот код от системного пользователя.

DECLARE
h2 NUMBER;
BEGIN
    h2 := DBMS_DATAPUMP.OPEN('EXPORT', 'SCHEMA');
    DBMS_DATAPUMP.ADD_FILE(h2,'POSData.dmp','Backups');
    DBMS_DATAPUMP.METADATA_FILTER(h2,'SCHEMA_EXP','IN (''POSData'')');
    DBMS_DATAPUMP.START_JOB(h2);
    dbms_datapump.detach(h2);
END;

но я всегда получаю эту ошибку

Error starting at line : 1 in command -
DECLARE
h2 NUMBER;
BEGIN
h2 := DBMS_DATAPUMP.OPEN('EXPORT', 'SCHEMA');
DBMS_DATAPUMP.ADD_FILE(h2,'POSData.dmp','Backups');
DBMS_DATAPUMP.METADATA_FILTER(h2,'SCHEMA_EXP','IN (''POSData'')');
DBMS_DATAPUMP.START_JOB(h2);
dbms_datapump.detach(h2);
END;
Error report -
ORA-39001: invalid argument value
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 79
ORA-06512: at "SYS.DBMS_DATAPUMP", line 3507
ORA-06512: at "SYS.DBMS_DATAPUMP", line 3756
ORA-06512: at line 5
39001. 00000 - "invalid argument value"
*Cause: The user specified API parameters were of the wrong type or
value range. Subsequent messages supplied by
DBMS_DATAPUMP.GET_STATUS will further describe the error.
*Action: Correct the bad argument and retry the API.

помогите пожалуйста?

Ответы [ 2 ]

0 голосов
/ 06 марта 2020

Я нашел решение для моей проблемы и вот код

                   DECLARE
                         h1 number;
                       errorvarchar varchar2(100):= 'ERROR';
                       tryGetStatus number := 0;
                   begin
                       h1 := dbms_datapump.open (operation => 'EXPORT', job_mode => 'SCHEMA', job_name => 'EXPORT_JOB_SQLDEV_2344', version => 'COMPATIBLE');
                       tryGetStatus := 1;
                       dbms_datapump.set_parallel(handle => h1, degree => 1);
                       dbms_datapump.add_file(handle => h1, filename => 'EXPDAT.LOG', directory => 'BACKUPS', filetype => 3);
                       dbms_datapump.set_parameter(handle => h1, name => 'KEEP_MASTER', value => 0);
                       dbms_datapump.metadata_filter(handle => h1, name => 'SCHEMA_EXPR', value => 'IN(''POSDATA'')');
                       dbms_datapump.add_file(handle => h1, filename => 'POSData.DMP', directory => 'BACKUPS', filesize => '100M',  filetype => 1, reusefile => 1);
                       dbms_datapump.set_parameter(handle => h1, name => 'INCLUDE_METADATA', value => 1);
                       dbms_datapump.set_parameter(handle => h1, name => 'DATA_ACCESS_METHOD', value => 'AUTOMATIC');
                       dbms_datapump.set_parameter(handle => h1, name => 'ESTIMATE', value => 'BLOCKS');
                       dbms_datapump.start_job(handle => h1, skip_current => 0, abort_step => 0);
                       dbms_datapump.detach(handle => h1);
                       errorvarchar := 'NO_ERROR';
                   EXCEPTION
                       WHEN OTHERS THEN
                       BEGIN
                           IF ((errorvarchar = 'ERROR')AND(tryGetStatus=1)) THEN
                               DBMS_DATAPUMP.DETACH(h1);
                           END IF;
                       EXCEPTION
                       WHEN OTHERS THEN
                           NULL;
                       END;
                       RAISE;
                   END;
0 голосов
/ 03 марта 2020

DBMS_DATAPUMP имеет несколько действительно хороших сообщений об ошибках, но вам нужно покопаться, чтобы их получить. В приведенном ниже примере я добавил вложенную процедуру output_expdp_error для вывода подробного сообщения. Конечно, вы должны изменить это, чтобы сделать соответствующую регистрацию для вашей среды:

 DECLARE
     h1            NUMBER;
     l_filename    VARCHAR2( 100 ) := 'deleteme.dmp';
     l_directory   VARCHAR2( 100 ) := 'CIFS_DIR';

     PROCEDURE output_expdpd_error( p_handle IN NUMBER ) AS
         -- *******************************************************************
         --  Output EXPDP Error
         --  Purpose:
         --    Send detailed EXPDP error to DBMS_OUTPUT
         --  Modified:
         --    2020.03.02 - BFL Created
         --  Notes:
         --    Borrowed from: https://docs.oracle.com/database/121/SUTIL/GUID-5AAC848B-5A2B-4FD1-97ED-D3A048263118.htm#SUTIL977
         -- *******************************************************************

         l_status              ku$_status;                                           --ku$_jobstatus;
         l_logentry            ku$_logentry;
         l_job_state           VARCHAR2( 30 );
         l_ind                 NUMBER;
         l_pos                 NUMBER;
         l_length              NUMBER;
         l_linesize   CONSTANT NUMBER := 1000;
         l_message             VARCHAR2( 1000 );
     BEGIN
         -- Original had "if sqlcode = dbms_datapump.success_with_info_num" but this
         -- hides some errors. Just always process the handle.
         DBMS_OUTPUT.put_line( 'Data Pump job started with info available:' );
         DBMS_DATAPUMP.get_status( p_handle
                                 , DBMS_DATAPUMP.ku$_status_job_error
                                 , 0
                                 , l_job_state
                                 , l_status );

         IF (BITAND( l_status.mask, DBMS_DATAPUMP.ku$_status_job_error ) != 0)
         THEN
             l_logentry   := l_status.error;

             IF l_logentry IS NOT NULL
             THEN
                 l_ind   := l_logentry.FIRST;

                 WHILE l_ind IS NOT NULL
                 LOOP
                     l_pos      := 1;
                     l_length   := LENGTH( l_logentry( l_ind ).logtext );
                     l_length   := CASE WHEN l_linesize < l_length THEN l_linesize ELSE l_length END;

                     WHILE l_length > 0
                     LOOP
                         l_message   :=
                             SUBSTR( l_logentry( l_ind ).logtext
                                   , l_pos
                                   , l_length );
                         DBMS_OUTPUT.put_line( l_message );
                         l_pos      := l_pos + l_linesize;
                         l_length   := LENGTH( l_logentry( l_ind ).logtext ) + 1 - l_pos;
                     END LOOP;

                     l_ind      := l_logentry.NEXT( l_ind );
                 END LOOP;
             END IF;
         END IF;
     END;
 BEGIN
     DBMS_OUTPUT.put_line( 'open' );
     h1   := DBMS_DATAPUMP.open( 'EXPORT', 'SCHEMA' );
     DBMS_OUTPUT.put_line( 'add_file' );
     DBMS_DATAPUMP.add_file( handle      => h1
                           , filename    => l_filename
                           , directory   => l_directory
                           , filetype    => DBMS_DATAPUMP.ku$_file_type_dump_file
                           , reusefile   => 1 );
     DBMS_OUTPUT.put_line( 'hr filter' );
     DBMS_DATAPUMP.metadata_filter( h1
                                  , 'SCHEMA_EXPR'
                                  , 'IN (''BOGUS'')' );
     DBMS_OUTPUT.put_line( 'BOGUS filter' );
     DBMS_DATAPUMP.metadata_filter( h1
                                  , 'SCHEMA_EXPR'
                                  , 'IN (''BOGUS'')' );
     DBMS_OUTPUT.put_line( 'start_job' );
     DBMS_DATAPUMP.start_job( h1 );
     DBMS_DATAPUMP.detach( h1 );
 EXCEPTION
     WHEN OTHERS
     THEN
         DECLARE
             l_message   VARCHAR2( 1000 );
         BEGIN
             output_expdpd_error( p_handle => h1 );
             DBMS_DATAPUMP.detach( h1 );
             l_message   :=
                 SUBSTR(
                        SQLERRM
                     || UTL_TCP.crlf
                     || DBMS_UTILITY.format_error_backtrace
                     || UTL_TCP.crlf
                     || UTL_TCP.crlf
                   , 1
                   , 1000 );
             DBMS_OUTPUT.put_line( l_message );
             raise_application_error( -20000, l_message );
         END;
 END;

Когда я запустил это с несуществующей схемой, я получил чудесно указанное c сообщение об ошибке:

ORA-39001: invalid argument value
ORA-39170: Schema expression IN ('BOGUS') does not correspond to any schemas.
ORA-39001: invalid argument value
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 79
ORA-06512: at "SYS.DBMS_DATAPUMP", line 3507
ORA-06512: at "SYS.DBMS_DATAPUMP", line 4825
ORA-06512: at line 76
...