2017-09-27 2 views
1

Cas d'utilisation: le client envoie sa sauvegarde de sa base de données dans un fichier dmp. C'est tout ce qu'ils vont envoyer.Comment importer un fichier Oracle DMP sans connaître le tablespace d'origine?

Je construis un script qui va importer ce fichier dmp dans Oracle en utilisant DBMS_DATAPUMP. Toutefois, comme je ne connais pas le nom d'espace table d'origine, j'obtiens l'erreur suivante: ORA-39083: Type d'objet USER: "XXXXX" n'a pas réussi à créer avec erreur: ORA-00959: l'espace de table 'XXXXXXX' n'existe pas

Ceci est mon PL/SQL procédure:

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; 

donc, fondamentalement, ma question est: est-il possible d'importer un fichier dmp dans Oracle sans connaître le tablespace d'origine ...?

Merci d'avance pour l'aide.

MISE À JOUR: J'ai trouvé lors de l'utilisation de ce script, j'ai également besoin de connaître le nom du schéma. Donc, cela apportera les modifications suivantes sur le script:

 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; 

J'ai testé cela avec un dmp que je connaissais si j'exporté le tablespace et le nom du schéma.

Résumé: comment connaître le nom du tablespace et le nom du schéma à partir d'un fichier dmp?

Merci.

Répondre

1

Réponse courte: non

Réponse longue: oui si vous générez le fichier ddl et vous pouvez réellement grep la fille et rechercher les tablespaces et les utilisateurs. Voir ci-dessous le script pour générer le fichier 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;