Arquivo da categoria: PL/SQL

Privilégios insuficientes ao criar view materializada em um esquema diferente

Recentemente um analista me trouxe uma questão interessante.  Ele reclamava que estava recebendo a mensagem ORA-01031: privilégios insuficientes ao criar uma view materializada sob um esquema diferente.

Eu também tentei criar a view materializada usando o usuário SYSTEM,  mas obtive o mesmo erro.

Depois de pesquisar no MOS, encontrei uma nota muito interessante: ORA-01031: Privilégios insuficientes quando criar um Mview em um esquema  diferente (Doc ID 749112.1) .

Segundo a nota do MOS, este não é um erro de código. Este é um comportamento esperado.
Conforme explicado acima,  ao owner da tabela base deve ser concedido  o privilégio ‘create table’ explicitamente.  Conceder o privilégio de ‘create table’ explicitamente ao owner do esquema nos permite criar views materializadas em um outro esquema.

Apos o grant, a instrução CREATE MATERIALIZED VIEW funciona como esperado:

1- Testes de criação de Visão Materializada sem o grant

No SQLPLUS tentei criar uma visão:

SQL> create materialized view SERGIO.MV_TESTE_POST
2 refresh force on demand
3 as
4 Select a.NI_ID, a.DT_TRANSACAO
5 from sergio.vw_arquivo a
6 where a.DT_TRANSACAO > to_date (’20/10/2016′) and
7 a.VALOR >= 100;

ERROR na linha 1:
ORA-01031: privilégios insuficientes

2 – Testes de criação de Visão Materializada como grant

No SQLPLUS após o grant,  criei a visão acima:

SQL> grant create table to SERGIO;

Grant succeeded

SQL>
SQL> create materialized view SERGIO.MV_TESTE_POST
2 refresh force on demand
3 as
4 Select a.NI_ID, a.DT_TRANSACAO
5 from sergio.vw_arquivo a
6 where a.DT_TRANSACAO > to_date (’20/10/2016′) and
7 a.VALOR >= 100;

Materialized view created

SQL>

Depois que o problema foi resolvido o analista me fez a seguinte pergunta:
“A função RESOURCE contém o privilégio CREATE TABLE, por que eu tenho que conceder esse privilégio de forma explícita?”.

Pesquisando no MOS, encontrei no documento 11740.1 (restrições de Roles)  a resposta para esta questão:

“Um usuário não pode criar um objeto usando privilégios recebidos por meio de uma role.
Por exemplo, um usuário não pode criar uma visão com base na tabela caso ele tenha recebido a permissão de select nesta tabela por meio de uma função.
Isso também se aplica a procedures, triggers e referências a tabela de outros usuários.
…Essa restrição é necessária porque as funções podem ser ativadas ou
desativadas dinamicamente, tornando a verificação de segurança em tempo de
execução ambígua.
…As roles são destinadas a serem usadas como uma ferramenta para administrar
privilégios para usuários finais.
Eles não são destinados a serem usados pelos desenvolvedores de aplicativos.

Espero que esta postagem seja útil.

Um abraço a todos!!!

Utilizando Help no SQLPLUS

 

 

Neste post estarei falando sobre o uso de scripts do Oracle Database, para carregar  o comando HELP para o SQLPLUS que pode ajudá-lo rapidamente a tirar dúvidas sobre comandos do SQLPLUS. Os scripts de instalação e remoção do help esta em $ORACLE_HOME/sqlplus/admin/help

O esquema a ser utilizado é SYSTEM, não SYS.

Abaixo segue uma demonstração de como habilitar o HELP para o SQLPLUS.

1 – Entar no diretório abaixo:

cd $ORACLE_HOME/sqlplus/admin/help

2 – Listar o conteúdo do diretório

ls -l
total 84

-rwxrwxrwx. 1 oracle oracle   265 Feb 17 2003 helpbld.sql

-rwxrwxrwx. 1 oracle oracle   366 Jan 4 2011 helpdrop.sql

-rwxrwxrwx. 1 oracle oracle 71817 Aug 17 2012 helpus.sql

