При сравнении схемы в oracle db необходимо игнорировать последовательность «начать с» для столбца идентификаторов. - PullRequest
1 голос
/ 05 августа 2020

У нас есть база данных oracle (18 c) на нескольких серверах, и нам необходимо синхронизировать c схему с серверов разработки и продуктов. Поскольку необходимо синхронизировать только схему, а не содержимое таблиц, нам не нужно знать следующий порядковый номер столбцов первичного ключа. (И мы, конечно, не хотим обновлять prod-серверы с этим порядковым номером.)

Пробовали как SQL Developers Diff Tool, так и dbForge Schema Compare для Oracle, но они оба перечисляют таблицы, где только это порядковый номер отличается от таблиц, которые необходимо обновить.

Я не нашел настройки в SQL Developer Diff Tool, которая справляется с этим. В dbForge Schema Compare для Oracle у них есть Ignore START WITH in sequences, но это, похоже, не работает, как я думал, поскольку он по-прежнему отмечает таблицы, которые равны, за исключением порядкового номера, как таблицы, которые нуждаются в обновлении.

Для новых таблиц, которые существуют только в исходной базе данных, сценарий syn c будет выглядеть следующим образом:

CREATE TABLE TEST (
ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY(
START WITH 102),
TEXT VARCHAR2(4000 BYTE),
CONSTRAINT TEST_ID_PK PRIMARY KEY (ID))
LOGGING;

Нам нужен этот сценарий без части (START WITH 102) в нем.

Для таблицы, которая существует как в исходной, так и в целевой базе данных (без каких-либо других изменений, кроме порядкового номера), сценарий syn c будет выглядеть так:

ALTER TABLE TEST
  MODIFY(ID GENERATED BY DEFAULT ON NULL AS IDENTITY(
  START WITH 114
  INCREMENT BY 1
  MAXVALUE 9999999999999999999999999999
  MINVALUE 1
  CACHE 20
  NOCYCLE
  NOORDER));

Реальность такова, что это таблица, которая не требует обновления, и я думал, что Ignore START WITH in sequence справится с этим, но, по-видимому, нет.

Кто-нибудь может предложить нам решение?

1 Ответ

3 голосов
/ 05 августа 2020

Что ж, я считаю, что использовать SQL Developer или любой другой инструмент IDE для создания сценариев для развертывания в производственной среде - очень плохая идея. Вы описываете явный случай отсутствия реальной контрольной версии программного обеспечения, например GIT или SVN. Вам не нужно сравнивать базы данных, если что-то не так, но никогда не нужно создавать сценарии DDL.

В этом конкретном c случае я бы использовал DBMS_METADATA для создания DDL

Пример

SQL> create table t ( c1 number generated by default on null as identity ( start with 1 increment by 1 ) , c2 number ) ;

Table created.

SQL> insert into t values ( null , 1 ) ;

1 row created.

SQL> r
  1* insert into t values ( null , 1 )

1 row created.

SQL> r
  1* insert into t values ( null , 1 )

1 row created.

SQL> r
  1* insert into t values ( null , 1 )

1 row created.

SQL> select * from t ;

        C1         C2
---------- ----------
         1          1
         2          1
         3          1
         4          1

В этом случае SQL разработчик показывает start with 5, потому что это следующее значение столбца идентификаторов. Вы можете использовать DBMS_METADATA.GET_DDL, чтобы получить правильный DDL без этого предложения.

SQL> begin
    DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'SQLTERMINATOR', true);
    DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'PRETTY', true);
end;
/

PL/SQL procedure successfully completed.

SQL> select dbms_metadata.get_ddl('TABLE','T') from dual

DBMS_METADATA.GET_DDL('TABLE','T')
--------------------------------------------------------------------------------

  CREATE TABLE "SYS"."T"
   (    "C1" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 99
99999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER  NOCYCLE
  NOKEEP  NOSCALE  NOT NULL ENABLE,
        "C2" NUMBER
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" ;

Есть несколько вариантов, например, чтобы не получать атрибуты хранилища. Я всегда использую этот

SQL> BEGIN
  2       DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'SQLTERMINATOR', true);
     DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'PRETTY', true);
  3    4       DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'SEGMENT_ATTRIBUTES', true);
     DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'STORAGE', false);
  END;
  /  5    6    7

PL/SQL procedure successfully completed.

SQL> select dbms_metadata.get_ddl('TABLE','T') from dual ;

DBMS_METADATA.GET_DDL('TABLE','T')
--------------------------------------------------------------------------------

  CREATE TABLE "SYS"."T"
   (    "C1" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 99
99999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER  NOCYCLE
  NOKEEP  NOSCALE  NOT NULL ENABLE,
        "C2" NUMBER
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  TABLESPACE "SYSTEM" ;


SQL>

Для сравнения вы можете взглянуть на DBMS_COMPARISON

https://docs.oracle.com/database/121/ARPLS/d_comparison.htm#ARPLS868

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...