Arquivo da categoria: Uncategorized

Hint – IGNORE_ROW_ON_DUPKEY_INDEX

Ola!! Depois de algum tempo sem publicar, estou colocando um novo post.
Encontrei um hint muito interessante, que fornece uma abordagem alternativa ao inserir dados onde valores duplicados podem vir a ser um problema.

Nas versões mais antigas do Oracle, eram usados em uma rotina PL/SQL, além de manipuladores de exceção ou instruções SQL que impediam a duplicação.
Como o Oracle 10g, o problema podia ser combatido com uma instrução MERGE,
embora o MERGE existisse desde a versão 9i, ele ainda precisava lidar com WHEN MATCHED e WHEN NOT MATCHED, o que em muitas aplicações isso não é viável.

O Oracle na versão 11.2.0.1 possui um recurso que permite silenciosamente inserir SQL para aceitar linhas duplicadas com o hint ignore_row_on_dupkey_index .
Quando hint ignore_row_on_dupkey_index é usado em uma instrução insert numa tabela com um índice de chave exclusivo, quaisquer linhas duplicadas serão silenciosamente ignoradas, em vez de causar o tradicional erro, ORA-00001 unique constraint violated .

Abaixo farei um cenário para testes, onde mostraremos o uso de hint ignore_row_on_dupkey_index :

I – USO DO HINT

Neste Cenário de testes, usarei uma tabela com 15 linhas com um índice de chave exclusiva, aonde tentarei inserir novas linhas a fim de ilustrar o uso do hint.

1 – Criando uma tabela de testes

postdezembro1

2 – Verificar índice único criado

postdezembro2

3 – Adicionar linhas a tabela

postdezembro3

4 – Verificar as linhas adicionadas na tabela

postdezembro4

5 – Adicionar linhas com valores duplicados

postdezembro5

Obs: Obviamente recebemos um erro de violação de restrição exclusiva e não ocorreu inserção na tabela.

Neste momento usarei o hint IGNORE_ROW_ON_DUPKEY_INDEX para adicionar linhas a tabela de testes, mesmo com registros duplicados. Assim poderemos verificar que o uso do hint IGNORE_ROW_ON_DUPKEY_INDEX , lidará silenciosamente com os erros de violação exclusivas de restrição, simplesmente ignorando e não inserindo nenhuma linha na qual os valores exclusivos já existam na tabela.

6 – Inserindo linha usando hint IGNORE_ROW_ON_DUPKEY_INDEX

postdezembro6

Observe que os 15 valores duplicados (1 – 15) foram ignorados e não foram inseridos na tabela, mas os valores 16 a 20 que não existiam anteriormente foram inseridos com êxito na tabela.

postdezembro7

No próximo exemplo, tentaremos inserir os valores de 1 a 21 na tabela, embora atualmente os valores entre 1 a 20 já existam. Desta vez, usaremos um segundo formato da usando o hint que nos permite estipular a coluna que contém valores exclusivos que devem ser ignorados se já existirem:

postdezembro8
Note que na figura abaixo, os valores entre 1 e 20 foram silenciosamente ignorados com apenas o valor 21 inserido desta vez na tabela.

postdezembro9

II – RESTRIÇÕES

O hint IGNORE_ROW_ON_DUPKEY_INDEX não pode ser usado dentro de uma instrução UPDATE.

postdezembro10

OBS: Uma diferença interessante no comportamento deste hint. Geralmente, os hints “inválidos” são apenas ignorados e tratados como comentários, mas para este hint, se uma operação ilegal for tentada, um erro ocorre.

Abaixo repetiremos os testes, mas dessa vez criaremos uma tabela sem chave primária por meio de um índice não-exclusivo.

postdezembro11

Observe novamente que um erro será invocado aqui, bem como verificaremos que esse hint só pode ser aplicado por meio de uma restrição policiada por um índice exclusivo. Um índice não exclusivo, mesmo com uma restrição Unique ou PK em vigor, não é suficiente e gerará o erro abaixo:

postdezembro12