-rwxrwxrwx. 1 oracle oracle 2154 Jan 4 2011 hlpbld.sql

3 – Executar o script de instalação do HELP

sqlplus -S system/oracle @helpbld.sql `pwd` helpus.sql

1 row created. 

Commit complete.
1 row created.

Commit complete.
Table altered.
View created.
58 rows created.
Commit complete.
PL/SQL procedure successfully completed.

O ‘pwd’ é uma forma de especificar o diretório atual no Unix e no Linux e especifica onde o arquivo de dados de ajuda está localizado. o script helpus.sql são os arquivos de dados de ajuda em Inglês (US-Inglês).

Os scripts cria uma tabela chamada “HELP” no esquema SYSTEM. Ao executar o comando “HELP” do SQLPlus, esta tabela será utilizada.

  • Exemplo de Utilização do comando HELP.

SQL> connect hr/hr 

Connected.

 

SQL> help col

COLUMN
——
Specifies display attributes for a given column, such as:
– text for the column heading
– alignment for the column heading
– format for NUMBER data
– wrapping of column data
Also lists the current display attributes for a single column
or all columns.
COL[UMN] [{column | expr} [option …] ]
where option represents one of the following clauses:
ALI[AS] alias
CLE[AR]
ENTMAP {ON|OFF}
FOLD_A[FTER]
FOLD_B[EFORE]
FOR[MAT] format
HEA[DING] text
JUS[TIFY] {L[EFT] | C[ENTER] | R[IGHT]}
LIKE {expr | alias}
NEWL[INE]
NEW_V[ALUE] variable
NOPRI[NT] | PRI[NT]
NUL[L] text
OLD_V[ALUE] variable
ON|OFF
WRA[PPED] | WOR[D_WRAPPED] | TRU[NCATED]

SQL>

SQL> help set

SET

Sets a system variable to alter the SQL*Plus environment settings  for your current session. For example, to:

–   set the display width for data

–   customize HTML formatting

–   enable or disable printing of column headings

–   set the number of lines per page

