如何从oracle数据库中获取对象的副本

时间:2011-12-30 03:50:17

标签: oracle oracle10g oracle9i release-management oracleforms

我计划为我们的产品发布一个版本。我们正在使用Oracle表单来开发我们的软件。

所以我有两种类型的发布对象

  1. 前端=> Oracle表单
  2. 后端=> Oracle数据库程序(程序,功能和包)
  3. 发布的一个重要部分是我们需要备份,所以如果发生任何事情,我们可以使用旧版本。

    顺便说一句,对于前端对象,我将使用一些批处理文件为我的前端对象创建备份但是对于后端对象我不知道如何获得函数,过程或包的副本(spec & body)自动。

    知道如何自动完成吗?请指教。 我们正在使用oracle 10g& 9i中

2 个答案:

答案 0 :(得分:2)

  

“在我的公司,有时开发人员应用一些包或功能   在webbex期间,有时客户的生产与我们的生产不同   PVCS“。

那么在存储库中存储代码有什么意义呢?测试配置有什么意义?发布管理有什么意义?

如果这些牛仔开发人员在您的客户的生产环境中徘徊是您的员工,那么您需要对其进行管理。强制执行流程以确保仅部署已认证的配置。如果需要进行紧急调整,则应将其改装为官方版本。

如果这些开发人员真的为客户工作,那么我想你无法阻止他们。但是您不必支持它们,并且您不必对其更改负责。 (除非销售合同说明你必须这样做,这不会让我感到惊讶。)

答案 1 :(得分:1)

(代码blob道歉)。

以下是我用来处理这类问题的一些代码:

PROCEDURE DUMP_CLOB(aCLOB        IN CLOB,
                    hOutput_file IN UTL_FILE.FILE_TYPE) IS
  nCLOB_length       NUMBER;
  nCLOB_offset       NUMBER := 1;
  nMax_chunk_size    NUMBER := 32767;
  strChunk           VARCHAR2(32767);
BEGIN
  nCLOB_length := DBMS_LOB.GETLENGTH(aCLOB);

  WHILE nCLOB_offset <= nCLOB_length LOOP
    strChunk := DBMS_LOB.SUBSTR(aCLOB, nMax_chunk_size, nCLOB_offset);

    UTL_FILE.PUT(hOutput_file, strChunk);

    nCLOB_offset := nCLOB_offset + LENGTH(strChunk);
  END LOOP;

  UTL_FILE.PUT_LINE(hOutput_file, ';');
END DUMP_CLOB;

PROCEDURE DUMP_PRIVS(strOwner        IN  VARCHAR2,
                     strObject_name  IN  VARCHAR2,
                     hOutput_file    IN  UTL_FILE.FILE_TYPE) IS
BEGIN
  FOR pRow IN (SELECT *
                 FROM DBA_TAB_PRIVS p
                 WHERE p.OWNER = strOwner AND
                       p.TABLE_NAME = strObject_name)
  LOOP
    UTL_FILE.PUT_LINE(hOutput_file, 'GRANT ' || pRow.PRIVILEGE || ' ON ' ||
                                    strOwner || '.' || strObject_name ||
                                    ' TO ' || pRow.GRANTEE || ';');
  END LOOP;
END DUMP_PRIVS;

PROCEDURE DUMP_OBJECT(strOwner        IN  VARCHAR2,
                      strObject_name  IN  VARCHAR2,
                      hOutput_file    IN  UTL_FILE.FILE_TYPE)
IS
  clobDDL              CLOB;
  strCurr_object_name  VARCHAR2(100);
BEGIN
  FOR rowObject IN (SELECT *
                      FROM SYS.DBA_OBJECTS o
                      WHERE o.OWNER = strOwner AND
                            o.OBJECT_NAME = strObject_name AND
                            o.OBJECT_TYPE <> 'TABLE PARTITION')
  LOOP
    strCurr_object_name := NVL(rowObject.SUBOBJECT_NAME, rowObject.OBJECT_NAME);

    UTL_FILE.PUT_LINE(hOutput_file, '-- DDL for ' || LOWER(rowObject.OBJECT_TYPE) || ' ' ||
                                    strOwner || '.' || strCurr_object_name);

    SELECT DBMS_METADATA.GET_DDL(rowObject.OBJECT_TYPE, strCurr_object_name, strOwner) AS DDL
      INTO clobDDL
      FROM DUAL;

    DUMP_CLOB(clobDDL, hOutput_file);

    DUMP_PRIVS(strOwner, strCurr_object_name, hOutput_file);

    IF rowObject.OBJECT_TYPE = 'TABLE' THEN
      -- Indexes

      FOR aRow IN (SELECT DBMS_METADATA.GET_DDL('INDEX', i.INDEX_NAME, i.OWNER) AS clobIndex
                     FROM DBA_INDEXES I
                     WHERE I.TABLE_OWNER = strOwner AND
                           I.TABLE_NAME = strCurr_object_name)
      LOOP
        DUMP_CLOB(aRow.clobIndex, hOutput_file);
      END LOOP;  -- Indexes
    END IF;

    IF rowObject.OBJECT_TYPE IN ('TABLE', 'VIEW') THEN
      -- Triggers

      FOR aRow IN (SELECT DBMS_METADATA.GET_DDL('TRIGGER', t.TRIGGER_NAME, t.OWNER) AS clobTrigger
                     FROM DBA_TRIGGERS t
                     WHERE TABLE_OWNER = strOwner AND
                     TABLE_NAME = strCurr_object_name)
      LOOP
        DUMP_CLOB(aRow.clobTrigger, hOutput_file);
      END LOOP;  -- Triggers
    END IF;
  END LOOP;
END DUMP_OBJECT;


PROCEDURE DUMP_OBJECT(strOwner           IN  VARCHAR2,
                      strObject_name     IN  VARCHAR2,
                      strDirectory_name  IN  VARCHAR2,
                      strFilename        IN  VARCHAR2,
                      strOpen_mode       IN  VARCHAR2 DEFAULT 'w')
IS
  hOutput_file  UTL_FILE.FILE_TYPE;
BEGIN
  hOutput_file := UTL_FILE.FOPEN(location  => strDirectory_name,
                                 filename  => strFilename,
                                 open_mode => strOpen_mode);
  DUMP_OBJECT(strOwner, strObject_name, hOutput_file);
  UTL_FILE.FCLOSE(hOutput_file);
EXCEPTION
  WHEN OTHERS THEN
    UTL_FILE.FCLOSE(hOutput_file);
    RAISE;
END DUMP_OBJECT;

我建议将这些程序放入一个包中。为你想要转储的东西调用DUMP_OBJECT。

分享并享受。