2017-09-27 13 views
1

사용 사례 : 고객의 DB 백업본을 dmp 파일로 보냅니다. 그것이 그들이 보낼 모든 것입니다.원본 테이블 공간을 모른 채 Oracle DMP 파일을 가져 오는 방법은 무엇입니까?

DBMS_DATAPUMP를 사용하여 해당 dmp 파일을 Oracle로 가져 오는 스크립트를 작성하고 있습니다. ORA-39083 : 객체 유형 USER : "XXXXX"오류를 생성하는 데 실패했습니다 : ORA-00959 : 테이블 공간 'XXXXXXX'가 존재하지 않습니다.

이 내 PL/SQL의 절차 :

PROCEDURE IMPORTING 
(
    DMPFILES IN VARCHAR2, 
    FROMSCHEMA IN VARCHAR2, 
    TOSCHEMA IN VARCHAR2 
) AS 
    ind NUMBER;    -- Loop index 
    h1 NUMBER;    -- Data Pump job handle 
    percent_done NUMBER;  -- Percentage of job complete 
    job_state VARCHAR2(30); -- To keep track of job state 
    le ku$_LogEntry;   -- For WIP and error messages 
    js ku$_JobStatus;  -- The job status from get_status 
    jd ku$_JobDesc;   -- The job description from get_status 
    sts ku$_Status;   -- The status object returned by get_status 
    array apex_application_global.vc_arr2; 
BEGIN 
    h1 := DBMS_DATAPUMP.open('IMPORT','FULL',NULL,'EXAMPLE1'); 
    dbms_datapump.add_file(handle => h1, filename => 'IMPORT.LOG', directory => 'DATA_PUMP_DIR', filetype => 3); 
    -- usign this function to split the files passed as a String to an array 
    array := apex_util.string_to_table(DMPFILES, ','); 

    for i in 1 .. array.count loop 
    DBMS_DATAPUMP.ADD_FILE(h1,array(i),'DATA_PUMP_DIR'); 
    end loop; 

    DBMS_DATAPUMP.METADATA_REMAP(h1,'REMAP_SCHEMA',FROMSCHEMA,TOSCHEMA); 

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 => 
'REUSE_DATAFILES', value => 0); 
dbms_datapump.set_parameter(handle => h1, name => 
'SKIP_UNUSABLE_INDEXES', value => 0); 

    DBMS_DATAPUMP.START_JOB(h1); 

-- The import job should now be running. In the following loop, the job is 
-- monitored until it completes. In the meantime, progress information is 
-- displayed. Note: this is identical to the export example. 

percent_done := 0; 
    job_state := 'UNDEFINED'; 
    while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop 
    dbms_datapump.get_status(h1, 
      dbms_datapump.ku$_status_job_error + 
      dbms_datapump.ku$_status_job_status + 
      dbms_datapump.ku$_status_wip,-1,job_state,sts); 
    js := sts.job_status; 

-- If the percentage done changed, display the new value. 

    if js.percent_done != percent_done 
    then 
     dbms_output.put_line('*** Job percent done = ' || 
          to_char(js.percent_done)); 
     percent_done := js.percent_done; 
    end if; 

-- If any work-in-progress (WIP) or Error messages were received for the job, 
-- display them. 

     if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0) 
    then 
     le := sts.wip; 
    else 
     if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0) 
     then 
     le := sts.error; 
     else 
     le := null; 
     end if; 
    end if; 
    if le is not null 
    then 
     ind := le.FIRST; 
     while ind is not null loop 
     dbms_output.put_line(le(ind).LogText); 
     ind := le.NEXT(ind); 
     end loop; 
    end if; 
    end loop; 

-- Indicate that the job finished and gracefully detach from it. 

    dbms_output.put_line('Job has completed'); 
    dbms_output.put_line('Final job state = ' || job_state); 
    dbms_datapump.detach(h1); 
END IMPORTING; 

그래서 기본적으로 내 질문은 : 은 원래의 테이블 스페이스를 모른 채 오라클로 DMP 파일을 가져올 수있는 방법이 ... 있는가?

도움을 미리 감사드립니다.

업데이트 : 이 스크립트를 사용할 때 스키마 이름을 알아야합니다. 그래서 스크립트에 다음과 같이 변경됩니다

 PROCEDURE IMPORTING 
(
    DMPFILES IN VARCHAR2, 
    FROMSCHEMA IN VARCHAR2, 
    TOSCHEMA IN VARCHAR2, 
    FROMTABLESPACE IN VARCHAR2, 
    TOTABLESPACE IN VARCHAR2 
) AS 
    ind NUMBER;    -- Loop index 
    h1 NUMBER;    -- Data Pump job handle 
    percent_done NUMBER;  -- Percentage of job complete 
    job_state VARCHAR2(30); -- To keep track of job state 
    le ku$_LogEntry;   -- For WIP and error messages 
    js ku$_JobStatus;  -- The job status from get_status 
    jd ku$_JobDesc;   -- The job description from get_status 
    sts ku$_Status;   -- The status object returned by get_status 
    array apex_application_global.vc_arr2; 
BEGIN 
    h1 := DBMS_DATAPUMP.open('IMPORT','FULL',NULL,'EXAMPLE1'); 
    dbms_datapump.add_file(handle => h1, filename => 'IMPORT.LOG', directory => 'DATA_PUMP_DIR', filetype => 3); 
    -- usign this function to split the files passed as a String to an array 
    array := apex_util.string_to_table(DMPFILES, ','); 

    for i in 1 .. array.count loop 
    DBMS_DATAPUMP.ADD_FILE(h1,array(i),'DATA_PUMP_DIR'); 
    end loop; 

    DBMS_DATAPUMP.METADATA_REMAP(h1,'REMAP_TABLESPACE',FROMTABLESPACE,TOTABLESPACE); 
    DBMS_DATAPUMP.METADATA_REMAP(h1,'REMAP_SCHEMA',FROMSCHEMA,TOSCHEMA); 

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 => 
'REUSE_DATAFILES', value => 0); 
dbms_datapump.set_parameter(handle => h1, name => 
'SKIP_UNUSABLE_INDEXES', value => 0); 

    DBMS_DATAPUMP.START_JOB(h1); 