Atualmente, apesar da conveniência associada ao uso do hint IGNORE_ROW_ON_DUPKEY_INDEX, há também outras limitações. Portanto, o índice fornecido no hint deve existir. Caso contrário o hint não é ignorada como de costume, mas um erro ocorrerá. Além disso, os INSERTs que usam a este hint não podem se beneficiar de Paralelismo, Direct Path ou NOLOGGING.

CONCLUSÃO

É claramente muito mais eficiente evitar inserir linhas duplicadas do que inseri-las e manipular a exceção ou usar o hint IGNORE_ROW_ON_DUPKEY_INDEX. Portanto, ainda é muito mais eficiente evitar inserir linhas duplicadas em primeiro lugar. Caso isso não seja possível, use o hint IGNORE_ROW_ON_DUPKEY_INDEX, mas leve em consideração as restrições acima citadas.

EXTERNAL TABLES

Esse post mostra um conceito básico de tabelas externas. Uma External Table é uma funcionalidade presente em uma serie de SGBDs, cada um com o seu nome e sintaxe próprias. As tabelas externas, estão disponíveis desde a versão Oracle9i. Uma tabela externa nada mais é do que uma tabela criada no banco de dados, cuja sua origem de dados está vinculada a um arquivo de texto, eliminando imediatamente a necessidade de carregar arquivos de texto em tabelas intermediárias visando economia no processamento de tempo e em espaço de armazenamento.

As tabelas externas são muito utilizadas em ambientes de data warehouse, extração, transformação e carregamento (ETL), no qual, esses processos podem ler o arquivo de texto de uma tabela externa direta e posteriormente carregar os dados em tabelas de resumo. Conforme dito acima, os processos ETL elimina a etapa de carregar os arquivos de texto em armazenamento intermediário, economizando espaço e tempo significativo, ou seja , isto é feito atraves da utilizaçao de arquivos “FLAT FILES” e Tabelas Relacionais sem a necessidade de uma ferramenta específica de ETL.

Quando criamos uma tabela simples no banco de dados Oracle podemos utilizar as instruções DML (ex. INSERT, UPDATE, DELETE) para manipular as informações. Uma conseqüência disso é que você não pode criar um índice em uma tabela externa.

Abaixo veremos como criar tabela externas em ambiente de banco de dados Oracle.Para esse teste o ambiente utilizado é linux com banco de dados Oracle 11g R2.

1 – Criar um diretório no sistema operacional

Como os dados de uma tabela externa está no sistema operacional, o arquivo de dados precisa estar em um lugar aonde o Oracle pode acessá-lo. Então o primeiro passo é criar um diretório e conceder acesso a ele. Primeiro, crie o diretório no sistema operacional ou escolha um diretório existente. Ele deve ser um diretório real, não um link simbólico. Certifique se o acesso de leitura e escrita do usuário oracle estão com as devidas permissões neste diretório.

No sistema operacional foi criado uma pasta chamada post no diretório /home/oracle.

[oracle@localhost]$ mkdir -p /home/oracle/post

[oracle@ localhost ]$ ls -l *

total 17520
-rw-rw-r– 1 oracle oracle       68 Jul 25 18:09 afiedt.buf
drwxr-xr-x 4 oracle oracle     4096 Jun 1 2013 ap
drwxrwxr-x 5 oracle oracle     4096 Jun 12 14:05 backup
drwxrwxr-x 3 oracle oracle     4096 Dez 5 2011 oradiag_oracle
drwxrwxr-x 2 oracle oracle     4096 Jul 27 14:57 post
drwxrwxr-x 2 oracle oracle     4096 Jun 12 14:38 scripts
-rw-rw-r– 1 oracle oracle     1750 Dez 7 2013 Untitled.sql

2 – Criar um diretório no banco de dados Oracle

As tabelas externas usam diretórios do Oracle. Um diretório Oracle é uma referência interna no dicionário de dados. Um diretório   mapeia um nome de diretório exclusivo para um diretório físico no sistema operacional local.

Para criar um diretório no banco de dados, é necessário ter acesso SYSDBA. O “diretório” será uma pasta mapeada em seu servidor, onde, haverá uma vinculo direto com o banco de dados e será possível determinar privilégios de acesso a determinados usuários/schemas. Antes de criar um diretório de banco de dados, é necessário criar uma pasta fisicamente no servidor. Conforme citado acima o diretório sera criado em ‘/home/oracle/post’.

