DBMS_METADATA

Всё по теме СУБД Oracle: установка, настройка, использование, решение проблем и т.д. и т.п. и др. и пр.
Ответить
Yury_P
Сообщения: 43
Зарегистрирован: Вт авг 23, 2022 3:07 pm

DBMS_METADATA

Сообщение Yury_P »

Здравствуйте,

Или я отстал от жизни или dbms_metadata не показывает полный DDL ...
Test case: создаём таблицу с партициями и делаем для неё DDL.

Код: Выделить всё

$ sql
conn / as sysdba
drop user testuser cascade;
grant dba to testuser identified by testuser;

conn testuser/testuser
create table TEST
   PARTITION BY RANGE (OBJECT_ID) INTERVAL (10000) 
 ( PARTITION "P_INITIAL"  VALUES LESS THAN (10000) )
as select * from dba_objects where object_id<60000;

select count(*) from test;

select object_type,object_name,subobject_name,status FROM user_objects order by 1,2,3;

select SEGMENT_TYPE,SEGMENT_NAME,PARTITION_NAME,BYTES,BLOCKS,EXTENTS from user_segments;

exec dbms_stats.gather_table_stats(null,'TEST');

select TABLE_NAME,PARTITION_NAME,HIGH_VALUE,NUM_ROWS,BLOCKS from user_tab_partitions;

ddl test

SELECT  sys.dbms_metadata.get_ddl ('TABLE','TEST','TESTUSER') FROM DUAL;
И вот что получается:

Код: Выделить всё

SQL> conn / as sysdba
Connected.
SQL> drop user testuser cascade;
User TESTUSER dropped.

SQL> grant dba to testuser identified by testuser;
Grant succeeded.

SQL> conn testuser/testuser
Connected.
SQL> create table TEST
  2     PARTITION BY RANGE (OBJECT_ID) INTERVAL (10000) 
  3   ( PARTITION "P_INITIAL"  VALUES LESS THAN (10000) )
  4* as select * from dba_objects where object_id<60000;

Table TEST created.

SQL> select count(*) from test;

   COUNT(*) 
___________ 
      58196 

SQL> select object_type,object_name,subobject_name,status FROM user_objects order by 1,2,3;

   OBJECT_TYPE    OBJECT_NAME    SUBOBJECT_NAME    STATUS 
______________ ______________ _________________ _________ 
TABLE          TEST                             VALID     
TABLE PARTITION    TEST           P_INITIAL         VALID     
TABLE PARTITION    TEST           SYS_P420          VALID     
TABLE PARTITION    TEST           SYS_P421          VALID     
TABLE PARTITION    TEST           SYS_P422          VALID     
TABLE PARTITION    TEST           SYS_P423          VALID     
TABLE PARTITION    TEST           SYS_P424          VALID     
7 rows selected. 

SQL> 
SQL> select SEGMENT_TYPE,SEGMENT_NAME,PARTITION_NAME,BYTES,BLOCKS,EXTENTS from user_segments;

      SEGMENT_TYPE    SEGMENT_NAME    PARTITION_NAME      BYTES    BLOCKS    EXTENTS 
__________________ _______________ _________________ __________ _________ __________ 
TABLE PARTITION    TEST            P_INITIAL            8388608      1024          1 
TABLE PARTITION    TEST            SYS_P420             8388608      1024          1 
TABLE PARTITION    TEST            SYS_P421             8388608      1024          1 
TABLE PARTITION    TEST            SYS_P422             8388608      1024          1 
TABLE PARTITION    TEST            SYS_P423             8388608      1024          1 
TABLE PARTITION    TEST            SYS_P424             8388608      1024          1 
6 rows selected. 

SQL> 
SQL> exec dbms_stats.gather_table_stats(null,'TEST');

PL/SQL procedure successfully completed.

SQL> 
SQL> select TABLE_NAME,[b]PARTITION_NAME[/b],HIGH_VALUE,NUM_ROWS,BLOCKS from [b]user_tab_partitions[/b];

   TABLE_NAME    [b]PARTITION_NAME[/b]    HIGH_VALUE    NUM_ROWS    BLOCKS 
_____________ _________________ _____________ ___________ _________ 
TEST          P_INITIAL         10000                9972       191 
TEST          SYS_P420          20000                9934       197 
TEST          SYS_P421          30000                9620       200 
TEST          SYS_P422          40000                9832       216 
TEST          SYS_P423          50000                9983       207 
TEST          SYS_P424          60000                8855       189 
6 rows selected. 

