Как получить копию объектов из базы данных Oracle - PullRequest
1 голос
/ 30 декабря 2011

Я планирую сделать релиз для нашего продукта. мы используем формы Oracle для разработки нашего программного обеспечения.

Итак, у меня есть два типа объектов для выпуска

  1. Front-end => Формы Oracle
  2. Back-end => Программа базы данных Oracle (процедура, функция и пакет)

Одной из важных частей релиза является необходимость создания резервной копии, чтобы в случае чего мы могли использовать старую версию.

Кстати, для объекта переднего плана я буду использовать какой-то командный файл для создания резервной копии для своих объектов переднего плана, но для объекта внутреннего уровня я не знаю, как получить копию функции, процедуры или пакета (спецификация & body) автоматически.

Есть идеи, как я могу сделать это автоматически? пожалуйста, посоветуйте мне. мы используем оракула 10g & 9i

Ответы [ 2 ]

2 голосов
/ 30 декабря 2011

"В моей компании иногда разработчик применяет какой-то пакет или функцию во время Webbex, так что иногда производство клиентов не совпадает с нашим PVCS ".

Так какой смысл хранить код в репозитории? Какой смысл тестировать конфигурацию? В чем смысл управления релизами?

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

Если эти разработчики действительно работают на клиента, то, я полагаю, вы не можете их остановить. Но вам не нужно их поддерживать, и вы не должны нести ответственность за их изменения. (если в договоре купли-продажи не указано иное, что меня не удивит.)

1 голос
/ 30 декабря 2011

(извинения за блок кода).

Вот код, который я использовал для решения таких проблем:

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 для вещей, которые вы хотите сбросить.

Поделитесь и наслаждайтесь.

...