SQL> create directory external as ‘/home/oracle/post’;

Directory created.

SQL> grant read, write on directory external to hr;

Grant succeeded.

3 – Criando uma tabela externa

A última etapa de preparação para criação de uma tabela externa exige que um arquivo de texto simples seja criado no diretório físico criado no S.O. e no banco de dados respectivamente.

           3.1 – Criando um arquivo texto

No diretório ‘/home/oracle/post’ foi criado um arquivo texto chamado empregado.csv. Segue abaixo o conteudo deste arquivo que usaremos para testes.

[oracle@localhost post]$ cat empregado.csv

001,Hutt,Jabba,jabba@thecompany.com
002,Simpson,Homer,homer@thecompany.co
03,Kent,Clark,superman@thecompany.com
004,Kid,Billy,billythkid@thecompany.com
005,Stranger,Perfect,nobody@thecompany.com
006,Zoidberg,Dr,crustacean@thecompany.com
007,Lane,Lois,loislane@thecompany.com
008,Bane,David,hulk@thecompany.com
009,Stark,Tony,ironman@thecompany.com
010,House,Gregory,drhouse@thecompany.com
011,Wayne,Bruce,batman@thecompany.com
012,Park,Peter,spiderman@thecompany.com

[oracle@localhost post]$

3.2 – Criando uma tabela externa

A sintaxe para criação de uma tabela externa é muito parecida com a sintaxe de criação de uma tabela normal. A primeira parte é como um CREATE TABLE normal, tem o nome da tabela e das colunas. Depois é seguido por um bloco de sintaxe específica para tabelas externas, o que permite que você informe o Oracle como interpretar os dados no arquivo externo.

A cláusula DEFAULT DIRECTORY, especifica o diretório padrão a ser usado para todos os arquivos de entrada e saída.

A cláusula LOCATION, lista todos os arquivos de dados para a tabela externa.

A cláusula ACCESS PARAMETERS é onde os arquivos de saída são nomeados.

SQL> connect hr/hr

Connected.

SQL> create table empregados

2   ( emp_id varchar2(3),

3   last_name varchar2(50),

4   first_name varchar2(50),

5   email varchar2(100)

6 )

7   organization external

8   ( default directory external

9   access parameters

10   ( records delimited by newline

11   fields terminated by ‘,’

12 )

13   location (‘empregado.csv’)

14 );

Table created.

Apos criada a tabela, vamos conferir os dados criados:

SQL> select count(*) from empregados;

COUNT(*)

———-

12

SQL> select * from empregados;

EMP LAST_NAME FIRST_NAME EMAIL

— ———- ———- ——————————

001 Hutt       Jabba     jabba@thecompany.com

002 Simpson   Homer     homer@thecompany.com

003 Kent       Clark     superman@thecompany.com

004 Kid       Billy     billythkid@thecompany.com

005 Stranger   Perfect   nobody@thecompany.com

006 Zoidberg   Dr         crustacean@thecompany.com

007 Lane       Lois       loislane@thecompany.com

008 Bane       David     hulk@thecompany.com

009 Stark     Tony       ironman@thecompany.com

010 House     Gregory   drhouse@thecompany.com

011 Wayne     Bruce     batman@thecompany.com

012 Parker       Peter     spiderman@thecompany.com

12 rows selected.

SQL>

Conforme falamos acima, uma tabela externa não aceita comandos DML, ela deve ser feita somente no arquivo texto. Caso tente realizar essas alterações utilizando DMLs, o resultado será:

SQL> insert into empregados values

2 (‘013′,’Steven’,’Rogers’,’capitaoamerica@thecompany.com’)

SQL> /

insert into empregados values

*

ERROR at line 1:

ORA-30657: operation not supported on external organized table

como vimos acima, a operação apresentou o erro ORACLE ORA-30657.

3.3 – Alterando uma tabela externa

Você pode usar o commando ALTER TABLE para alterar os parâmetros de acesso sem dropa-la e redefinir a tabela inteira:

SQL> alter table empregados

2       access parameters

3             ( records delimited by newline

4               badfile ‘empregado.bad’

5               logfile ‘empregado.log’

6               discardfile ‘empregado.dsc’

7             fields terminated by ‘,’

8           )

SQL> /

Table altered.

SQL>

3.4 – Visualizando o dicionários de dados

Os metadados são armazenadas em duas visões, chamadas USER_EXTERNAL_TABLES e USER_EXTERNAL_LOCATIONS (que, naturalmente, podem ser vistas nas visões ALL_ ou DBA_). O diretório virtual é armazenada na visão USER_EXTERNAL_TABLES, enquanto o nome do arquivo físico é armazenado na exibição USER_EXTERNAL_LOCATIONS.

3.4.1 – Consultando a visão USER_EXTERNAL_LOCATIONS

SQL> select * from user_external_locations where table_name = ‘EMPREGADOS’;

TABLE_NAME   LOCATION             DIR DIRECTORY_NAME

———— ——————– — ——————————

EMPREGADOS   empregado.csv       SYS EXTERNAL

3.4.2 – Consultando a visão USER_EXTERNAL_TABLES

SQL>select * from user_external_tables where table_name = ‘EMPREGADOS’;

TABLE_NAME   TYP TYPE_NAME       DEF DEFAULT_DIRECTORY_NAME         REJECT_LIMIT ACCESS_

———— — ————— — —————————— ————- ——-

ACCESS_PARAMETERS                                                               PROPERTY

——————————————————————————– ———-

EMPREGADOS   SYS ORACLE_LOADER   SYS EXTERNAL                      0           CLOB

records delimited by newline                                                   ALL

badfile ‘empregado.bad’

4 – Criando tabela externa apartir de tabela do banco de dados

O Oracle permite criar uma nova tabela externa a partir de dados em outras tabelas em seu banco de dados, que entra por um FLAT FILE  usando o driver de acesso ORACLE_DATAPUMP. Este FLAT FILE  está em um formato proprietário da Oracle que pode ser lido por DataPump. A sintaxe é semelhante a sintaxe CREATE TABLE … ORGANIZATION EXTERNAL acima, porém mais simples, uma vez que não é possível especificar o formato de dados, você pode especificar alguns parametros de acesso. A principal diferença é que você deve especificar o driver de acesso, ORACLE_DATAPUMP, desde que o driver de acesso predefinido para ORACLE_LOADER.

Vamos aos testes:

SQL> create table export_teste

2      organization external

3      ( type oracle_datapump

4        default directory external

5       location (‘teste.dmp’)

6    ) as select * from employees;

Table created.

SQL>

Depois de criada a tabela vamos verificar os dados:

SQL> select count(*) from export_teste;

COUNT(*)

———-

107

SQL> select * from export_teste where rownum < 5;

EMPLOYEE_ID FIRST_NAME LAST_NAME  EMAIL        PHONE_NUMBER HIRE_DATE JOB_ID        SALARY

———– ———- ———- ———— ———— ——— ———- ———-

COMMISSION_PCT MANAGER_ID DEPARTMENT_ID

————– ———- ————-

198 Donald    OConnell   DOCONNEL  650.507.9833 21-JUN-07 SH_CLERK  2600 124   50

199 Douglas    Grant   DGRANT  650.507.9844 13-JAN-08 SH_CLERK  2600 124   50

200 Jennifer   Whalen     JWHALEN      515.123.4444 17-SEP-03 AD_ASST   4400  101   10

201 Michael    Hartstein  MHARTSTE     515.123.5555 17-FEB-04 MK_MAN  13000  100   20

CONCLUSÃO

Nós vimos acima uma introdução de carga  de dados usando tabelas externas. As tabelas externas  fornecem uma maneira conveniente de mover dados para dentro e fora do banco de dados, com integração do SQLLoader, agregando funcionalidade do Data Pump e a facilidade no uso de instruções SQL.  Definitivamente vale a pena considerar o uso de tabelas externas na tarefa de carregar dados ao banco. Segue abaixo o link da documentação da ORACLE para melhor compreensão do assunto.

LINK LINK2

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!!

 

 

