Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

12c colunas de IDENTIDADE


Eu moro e trabalho perto de uma instalação da Microsoft. Como tal, muitos de nossos funcionários atuais são ex-funcionários da Microsoft com experiência em SQL Server. O SQL Server permite criar uma tabela com uma coluna IDENTITY. O Oracle 12c agora permite que você faça o mesmo. Isso deve ajudar aqueles que estão fazendo a transição do SQL Server para o Oracle. Ele também permite que uma empresa transfira mais facilmente um aplicativo do SQL Server, ou qualquer outro banco de dados que permita a coluna IDENTITY, para o Oracle.

Primeiro vou criar uma tabela com a coluna IDENTITY e preenchê-la com algumas linhas de dados.
SQL> cria tabela test_tab (2      id   NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,  3      val  VARCHAR2(20));Table created.SQL> insere valores test_tab (val) ('minha primeira linha');1 linha created.SQL> insira em test_tab (val) valores ('minha segunda linha');1 linha criada.SQL> commit;Commit completo.
 
Observe que não inseri nenhum valor na coluna ID. Agora vamos consultar a tabela.


SQL> selecione * from test_tab;ID VAL---------- --------------------1 minha primeira linha2 minha segunda linha 
 
Como você pode ver, meus valores de ID foram adicionados como você poderia esperar. Na minha criação de tabela, defini esta coluna IDENTITY com:    GENERATED BY DEFAULT ON NULL

A cláusula BY DEFAULT significa que o Oracle atribuirá automaticamente o próximo valor na sequência se você o omitir em sua instrução INSERT. Se você incluí-lo, o Oracle usará o valor especificado. Considere isto:


SQL> insira em valores test_tab (4,'ID especificado=4');1 linha criada.SQL> commit;Commit complete.SQL> selecione * from test_tab; ID VAL---------- --------------------         1 minha primeira linha         2 minha segunda linha         4 ID especificado=4
 
Como você pode ver, porque eu declarei explicitamente ID=4 e o Oracle deixou esse valor passar. O que acontece quando tento inserir o próximo valor, que deve ser 3?
SQL> inserir valores test_tab (val) ('minha linha após ID=4');1 linha criada.SQL> commit;Commit complete.SQL> selecione * from test_tab; ID VAL---------- --------------------         1 minha primeira linha         2 minha segunda linha         4 ID especificado=4         3 minha linha após o ID =4
O acima funcionou como eu esperava. O próximo valor de ID disponível foi usado. Mas a próxima inserção usará '4' ou '5'?
SQL>  insira nos valores test_tab (val) ('minha quinta linha');1 linha criada.SQL> commit;Commit complete.SQL> selecione * de teste_tab; ID VAL---------- --------------------         1 minha primeira linha         2 minha segunda linha         4 ID especificado=4         3 minha linha após o ID =4         4 minha quinta linha
Uh-oh! O valor duplicado foi permitido. Eu teria esperado que uma restrição de Chave Primária fosse criada para impor o conceito de um valor de “identidade”, mas isso não acontece. Quais restrições existem?
SQL> selecione constraint_name,constraint_type,table_name,search_condition de user_constraints;CONSTRAINT_NAME                C TABLE_NAME-------------------------- --- - ------------------------------SEARCH_CONDITION--------------- -------------------------------------------------- ---------------SYS_C004978                    C TEST_TAB"ID" NÃO É NULO
Portanto, a única restrição é uma restrição de verificação NOT NULL. Agora vamos remover a última linha e adicionar uma restrição PK.
SQL> delete from test_tab where val='my five row';1 row delete.SQL> commit;Commit complete.SQL> alter table test_tab add constraint test_tab_pk chave primária (id);Tabela alterada.
Agora vou me certificar de que tenho alguns dados para testar.
SQL> insira nos valores test_tab (val) ('after pk constraint'); 1 linha criada.SQL> insira nos valores test_tab (id,val) ( 6,'definir explicitamente id=6');1 linha criada.SQL> commit;Commit complete.SQL> select * from test_tab; ID VAL---------- --------------------         1 minha primeira linha         2 minha segunda linha         4 ID especificado=4         3 minha linha após o ID =4         5 após a restrição de pk         6 id definido explicitamente=66 linhas selecionadas.
Então eu adicionei explicitamente ID=6. Se for como quando eu adicionei explicitamente ID=4, minha próxima inserção tentará usar ID=6 e com a restrição PK em vigor, uma exceção será lançada.
SQL> insert into test_tab (val) values ​​(' after ID=6'); insira nos valores test_tab (val) ('after ID=6')*ERROR na linha 1:ORA-00001:restrição exclusiva (PEASLAND.TEST_TAB_PK) violada
Portanto, a moral da história é que, se você usar ON DEFAULT, esteja preparado para lidar com colisões de valores de identidade. O padrão é SEMPRE em vez de ON DEFAULT. Com ALWAYS, o Oracle sempre usará o gerador de número de sequência. Se você tentar especificar um valor de id, ocorrerá uma exceção.
SQL> create table test_tab2(id number gerado sempre como identidade, val varchar2(20));Table created.SQL> insert into test_tab2(id,val) values ​​(1,'first row');insert into test_tab2(id,val) values ​​(1,'first row')                      *ERRO na linha 1:ORA-32795:não é possível inserir em uma coluna sempre de identidade gerada
A visualização *_TAB_COLUMNS pode mostrar quais colunas em uma tabela são colunas IDENTITY.
SQL> selecione column_name,identity_column de user_tab_columns onde table_name='TEST_TAB';COLUMN_NAME     IDE-------------- - ---ID              YESVAL             NÃO
Se você usar a coluna IDENTITY em suas tabelas, tenha o cuidado de testar para garantir que ela funcione corretamente para seu aplicativo. Fiquei surpreso que uma restrição PK ou UNIQUE não foi incluída automaticamente, o que me permitiu adicionar um valor duplicado.