SQL> 
SQL> ddl test

  CREATE TABLE "TESTUSER"."TEST" 
   (	"OWNER" VARCHAR2(128), 
	"OBJECT_NAME" VARCHAR2(128), 
	"SUBOBJECT_NAME" VARCHAR2(128), 
	"OBJECT_ID" NUMBER, 
	"DATA_OBJECT_ID" NUMBER, 
	"OBJECT_TYPE" VARCHAR2(23), 
	"CREATED" DATE, 
	"LAST_DDL_TIME" DATE, 
	"TIMESTAMP" VARCHAR2(19), 
	"STATUS" VARCHAR2(7), 
	"TEMPORARY" VARCHAR2(1), 
	"GENERATED" VARCHAR2(1), 
	"SECONDARY" VARCHAR2(1), 
	"NAMESPACE" NUMBER, 
	"EDITION_NAME" VARCHAR2(128), 
	"SHARING" VARCHAR2(18), 
	"EDITIONABLE" VARCHAR2(1), 
	"ORACLE_MAINTAINED" VARCHAR2(1), 
	"APPLICATION" VARCHAR2(1), 
	"DEFAULT_COLLATION" VARCHAR2(100), 
	"DUPLICATED" VARCHAR2(1), 
	"SHARDED" VARCHAR2(1), 
	"CREATED_APPID" NUMBER, 
	"CREATED_VSNID" NUMBER, 
	"MODIFIED_APPID" NUMBER, 
	"MODIFIED_VSNID" NUMBER
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" 
  PARTITION BY RANGE ("OBJECT_ID") INTERVAL (10000) 
 [b](PARTITION "P_INITIAL"  VALUES LESS THAN (10000)[/b] SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
 NOCOMPRESS LOGGING 
  STORAGE(INITIAL 8388608 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ) ;

SQL> SELECT  sys.dbms_metadata.get_ddl ('TABLE','TEST','TESTUSER') FROM DUAL;

  CREATE TABLE "TESTUSER"."TEST" 
   (	"OWNER" VARCHAR2(128), 
	"OBJECT_NAME" VARCHAR2(128), 
	"SUBOBJECT_NAME" VARCHAR2(128), 
	"OBJECT_ID" NUMBER, 
	"DATA_OBJECT_ID" NUMBER, 
	"OBJECT_TYPE" VARCHAR2(23), 
	"CREATED" DATE, 
	"LAST_DDL_TIME" DATE, 
	"TIMESTAMP" VARCHAR2(19), 
	"STATUS" VARCHAR2(7), 
	"TEMPORARY" VARCHAR2(1), 
	"GENERATED" VARCHAR2(1), 
	"SECONDARY" VARCHAR2(1), 
	"NAMESPACE" NUMBER, 
	"EDITION_NAME" VARCHAR2(128), 
	"SHARING" VARCHAR2(18), 
	"EDITIONABLE" VARCHAR2(1), 
	"ORACLE_MAINTAINED" VARCHAR2(1), 
	"APPLICATION" VARCHAR2(1), 
	"DEFAULT_COLLATION" VARCHAR2(100), 
	"DUPLICATED" VARCHAR2(1), 
	"SHARDED" VARCHAR2(1), 
	"CREATED_APPID" NUMBER, 
	"CREATED_VSNID" NUMBER, 
	"MODIFIED_APPID" NUMBER, 
	"MODIFIED_VSNID" NUMBER
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" 
  PARTITION BY RANGE ("OBJECT_ID") INTERVAL (10000) 
 ([b]PARTITION "P_INITIAL"  VALUES LESS THAN (10000) [/b]SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
 NOCOMPRESS LOGGING 
  STORAGE(INITIAL 8388608 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ) ;  
В выводе DDL одна единственная партиция "PARTITION "P_INITIAL" VALUES LESS THAN (10000)".
Вот так посмотришь DDL и будешь уверен, что в таблице только одна партиция. А их там - много !

Так должно быть ?

Версия 19.20, DataPump patch установлен.
Аватара пользователя
SQL*Plus
Сообщения: 256
Зарегистрирован: Ср апр 20, 2022 1:09 pm

Re: DBMS_METADATA

Сообщение SQL*Plus »

Yury_P писал(а): Вт янв 16, 2024 11:57 am

Код: Выделить всё

SQL> create table TEST
  2     PARTITION BY RANGE (OBJECT_ID) INTERVAL (10000) 
  3   ( PARTITION "P_INITIAL"  VALUES LESS THAN (10000) )
  4* as select * from dba_objects where object_id<60000;
Table TEST created.
. . .
SQL> select object_type,object_name,subobject_name,status FROM user_objects order by 1,2,3;

   OBJECT_TYPE    OBJECT_NAME    SUBOBJECT_NAME    STATUS 
______________ ______________ _________________ _________ 
TABLE          TEST                             VALID     
TABLE PARTITION    TEST           P_INITIAL         VALID     
TABLE PARTITION    TEST           SYS_P420          VALID     
TABLE PARTITION    TEST           SYS_P421          VALID     
TABLE PARTITION    TEST           SYS_P422          VALID     
TABLE PARTITION    TEST           SYS_P423          VALID     
TABLE PARTITION    TEST           SYS_P424          VALID     
7 rows selected. 
Думаю, что это штатное поведение при интервальном секционировании.
При создании таблицы указан способ секционирования (интервалу по OBJECT_ID через 10000
PARTITION BY RANGE (OBJECT_ID) INTERVAL (10000)
и одна (первая) секция (partition) P_INITIAL
PARTITION "P_INITIAL" VALUES LESS THAN (10000)

Пять секций SYS_Pxxx были созданы при заполнении таблицы.
Получилось в данном примере 5 (пять) секций SYS_Pxxx.
Если то же самое действие выполнить в той же БД в другое время или в другой БД,
может получиться больше или меньше секций - это зависит от количества строк,
которые вернет SELECT.

Поэтому DBMS_METADATA.GET_DDL возвращает команду создания таблицы,
не зависящую от данных, которыми она будет заполняться.
Аватара пользователя
SQL*Plus
Сообщения: 256
Зарегистрирован: Ср апр 20, 2022 1:09 pm

Re: DBMS_METADATA

Сообщение SQL*Plus »

Покопался ещё и нашел:
чтобы выводились сведения о секциях (partitions), созданных автоматически по интеревалам,
нужно на уровне сессии установить значение параметра преобразования EXPORT = TRUE,
а затем уже вызывать функцию GET_DDL

Код: Выделить всё

EXEC dbms_metadata.set_transform_param(dbms_metadata.SESSION_TRANSFORM, 'EXPORT', TRUE);
SELECT  sys.dbms_metadata.get_ddl ('TABLE','TEST','TESTUSER') FROM DUAL;
Проверил.
Работает!
Ответить