-- The import job should now be running. In the following loop, the job is 
-- monitored until it completes. In the meantime, progress information is 
-- displayed. Note: this is identical to the export example. 

percent_done := 0; 
    job_state := 'UNDEFINED'; 
    while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop 
    dbms_datapump.get_status(h1, 
      dbms_datapump.ku$_status_job_error + 
      dbms_datapump.ku$_status_job_status + 
      dbms_datapump.ku$_status_wip,-1,job_state,sts); 
    js := sts.job_status; 

-- If the percentage done changed, display the new value. 

    if js.percent_done != percent_done 
    then 
     dbms_output.put_line('*** Job percent done = ' || 
          to_char(js.percent_done)); 
     percent_done := js.percent_done; 
    end if; 

-- If any work-in-progress (WIP) or Error messages were received for the job, 
-- display them. 

     if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0) 
    then 
     le := sts.wip; 
    else 
     if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0) 
     then 
     le := sts.error; 
     else 
     le := null; 
     end if; 
    end if; 
    if le is not null 
    then 
     ind := le.FIRST; 
     while ind is not null loop 
     dbms_output.put_line(le(ind).LogText); 
     ind := le.NEXT(ind); 
     end loop; 
    end if; 
    end loop; 

-- Indicate that the job finished and gracefully detach from it. 

    dbms_output.put_line('Job has completed'); 
    dbms_output.put_line('Final job state = ' || job_state); 
    dbms_datapump.detach(h1); 
END IMPORTING; 

는 내가 너무 내 보낸 DMP와 나는 테이블 및 스키마 이름을 알고 있었다는 것을 테스트했다.

요약 : 어떤 식 으로든 dmp 파일에서 테이블 공간 이름과 스키마 이름을 알고 싶습니까?

감사합니다.

답변

1

짧은 답변 : 예

긴 대답 : 예 당신이 DDL 파일을 생성 한 다음 실제로 fille을 grep을하고 테이블 스페이스와 사용자를 검색 할 수 있습니다합니다. DDL 파일을 생성하려면 스크립트를 참조하십시오.

create or replace 
PROCEDURE GENERATE_SQL 
(
    DMPFILES IN VARCHAR2 
, SQLFILENAME IN VARCHAR2 
, VERSIONPARAM IN VARCHAR2 
, JOBNAME IN VARCHAR2 
) AS 
    h1 number; 
    array apex_application_global.vc_arr2; 
    ind NUMBER;    -- Loop indexdasdads 
    percent_done NUMBER;  -- Percentage of job complete 
    job_state VARCHAR2(30); -- To keep track of job state 
    le ku$_LogEntry;   -- For WIP and error messages 
    js ku$_JobStatus;  -- The job status from get_status 
    jd ku$_JobDesc;   -- The job description from get_status 
    sts ku$_Status;   -- The status object returned by get_status 
BEGIN 
    h1 := dbms_datapump.open(
    operation => 'SQL_FILE', 
    job_mode  => 'SCHEMA', 
    remote_link => null, 
    job_name  => JOBNAME, 
    version  => VERSIONPARAM 
); 
    array := apex_util.string_to_table(DMPFILES, ','); 
    for i in 1 .. array.count loop 
    dbms_output.put_line('array(i): ' || array(i)); 
    DBMS_DATAPUMP.ADD_FILE(h1,array(i),'DBRAT_DMP',dbms_datapump.ku$_file_type_dump_file); 
    end loop; 
    dbms_output.put_line('datapump_job: ' || h1); 

    dbms_datapump.add_file(
    handle => h1, 
    filename => SQLFILENAME, 
    directory => 'DBRAT_DMP', 
    filetype => dbms_datapump.ku$_file_type_sql_file); 

    dbms_datapump.start_job(
    handle  => h1, 
    skip_current => 0, 
    abort_step => 0); 

    percent_done := 0; 
    job_state := 'UNDEFINED'; 
    while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop 
    dbms_datapump.get_status(h1, 
      dbms_datapump.ku$_status_job_error + 
      dbms_datapump.ku$_status_job_status + 
      dbms_datapump.ku$_status_wip,-1,job_state,sts); 
    js := sts.job_status; 

-- If the percentage done changed, display the new value. 

    if js.percent_done != percent_done 
    then 
     dbms_output.put_line('*** Job percent done = ' || 
          to_char(js.percent_done)); 
     percent_done := js.percent_done; 
    end if; 

-- If any work-in-progress (WIP) or Error messages were received for the job, 
-- display them. 

     if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0) 
    then 
     le := sts.wip; 
    else 
     if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0) 
     then 
     le := sts.error; 
     else 
     le := null; 
     end if; 
    end if; 
    if le is not null 
    then 
     ind := le.FIRST; 
     while ind is not null loop 
     dbms_output.put_line(le(ind).LogText); 
     ind := le.NEXT(ind); 
     end loop; 
    end if; 
    end loop; 

-- Indicate that the job finished and gracefully detach from it. 

    dbms_output.put_line('Job has completed'); 
    dbms_output.put_line('Final job state = ' || job_state); 
    dbms_datapump.detach(h1); 
END GENERATE_SQL;