【问题标题】:How to import Oracle DMP file without knowing the original tablespace?如何在不知道原始表空间的情况下导入 Oracle DMP 文件?
【发布时间】:2017-09-27 22:49:14
【问题描述】:

用例:客户将在 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 文件导入 Oracle...?

提前感谢您的帮助。

更新: 我发现在使用这个脚本时,我还需要知道架构名称。所以这将对脚本进行以下更改:

     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 对其进行了测试,因此我知道 TableSpace 和 Schema 名称。

总结:有什么方法可以从 dmp 文件中知道表空间名称和模式名称?

谢谢。

【问题讨论】:

    标签: database oracle migration datapump


    【解决方案1】:

    简短回答:没有

    长答案:是的如果您生成 ddl 文件,然后您实际上可以 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;
    

    【讨论】:

      猜你喜欢
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 2023-03-24
      • 1970-01-01
      • 2011-11-20
      相关资源
      最近更新 更多