SET system_variable value   where system_variable and value represent one of the following clauses:

 APPI[NFO]{OFF|ON|text}                   NEWP[AGE] {1|n|NONE}    ARRAY[SIZE] {15|n}                       NULL text    AUTO[COMMIT] {OFF|ON|IMM[EDIATE]|n}      NUMF[ORMAT] format    AUTOP[RINT] {OFF|ON}                     NUM[WIDTH] {10|n}    AUTORECOVERY {OFF|ON}                    PAGES[IZE] {14|n}    AUTOT[RACE] {OFF|ON|TRACE[ONLY]}         PAU[SE] {OFF|ON|text}      [EXP[LAIN]] [STAT[ISTICS]]             RECSEP {WR[APPED]|EA[CH]|OFF}    BLO[CKTERMINATOR] {.|c|ON|OFF}           RECSEPCHAR {_|c}    CMDS[EP] {;|c|OFF|ON}                    SERVEROUT[PUT] {ON|OFF}    COLSEP {_|text}                            [SIZE {n | UNLIMITED}]    CON[CAT] {.|c|ON|OFF}                      [FOR[MAT]  {WRA[PPED] |    COPYC[OMMIT] {0|n}                          WOR[D_WRAPPED] |    COPYTYPECHECK {ON|OFF}                      TRU[NCATED]}]    DEF[INE] {&|c|ON|OFF}                    SHIFT[INOUT] {VIS[IBLE] |    DESCRIBE [DEPTH {1|n|ALL}]                 INV[ISIBLE]}      [LINENUM {OFF|ON}] [INDENT {OFF|ON}]   SHOW[MODE] {OFF|ON}    ECHO {OFF|ON}                            SQLBL[ANKLINES] {OFF|ON}    EDITF[ILE] file_name[.ext]               SQLC[ASE] {MIX[ED] |    EMB[EDDED] {OFF|ON}                        LO[WER] | UP[PER]}    ERRORL[OGGING] {ON|OFF}                  SQLCO[NTINUE] {> | text}      [TABLE [schema.]tablename]             SQLN[UMBER] {ON|OFF}      [TRUNCATE] [IDENTIFIER identifier]     SQLPLUSCOMPAT[IBILITY] {x.y[.z]}    ESC[APE] {\|c|OFF|ON}                    SQLPRE[FIX] {#|c}    ESCCHAR {@|?|%|$|OFF}                    SQLP[ROMPT] {SQL>|text}    EXITC[OMMIT] {ON|OFF}                    SQLT[ERMINATOR] {;|c|ON|OFF}    FEED[BACK] {6|n|ON|OFF}                  SUF[FIX] {SQL|text}    FLAGGER {OFF|ENTRY|INTERMED[IATE]|FULL}  TAB {ON|OFF}    FLU[SH] {ON|OFF}                         TERM[OUT] {ON|OFF}    HEA[DING] {ON|OFF}                       TI[ME] {OFF|ON}    HEADS[EP] {||c|ON|OFF}                   TIMI[NG] {OFF|ON}    INSTANCE [instance_path|LOCAL]           TRIM[OUT] {ON|OFF}    LIN[ESIZE] {80|n}                        TRIMS[POOL] {OFF|ON}    LOBOF[FSET] {1|n}                        UND[ERLINE] {-|c|ON|OFF}    LOGSOURCE [pathname]                     VER[IFY] {ON|OFF}    LONG {80|n}                              WRA[P] {ON|OFF}    LONGC[HUNKSIZE] {80|n}                   XQUERY {BASEURI text|    MARK[UP] HTML [OFF|ON]                     ORDERING{UNORDERED|      [HEAD text] [BODY text] [TABLE text]              ORDERED|DEFAULT}|      [ENTMAP {ON|OFF}]                        NODE{BYVALUE|BYREFERENCE|      [SPOOL {OFF|ON}]                              DEFAULT}|      [PRE[FORMAT] {OFF|ON}]                   CONTEXT text}

SQL>

Para melhor entendermos, o HELP usa um arquivo de texto simples (script helpus.sql neste caso) para carregar as informações de ajuda.

NOTA: Os comando suportados pelo HELP são comandos SQLPlus, não Comandos de linguagem SQL. Logo,  o comando HELP não fornecerá ajuda sobre comandos CREATE ou ALTER ou SELECT e entre outros comandos.

Para remover o script instalado HELP, o procedimento é semelhante ao de instalação conforme podemos ver abaixo:

sqlplus -S system/oracle @helpdrop.sql `pwd` helpus.sql

  • Verificando a emoção do script HELP

sqlplus hr/hr

SQL*Plus: Release 11.2.0.1.0 Production on Tue Jul 26 22:11:45 2016
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> help
SP2-0171: HELP system not available.
SQL>

Um abraço a Todos!!

 

 

Utilizando Expressões Regulares

A partir da versão 10g do banco de dados a Oracle implementou o uso de expressões regulares. Uma expressão regular é uma expressão que define um padrão de caracteres. Você pode usar uma expressão regular para encontrar strings que correspondem a um padrão específico em uma string de dados. As funções de expressões regulares disponíveis no Oracle pode nos ajudar a realizar as tarefas de busca de caracteres de uma forma mais simples e rápida.

Você pode usar essas funções em uma literal de texto, variável bind ou qualquer coluna de dados de tipo de caracteres como: CHAR, NCHAR, CLOB, NCLOB, NVARCHAR2 e VARCHAR2 (exceto tipo de dados LONG).

As expressões regulares disponíveis no Oracle, são implementadas com as seguintes funções:

  • REGEXP_INSTR – Semelhante a função INSTR,  usa uma expressão regular em vez de uma literal como cadeia de procura.
  • REGEXP_LIKE – Semelhante a função LIKE, só que esta função usa uma expressão regular como cadeia de procura.
  • REGEXP_REPLACEO uso dessa função tem como objetivo procurar um padrão e substituí-lo por uma string.
  • REGEXP_SUBSTR – Retorna parte de uma string com recursos avançados, estende as funcionalidades da função SUBSTR, permitindo pesquisar uma string para uma expressão regular padrão. 
  • REGEXP_COUNT (Novidade na versão 11g) – Usado para obter a quantidade de vezes que uma expressão regular ocorre em uma string.

Logo abaixo montamos um cenário com dois exemplo, passo a passo de consultas utilizando expressões regulares:

1 – Utilizando REGEXP_LIKE(x, padrão[,opção_correspondente])  

Esta expressão realiza a busca em da expressão regular definida no parâmetro padrão. A opção_correspondente  pode ser definida com os valores abaixo:

  • ‘c’  – Especifica correspondência com diferenciação de maiúsculas e minúsculas (Padrão – case-sensitive)
  • ‘i’   – Especifica a busca sem diferenciação de caracteres maiúsculos e minúsculos (case-insensitive)
  • ‘n’  – Que permite usar o operador de correspondência com qualquer caractere.
  • ‘m’ – Que trata x como uma linha múltipla.
  • ‘x’  – ignora espaços em branco.

A semelhança com o comando LIKE não é mera coincidência, mas o leitor já poderá notar a maior flexibilidade no uso de REGEXP_LIKE  em relação ao operador  LIKE.

No primeiro exemplo abaixo, suponhamos a necessidade de achar na tabela de clientes, todos os clientes que tenham credito entre 10 e 19. Podemos realizar a busca usando expressões regulares da seguinte forma:

SELECT CUST_FIRST_NAME,CUST_LAST_NAME, CREDIT_LIMIT FROM SOE.CUSTOMERS  WHERE REGEXP_LIKE(CREDIT_LIMIT,’^1[0-9]$’);

Captura de Tela 2016-04-04 às 15.28.24

No segundo exemplo abaixo, foi feito um select para recuperar os clientes cujo sobrenome se iniciem com ‘Co’ ou ‘co’, o que é realmente um exemplo simples. Nesse caso  por exemplo,  podemos lançar mão do seguinte código, onde podemos observar que o metacaracter  “^” garante a busca no inicio do campo e a opção correspondente “i”  garante uma busca case-insensitive:

SELECT CUST_FIRST_NAME,CUST_LAST_NAME, CREDIT_LIMIT FROM SOE.CUSTOMERS  WHERE REGEXP_LIKE(CUST_LAST_NAME,’^Co’,’i’);

Captura de Tela 2016-04-04 às 15.18.05

OBS: A expressão regexp_like é uma ferramenta poderosa para consultas, mas no entanto não se deve usar essa expressão regular quando uma cláusula LIKE simples vai funcionar, pois haverá uma sobrecarga (full table scan) ao usar expressão regular em oposição a caracteres coringas.

2 –  REGEXP_REPLACE

SQL> SELECT PRODUCT_STATUS FROM PRODUCT_INFORMATION WHERE ROWNUM < 10;

Captura de Tela 2016-04-06 às 11.59.43

SQL> SELECT  REGEXP_REPLACE(PRODUCT_STATUS,’obsolete’,’obsoleto’) FROM PRODUCT_INFORMATION WHERE ROWNUM < 10;
Captura de Tela 2016-04-06 às 12.00.10

 

 

 

 

Conclusão:

As Expressões regulares são muito poderosas e permitem efetuar qualquer padrão de pesquisa, porém a sua utilização deve ser muito bem avaliada. Pois se forem mal utilizadas, poderão tornar as consultas muito lentas  e consequentemente, poderão degradar a performance da instrução SQL.

Para maiores informações e aprofundamento segue os links abaixo:

Como Rastrear uma Sessão usando SQL_TRACE

O rastreamento de sessões podem ser feito de várias maneiras em um banco de dados Oracle.
Um dos métodos mais populares é através do parâmetro sql_trace a nível de sessão.

SINTAXE:
alter session set events ‘sql_trace level <trace_level>’

ONDE:
<trace_level>  define o nível de rastreamento de uma instrução SQL que pode ser realizada;

Exemplo:

Todos os exemplos abaixo, foram efetuados em sessões conectadas a um banco de dados single-instance utilizando uma conexão dedicada.

1. Habilitando o rastreamento a nível de sessão

SQL> alter session set events ‘sql_trace level 4’;
Session altered.

2. Executar instrução sql
SQL> select 1 from dual;

1
———-
1
SQL>

3. Desligue o rastreamento em nível de sessão

SQL> alter session set events ‘sql_trace off’;
Session altered.

4. Rastreamentos gerados são armazenados no diretório

<diagnostic_dest>\rdbms\<database name>\<instance name>\trace

onde:

4.1 – <diagnostic_dest> é o  parâmetro de inicialização  DIAGNOSTIC_DEST do banco de dados aonde está definido o  diretório de diagnóstico.
Para descobrir a localização de parâmetro DIAGNOSTIC_DEST podemos executar a query abaixo:

SQL> select name, value from v$parameter where name like ‘diagnostic_dest’;   

NAME                      VALUE
————————- ———————————–
diagnostic_dest           /u01/app/oracle

4.2 – <database_name> – nome do banco de dados

SQL> select name from v$database;

NAME
————————-
ORCL

Então,os arquivos traces serão gerados no diretório:

/u01/app/oracle/diag/rdbms/orcl/orcl/trace

OBS: O valor em negrito acima, está relacionado com o servidor de banco de dados  que estou usando para fazer os testes.  Dependendo do local de instalação e do sistema operacional (windows, Linux, etc)  do binário do Oracle esse valor  será diferente do valor que esta em negrito acima.

Normalmente, com o banco de dados em atividade, são gerados vários arquivos traces nesse diretório e, para identificar o arquivo trace que geramos devemos descobrir o processo de servidor dedicado da sessão rastreada.
Lembre-se,  a consulta deve ser feita na mesma sessão em que o trace esta sendo efetuado.

SQL> select spid from v$process
where addr in (select paddr from v$session
               where sid=sys_context(‘USERENV’, ‘SID’));

SPID
————
5347

Nome do arquivo de rastreamento é gerado como:

<instance_name>_ora_<process_id>.trc

onde:

<instance_name> – nome de instância
<process_id>    – id do processo de servidor dedicado para sessão

então o nome do arquivo é:

orcl_ora_5347.trc

Verificando localmente no servidor oracle (neste caso o servidor  é o servidor aonde fiz os testes)

-rw-r—– 1 oracle oinstall 269077 Jun 22 06:13 alert_orcl.log
-rw-r—– 1 oracle oinstall     68 Jun 22 07:00 orcl_j000_6610.trm
-rw-r—– 1 oracle oinstall    968 Jun 22 07:00 orcl_j000_6610.trc
-rw-r—– 1 oracle oinstall    133 Jun 22 08:35 orcl_ora_5347.trm
-rw-r—– 1 oracle oinstall   4624 Jun 22 08:36 orcl_ora_5347.trc

Se executarmos novamente o rastreamento, é preciso lembrar que cada interação irá substituir o conteúdo do arquivo trace.

Para evitar isso, você pode usar o parâmetro tracefile_identifier.
Este parâmetro adicionará a variável do parâmetro tracefile_identifier ao nome do arquivo.

Outros parâmetros que podem ser usados durante o trace:

TIMED_STATISTICS – Especifica se as estatísticas relacionadas ao tempo são coletados ou não. Este parâmetro é verdadeiro quando o parâmetro de inicialização statistic_level está definido como TYPICAL ou ALL
STATISTICS_LEVEL – Especifica o nível de coleta de estatísticas do banco de dados e do sistema operacional.  A visão V$STATISTICS_LEVEL pode mostrar o que esse parâmetro controla.
MAX_DUMP_FILE_SIZE – define o tamanho máximo do arquivo trace gerado.

exemplo:

SQL> alter session set tracefile_identifier=’teste_trace’;
Session altered.

SQL> alter session set timed_statistics = true;
Session altered.

SQL> alter session set statistics_level = all;
Session altered.

SQL> alter session set max_dump_file_size = unlimited;
Session altered.

SQL> alter session set events ‘sql_trace level 4’;
Session altered.

SQL> select count(*) from user_tables;

COUNT(*)
———-
987

SQL> select count(*) from dba_tables;

COUNT(*)
———-
2970

SQL> alter session set events ‘sql_trace off’;

Session altered.

5. Encontrar a instrução sql rastreada. Você pode usar a exibição V$SQL

SQL> select sql_text, sql_id from v$sql
where sql_text=’select count(*) from dba_tables’;

SQL_TEXT                                                    SQL_ID
———————————-                     ————-
select count(*) from dba_tables        56bs32ukywdsq

6. Executando mais alguns passos,  as informações geradas no arquivo trace são armazenadas para o sql rastreado.

SQL> alter session set tracefile_identifier=’sql_trace_teste’;
Session altered.

SQL> alter session set events ‘sql_trace [sql:56bs32ukywdsq] level 4’;
Session altered.

SQL> select 1 from dual;

1
———-
1

SQL> select count(*) from user_tables;
COUNT(*)
———-
987

SQL> select count(*) from dba_tables;
COUNT(*)
———-
2970

SQL> alter session set events ‘sql_trace off’;
Session altered.

Verificando os arquivos gerados no servidor oracle:

-rw-r—– 1 oracle oinstall    125 Jun 22 10:49 orcl_ora_11951_teste_trace.trm
-rw-r—– 1 oracle oinstall    756 Jun 22 11:00 orcl_mmon_5213.trm
-rw-r—– 1 oracle oinstall   7992 Jun 22 11:00 orcl_mmon_5213.trc
-rw-r—– 1 oracle oinstall   9156 Jun 22 11:00 orcl_ora_11951_teste_trace.trc
-rw-r—– 1 oracle oinstall     83 Jun 22 11:00 orcl_ora_11951_sql_trace_teste.trm
-rw-r—– 1 oracle oinstall   4423 Jun 22 11:00 orcl_ora_11951_sql_trace_teste.trc

Nos próximos post, veremos  como rastrear uma sessão usando dbms_trace e  também o uso do TKPROF.

Um abraço

Convertendo uma coluna Varchar2 para BLOB e CLOB

Neste post mostrarei como converter uma coluna do tipo Varchar2 para uma coluna do tipo LOB (BLOB ou CLOB)

Para converter uma coluna de tabela de varchar2 para blob ou clob faça o seguinte:

1 – VARCHAR2 -> BLOB

1.1 – Criando uma tabela de teste

SQL> create table teste (col1 varchar2 (1000));
Table created.

    1.2 – Inserindo dados a tabela

SQL> insert into teste select table_name from user_tables;
9 rows created.

SQL> commit;
Commit complete.

1.3 – Verificando os dados na tabela

SQL> SELECT * FROM teste;

COL1
———————————
CUSTKEYS
PACKAGECLIS
TESTE
CC_PARAMS
CUSTCLIS
CUSTACCOUNTS
PACKAGESLOTS
CALLPACKAGES
DIALCODES

9 rows selected.

 1.4 – Adicionando uma coluna do tipo lob na tabela(BLOB)

SQL> alter table teste add blob_col blob;
Table altered.

1.5 – Verificando a estrutura da tabela

SQL> desc teste
Name                                      Null?    Type
—————————————– ——– —————————-
COL1                                               VARCHAR2(1000)
BLOB_COL                                           BLOB

 1.6 – Inserindo dados a coluna tipo lob

SQL> update teste set blob_col = utl_raw.cast_to_raw(COL1);
9 rows updated.

commit;

1.7 – Verificando os dados na tabela

SQL>  SELECT * FROM teste;

COL1         BLOB_COL
———— ——————————
CUSTKEYS     435553544B455953
PACKAGECLIS  5041434B414745434C4953
TESTE        5445535445
CC_PARAMS    43435F504152414D53
CUSTCLIS     43555354434C4953
CUSTACCOUNTS 435553544143434F554E5453
PACKAGESLOTS 5041434B414745534C4F5453
CALLPACKAGES 43414C4C5041434B41474553
DIALCODES    4449414C434F444553

9 rows selected.

 1.8 – excluindo a coluna do tipo varchar2

SQL> alter table teste drop column col1 ;
Table altered.

 1.9 – Renomeando a coluna do tipo lob para COL1

SQL> alter table teste rename column blob_col to col1;
Table altered.

1.10 – Verificando a estrutura da tabela

SQL> desc  teste
Name                Null?    Type
——————- ——– ————–
COL1                         BLOB

 1.11 – Verificando os dados na tabela

SQL> select utl_raw.cast_to_varchar2(col1) from teste;

UTL_RAW.CAST_TO_VARCHAR2(COL1)
——————————–
CUSTKEYS
PACKAGECLIS
TESTE
CC_PARAMS
CUSTCLIS
CUSTACCOUNTS
PACKAGESLOTS
CALLPACKAGES
DIALCODES

9 rows selected.

Podemos observar que os dados são os mesmos exibidos no ítem 1.3 deste artigo

2 – VARCHAR2 -> CLOB

2.1 – Criando uma tabela de teste

SQL> create table teste1
(col1 varchar2 (1000));  2

Table created.

2.2 – Inserindo dados a tabela

SQL> insert into teste1 select table_name from user_tables where rownum <5;
4 rows created.

SQL> commit;
Commit complete.

2.3 – Verificando os dados na tabela

SQL> SELECT * FROM teste1;

COL1
————
CUSTKEYS
PACKAGECLIS
TESTE1
T

 2.4 – Adicionando uma coluna do tipo lob na tabela(CLOB)

SQL> alter table teste1 add clob_col clob;
Table altered.

2.5 Verificando a estrutura da tabela

SQL> desc teste1
Name                Null?    Type
——————- ——– ——————
COL1                         VARCHAR2(1000)
CLOB_COL                     CLOB

2.6 – Inserindo dados a coluna tipo LOB

SQL> update teste1 set clob_col = COL1;
4 rows updated.

SQL> commit ;
Commit complete.

2.7 – Verificando os dados na tabela

SQL>  select * from teste1 ;

COL1                 CLOB_COL
——————– ——————–
CUSTKEYS             CUSTKEYS
PACKAGECLIS          PACKAGECLIS
TESTE1               TESTE1
T                    T

2.8 – Excluindo a coluna do tipo varchar2

SQL> alter table teste1 drop column COL1;

Table altered.

2.9 – Renomeando a coluna do tipo lob para COL1

SQL>  alter table teste1 rename column CLOB_COL to COL1;

Table altered.

    2.10 – Verificando a estrutura da tabela

SQL> desc teste1
Name                Null?    Type
——————- ——– ——————
COL1                         CLOB

    2.11 – Verificando os dados na tabela

SQL>  select * from teste1;

COL1
——————–
CUSTKEYS
PACKAGECLIS
TESTE1
T

Podemos observar que os dados são os mesmos exibidos no ítem 2.3 deste artigo

Um abraço;

Obtendo DDL com DBMS_METADATA

Existem vários métodos disponíveis para extrair o DDL num banco de dados Oracle. Nesse post abordaremos o uso do pacote DBMS_METADATA.
A package DBMS_METADATA fornece uma maneira de recuperar metadados a partir do dicionário de dados como XML ou DDL.  Podemos recuperar um determinado tipo de objeto, por exemplo, uma tabela, índice ou procedure, etc.
A package DBMS_METADATA tem 11 procedures, cada uma adaptada a uma função específica.
Todas essas onze procedures permitem critérios de seleção flexíveis e extração de grupos de objetos:

1. Get_xml
2. GET_DDL
3. OPEN,
4. SET_FILTER
5. SET_COUNT
6. GET_QUERY
7. SET_PARSE_ITEM
8. ADD_TRANSFORM
9. SET_TRANSFORM_PARAM
10. FETCH_XXX
11. CLOSE
Abaixo estaremos vendo alguns exemplo de obtenção de algumas DDL:

1 – usando a package DBMS_METADATA.GET_DDL.

set pagesize 0
set long 300000  
col OBJECT_NAME format a20

SQL> select object_type,object_name from dba_objects where owner=’SCOTT’;

OBJECT_TYPE             OBJECT_NAME
———————– ——————–
TABLE                   SALGRADE
TABLE                   BONUS
INDEX                   PK_EMP
TABLE                   EMP
INDEX                   PK_DEPT
TABLE                   DEPT

 6 rows selected.

2 – Obtendo o script da tabela DEPT

SQL> set 120
SQL> set long 30000
SQL> SELECT DBMS_METADATA.GET_DDL (‘TABLE’,’DEPT’,’SCOTT’) from dual;

DBMS_METADATA.GET_DDL(‘TABLE’,’DEPT’,’SCOTT’)
——————————————————————————–
CREATE TABLE “SCOTT”.”DEPT”
   (   “DEPTNO” NUMBER(2,0),
       “DNAME” VARCHAR2(14),
       “LOC” VARCHAR2(13),
         CONSTRAINT “PK_DEPT” PRIMARY KEY (“DEPTNO”)
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
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 “USERS” ENABLE
) SEGMENT CREATION IMMEDIATE
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 “USERS”

3 – Obtendo o script do incice PK_DEPT

SQL> SELECT DBMS_METADATA.GET_DDL (‘INDEX’,’PK_DEPT’,’SCOTT’) from dual;

 DBMS_METADATA.GET_DDL(‘INDEX’,’PK_DEPT’,’SCOTT’)
——————————————————————————–
CREATE UNIQUE INDEX “SCOTT”.”PK_DEPT” ON “SCOTT”.”DEPT” (“DEPTNO”)
PCTFREE 10 INITRANS 2 MAXTRANS 255
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 “USERS”

4 – Obtendo o script da tablespace users 

SQL> SELECT DBMS_METADATA.GET_DDL (‘TABLESPACE’, ‘USERS’) FROM dual;

DBMS_METADATA.GET_DDL(‘TABLESPACE’,’USERS’)
——————————————————————————–
CREATE TABLESPACE “USERS” DATAFILE
‘/u01/app/oracle/oradata/rdba/users01.dbf’ SIZE 5242880
AUTOEXTEND ON NEXT 1310720 MAXSIZE 32767M
LOGGING ONLINE PERMANENT BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL AUTOALLOCATE DEFAULT
NOCOMPRESS SEGMENT SPACE MANAGEMENT AUTO

5 – Obtendo o script das permissões do usuário SCOTT

SQL> SELECT DBMS_METADATA.GET_GRANTED_DDL (‘ROLE_GRANT’, ‘SCOTT’) from dual;

DBMS_METADATA.GET_GRANTED_DDL(‘ROLE_GRANT’,’SCOTT’)
——————————————————————————–
GRANT “CONNECT” TO “SCOTT”
GRANT “RESOURCE” TO “SCOTT”

6 – Obtendo o script das referencias da tabela EMP

SQL> SELECT DBMS_METADATA.GET_DEPENDENT_DDL (‘REF_CONSTRAINT’,’EMP’,’SCOTT’) from dual;

DBMS_METADATA.GET_DEPENDENT_DDL(‘REF_CONSTRAINT’,’EMP’,’SCOTT’)
——————————————————————————–
ALTER TABLE “SCOTT”.”EMP” ADD CONSTRAINT “FK_DEPTNO” FOREIGN KEY (“DEPTNO”)
REFERENCES “SCOTT”.”DEPT” (“DEPTNO”) ENABLE

Conforme dito acima, existem muitas ferramentas de mercado que fazem extração de código (TOAD, PLSQL DEVELOPER, SQLDEVELOPER, EMBARCADERO, ENTERPRISE MANAGER),
além do DATA PUMP da própria ORACLE que extrai a DDL com o uso da opção metadata.
Podemos ver que o uso do DBMS_METADATA  pode ser uma excelente opção que merece ser avaliada e utilizada nas atividades diárias do dba ou desenvolvedor.

Segue abaixo o link com a documentação do Oracle 11g da package DBMS_METADATA, para melhor compreensão e estudo do assunto deste post:
http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_metada.htm#ARPLS026