ORACLE 12C – Colunas Identity – Parte 2

No último post, começamos a falar sobre colunas Identity, uma nova funcionalidade do Oracle 12c, no post de hoje estaremos continuando e concluindo sobre este tema.

4 – Criação de uma tabela com a cláusula By Default com restrição Not Null.

Esta definição de uma coluna, permite a utilização de valores externos e gera
valores  quando se insere um valor null a uma  coluna criada com a cláusula By Default Not Null;

SQL> Create Table  teste.Identity_Default_Not_Null_1
(Col_1  Number Generated By Default On Null As Identity,
Col_2 Varchar2(50));  2    3

Table created.
SQL>

SQL> Insert Into  teste.Identity_Default_Not_Null_1
Values  (Null,’Prova’);   2

1 row created.
SQL>

SQL>   Select * From  teste.Identity_Default_Not_Null_1;

COL_1 COL_2
———- ————————————————–
1 Prova

SQL>

Como podemos ver neste caso,um erro não é gerado pelo insert como no ultimo exemplo do post anterior.  Esta cláusula  gera valores para a coluna pare que esta não contenha valores nulos, sem levar em consideração que os valores de entrada sejam consecutivos.

5 – Opções sobre o uso da cláusula Identity

O exemplo abaixo mostra como criar uma Tabela  com a cláusula Identity com um valor inicial de 100 e com um incremento de 10.

SQL> Create Table  teste.Identity_Start_Increment
( Col_1 Number Generated Always As Identity  (Start With 100
Increment By 10),   Col_2 Varchar2(50));
2    3
Table created.

SQL>

Realizamos un Insert de 10 registros

SQL> Insert Into  teste.Identity_Start_Increment (Col_2)
Select Level||’ Numero’
From Dual
Connect by level<=10;  2    3    4

10 rows created.
SQL>

Vemos o resultado da cláusula Insert

SQL>  Select *  From  teste.Identity_Start_Increment;

COL_1 COL_2
———- ————————————————–
100 1 Numero
110 2 Numero
120 3 Numero
130 4 Numero
140 5 Numero
150 6 Numero
160 7 Numero
170 8 Numero
180 9 Numero
190 10 Numero

10 rows selected.

SQL>

Como mostrado o valor da coluna col_1 começa em 100 e vai aumentando em 10.

Verificando as colunas IDENTITY

SQL>  Select Table_Name, Column_Name,Data_Default From Dba_Tab_Columns
Where  Table_Name=’IDENTITY_DEFAULT_NOT_NULL_1′;

TABLE_NAME                     COLUMN_NAME          DATA_DEFAULT
—————————— ——————– ——————————
IDENTITY_DEFAULT_NOT_NULL_1    COL_2
IDENTITY_DEFAULT_NOT_NULL_1    COL_1                “TESTE”.”ISEQ$$_92301″.nextval

SQL>

SQL> Select  Last_Number, Increment_By, Cache_Size,  Max_Value
From  dba_Sequences
Where  Sequence_Name=’ISEQ$$_92301′;  2    3

LAST_NUMBER INCREMENT_BY CACHE_SIZE  MAX_VALUE
———– ———— ———- ———-
21            1         20 1.0000E+28
SQL>

6 – deletando tabelas com coluna Identity

6.1 – deletando uma tabela com uma coluna Identity a sequencia não é deletada.

drop table teste.IDENTITY_DEFAULT_NOT_NULL_1;

Table dropped.

SQL> Select  Last_Number, Increment_By, Cache_Size,  Max_Value
From  dba_Sequences
Where  Sequence_Name=’ISEQ$$_92301′;  2    3

LAST_NUMBER INCREMENT_BY CACHE_SIZE  MAX_VALUE
———– ———— ———- ———-
21            1         20 1.0000E+28
SQL>

6.2 – Restaurando a tabela e dropando a mesma com a opção purge

SQL> FLASHBACK TABLE  teste.IDENTITY_DEFAULT_NOT_NULL_1 to before drop;

Flashback complete.

SQL> SQL> desc  teste.IDENTITY_DEFAULT_NOT_NULL_1
Name                                      Null?    Type
—————————————– ——– —————————-
COL_1                                     NOT NULL NUMBER
COL_2                                              VARCHAR2(50)
SQL>

SQL> drop table teste.IDENTITY_DEFAULT_NOT_NULL_1 purge;

Table dropped.

SQL> Select  Last_Number, Increment_By, Cache_Size,  Max_Value
From  dba_Sequences
Where  Sequence_Name=’ISEQ$$_92301′;  2    3

no rows selected
SQL>

Colocando a cláusula purge a sequencia também é deletada.

7 – Comparando tempo de resposta entre insert com colunas Identity e uso de sequences

Agora iremos mostrar o tempo de resposta da cláusula Identity.  Vamos inserir 100.000 registros numa tabela, vamos tomar o tempo cada um:

7.1 –  carregando uma tabela com campo de Identity Allways.

SQL> Create Table  teste.Identity
( Col_1 Number Generated Always As Identity, Col_2 Varchar2(50));  2

Table created.

SQL> Set Timing On
Insert Into teste.Identity   (Col_2)
Select ‘Numero de registro ‘|| Level
From Dual
Connect By  Level<=100000;SQL>   2    3    4

100000 rows created.

Elapsed: 00:00:01.96
SQL>

7.2 – uma nova carga em uma tabela com a coluna definida com By Default

SQL> Insert Into teste.Identity_Default  (Col_2)
Select ‘Numero de registro ‘|| Level
From Dual
Connect By Level<=100000;  2    3    4

100000 rows created.

Elapsed: 00:00:01.76
SQL>

7.3 – Comparando  o tempo de resposta durante a inserção de uma tabela com a opção allways e outra BY DEFAULT ON NULL

Primeiro carregar uma tabela com campo de Identity Allways.

SQL> Insert Into teste.Identity   (Col_2)
Select ‘Numero de registro ‘|| Level
From Dual
Connect By  Level<=100000;  2    3    4

100000 rows created.

Elapsed: 00:00:01.69
SQL>

7.4 –  Carregar uma tabela com uma coluna definida por By Default On Null

SQL>  Create Table  teste.Identity_Default_On_Null
2  (Col_1  Number Generated By Default On Null As Identity, Col_2 Varchar2(50));

Table created.
SQL>

SQL> Insert Into  teste.Identity_Default_On_Null (Col_2)
Select ‘Numero de registro ‘|| Level
From Dual
Connect By  Level<=100000;  2    3    4

100000 rows created.

Elapsed: 00:00:02.01
SQL>

Por ultimo utilizaremos o velho método, já utilizado antes da versão 12c
7.5 – Criando uma tabela sem colunas Identitity e uma sequence para avaliamos o tempo.

SQL> Create Table  teste.Tabela_com_sequence (Col_1 Number,
Col_2 Varchar2(50 Char));  2

Table created.
SQL>

agora vamos criar uma sequencia

SQL>  Create Sequence  teste.Seq_teste
2  Start With 1 Increment By 1;

Sequence created.
SQL>

Agora vamos inserir registros nessa tabela

SQL> Insert Into teste.Tabela_com_sequence
Select  teste.Seq_teste.nextval, ‘Numero de registro ‘|| Level
From Dual
Connect By  Level<=100000;
2    3    4
100000 rows created.

Elapsed: 00:00:01.83
SQL>

8 – Alguns pontos devem  ser observados:

8.1 – Dado uma coluna definida como Identity está vinculada a uma sequencia,no caso de uma instrução insert for abortada, os números da sequência serão perdidos.

8.2 – Caso uma tabela seja exportada com todos os seus valores, devemos observar que a coluna de identity esteja em by default, porque de outra forma teremos um erro.

Conclusão

A inclusão de colunas de Identity é um avanço importante, já que a mesma encapsula a instrução nextval de uma sequência.
Por outro lado, a inclusão de opções,  By Default e By Default On Null, permitem que os valores a serem inseridos possam  ser internos ou externos.
A coisa mais importante neste post  é que demonstramos isso sem quase perder desempenho.

bibliografia

ORACLE-BASE
ASK-TOM                                                                                                                                                             ORACLE Documentation