Pesquisar no Programero

quinta-feira, 26 de julho de 2012

O que devemos conhecer sobre SQL/Oracle Parte 18: Controlando o acesso dos usuários

Diferenciando privilégios de sistema de privilégios de objetos


Existem três categorias gerais para agrupar privilégios, que são:

  • Privilégios de sistema: habilidade de realizar tarefas especificas no banco de dados, como por exemplo, logar ou criar uma tabela;
  • Privilégios de objeto: habilidade de realizar tarefas em um determinado objeto do banco de dados;
  • Regra (role): coleção de um ou mais privilégios de sistema e/ou privilégios de objeto, e/ou outras regras;


O que devemos ter em mente é o seguinte, privilégios de sistema é o que precisamos para criar objetos do banco de dados, por exemplo, o direito de criar uma tabela é um privilégio de sistema e a habilidade de alterar registros dessa tabela é um privilégio de objeto.

A seguir uma tabela com alguns dos privilégios de sistema:

Privilégios de sistema
Privilégio
Descrição
CREATE SESSION
Conectar a base.
CREATE TABLE
Criar uma tabela na conta do usuário, incluindo a capacidade de alterar e remover a tabela.
CREATE VIEW
Criar visões na conta do usuário, incluindo a capacidade de alterar e remover.
CREATE SEQUENCE
Criar sequência na conta do usuário, incluindo a capacidade de alterar e remover.
CREATE SYNONYM
Criar sinônimos na conta do usuário, incluindo a capacidade de alterar e remover (apenas privados).
CREATE ROLE
Criar uma regra, incluindo a capacidade de alterar e remover.
CREATE PUBLIC SYNONYM
Criar sinônimos na conta PUBLIC.
DROP PUBLIC SYNONYM
Remover um sinônimo da conta PUBLIC.
CREATE ANY TABLE
Criar tabelas em qualquer conta.
ALTER ANY TABLE
Alterar tabelas de qualquer conta.
DELETE ANY TABLE
Remover registros de qualquer tabela de qualquer conta.
DROP ANY TABLE
Remover tabelas de qualquer conta.
INSERT ANY TABLE
Inserir registros de qualquer tabela de qualquer conta.
SELECT ANY TABLE
Selecionar registros de qualquer tabela de qualquer conta.
UPDATE ANY TABLE
Atualizar registros de qualquer tabela de qualquer conta.
CREATE ANY VIEW
Criar visões em qualquer conta.
DROP ANY VIEW
Remover visões de qualquer conta.
CREATE ANY INDEX
Criar índices em qualquer conta.
ALTER ANY INDEX
Alterar índices de qualquer conta.
DROP ANY INDEX
Remover índices de qualquer conta.
CREATE ANY SEQUENCE
Criar sequências em qualquer conta.
ALTER ANY SEQUENCE
Alterar sequências de qualquer conta.
DROP ANY SEQUENCE
Remover sequências de qualquer conta.
SELECT ANY SEQUENCE
Selecionar de uma sequência de qualquer conta.
CREATE ANY SYNONYM
Criar sinônimos em qualquer conta.
ALTER ANY SYNONYM
Alterar sinônimos de qualquer conta.
CREATE ANY DIRECTORY
Criar diretórios em qualquer conta.
DROP ANY DIRECTORY
Remover diretórios de qualquer conta.
ALTER ANY ROLE
Alterar regras de qualquer conta.
DROP ANY ROLE
Remover regras de qualquer conta.
GRANT ANY ROLE
Delega qualquer regra da base.
FLASHBACK ANY TABLE
Realiza operações de FLASHBACK em qualquer tabela de qualquer conta.
CREATE USER
Criar conta de usuário.
ALTER USER
Alterar conta de usuário.
DROP USER
Remover conta de usuário.
GRANT ANY PRIVILEGE
Delega qualquer privilégio de sistema para qualquer usuário do banco.
GRANT ANY OBJECT PRIVILEGE
Delega para qualquer conta qualquer privilegio de objeto cujo dono possua direito de delegar.

Vamos a alguns exemplos:

CONNECT SYSTEM/SENHASYS;
CREATE USER MARIA IDENTIFIED BY SENHA123;
GRANT CREATE SESSION, CREATE TABLE TO MARIA;
GRANT UNLIMITED TABLESPACE TO MARIA;

Considerando que estamos executando os comandos no SQL Plus, a primeira linha conecta o usuário SYSTEM ao banco de dados, na segunda o usuário MARIA é criado, na terceira é concedido ao usuário recém-criado o direito de se conectar a base e criar tabelas, e por fim foi definido que esse usuário terá espaço ilimitado no TABLESPACE (o ultimo comando não deve ser replicado em ambiente de produção, sempre deve ser definido uma cota de TABLESPACE para os usuários).

CONNECT SYSTEM/SENHASYS;
CREATE USER JOAO IDENTIFIED BY SENHA123;
GRANT CREATE SESSION, CREATE ANY TABLE TO JOAO;
GRANT UNLIMITED TABLESPACE TO JOAO;
CONNECT JOAO/SENHA123;
CREATE TABLE MARIA.TESTE (CODIGO NUMBER(10));

No exemplo acima criamos mais um usuário nas primeiras linhas, JOAO, o diferença fica apenas por conta da palavra ANY incluída na delegação do privilégio de criação de tabelas, concedendo a JOAO o direito de criar uma tabela na conta de qualquer usuário, e foi justamente isso o que fizemos, primeiro nos conectamos a nova conta na linha cinco e então criamos uma tabela chamada TESTE na conta do usuário MARIA.

É possível em um comando de GRANT conceder o privilegio de replicar esse mesmo privilegio para outros usuários:

GRANT privilegio TO usuário WITH ADMIN OPTION;

No exemplo acima o usuário poderá conceder esse mesmo direito para outro usuário.
É possível também conceder todos os privilégios disponíveis de uma só vez:

GRANT ALL PRIVILEGES TO USER;

Resumindo:

O direito de usar qualquer comando SQL e/ou executar uma tarefa no banco é um privilegio de sistema;
O direito de usar um privilégio de sistema para realizar uma tarefa em um objeto em especifico do banco é um privilégio de objeto;
Ambos são garantidos ou revogados de usuários do banco;
Privilégios de sistema atribuídos com WITH ADMIN OPTION, garantem a habilidade ao usuário que recebeu o privilegio de repassar o mesmo a outro usuário;
Quando um privilégio de sistema é revogado, a revogação não ocorre em cascata, ou seja, ela ocorre apenas para o usuário indicado no comando;
ALL PRIVILEGES pode ser usado para atribuir ou revogar todos os privilégios de ou para um usuário;

Atribuindo privilégios a tabelas


Quando uma tabela é criada, o usuário passa a ter direitos de selecionar, incluir e atualizar dados nessa tabela, o mesmo não é valido para outros usuários, que sequer saberão que a tabela existe. Para que outros usuários possam ver a tabela o dono da mesma deve delegar direitos como GRANT SELECT, UPDATE. Ao receber o direito de acesso a uma tabela de outro usuário é necessário sempre indicar primeiro o nome do usuário e em seguida o nome da tabela, a menos que um sinônimo seja criado.
Os direitos de acesso e alteração uma vez concedidos podem ser revogados a qualquer momento com o comando REVOKE. É importante salientar que se uma tabela for removida da base todos os GRANTS concedidos a outros usuários também são eliminados, caso a tabela seja criada novamente esses privilégios devem ser criados novamente.

Resumindo:

  • Privilégios de objetos correspondem a comandos DML, e para comandos DDL que são relevantes para a existência de objetos;
  • Privilégios de objetos podem ser atribuídos com WITH GRANT OPTION, que provê a capacidade a quem recebeu o privilegio repassar o mesmo a outro usuário;
  • Quando um privilégio de objeto é revogado ele ocorre em cascata, ou seja, todos os usuários que receberam esse privilégio também o perdem;
  • Quando um usuário recebe o direito de acesso a um objeto, o nome do objeto deve possuir como prefixo o nome do esquema ao qual ele pertence;
  • Um PUBLIC SYNONYM provê uma alternativa para evitar a necessidade do uso do esquema no nome dos objetos;
  • ALL PRIVILEGES pode ser usado para atribuir ou revogar todos os privilégios de ou para um usuário;

Visualizando privilégios no dicionário de dados


O dicionário de dados possui algumas tabelas para que possamos ver quais os privilégios temos sobre os objetos do banco, vejamos alguns:

Visões do dicionário de dados que dizem respeito a privilégios
Visões
Descrição
USER_SYS_PRIVS
Privilégios de sistema atribuídos para o usuário atual.
DBA_SYS_PRIVS
Privilégios de sistema atribuídos para usuários e regras.
USER_TAB_PRIVS
Privilégios sobre objetos para cada usuário que concedeu, recebeu ou cujo ele seja o dono.
ALL_TAB_PRIVS
Privilégios sobre objetos para cada usuário que concedeu, recebeu ou cujo ele seja o dono, ou uma regra ativa ou publica.
DBA_TAB_PRIVS
Privilégios de todos os objetos da base.
ALL_TAB_PRIVS_RECD
Privilégios de objetos para cada usuário, publico, ou regra ativa.
SESSION_PRIVS
Privilégios do usuário atual.

Resumindo:

  • Existem varias visões que permitem a consulta sobre os privilégios de sistema e objetos;
  • Usuários podem visualizar privilégios garantidos a si mesmos, ou a outros usuários por meio dessas visões;

Atribuindo regras (ROLES)


Uma regra é um objeto onde é possível indicar privilégios de sistema ou de objeto, desse modo podemos atribuir uma série de privilégio a um único objeto (regra) e então realizar GRANTs apenas da regra para os usuários. Isso não só garante uma maior agilidade durante as atribuições como também das revogações, já que basta revogar da regra para que todos os usuários ligados a ela sejam afetados. Veja um exemplo:

CREATE ROLE DIREITOS_INICIAIS;
GRANT CREATE SESSION, CREATE TABLE, CREATE PROCEDURE TO DIREITOS_INICIAIS;
GRANT DIREITOS_INICIAIS TO JOSE;

No exemplo acima criamos uma regra, em seguida atribuímos alguns privilégios para ela e em seguida atribuímos a regra para um usuário, logo todos os privilégios contidos na regra ficam disponíveis para o usuário.
Também é possível atribuir regras para regras, e até mesmo atribuir regras com WITH ADMIN OPTION, o que garante para o usuário o direito de repassar a regra para outros usuários, perceba que se o usuário A recebeu uma regra e a repassou para o usuário B, esse ultimo não perde os direitos da regra quando a mesma é revogada do usuário A, para isso a regra deve ser revogada explicitamente do usuário B.
Uma regra criada fica armazenada em um namespace a parte, fora da área do usuário. É importante lembrar também que um usuário pode receber privilégios de varias regras ao mesmo tempo. Para obter informações sobre as regras podemos consultar as seguintes visões:

Visões do dicionário de dados que dizem respeito a regras (roles)
Visões
Descrição
DBA_ROLES
Todas as regras que existem na base.
DBA_ROLE_PRIVS
Regras atribuídas aos usuários e outras regras.
DBA_SYS_PRIVS
Privilégios de sistema atribuídos a usuários e regras.
DBA_TAB_PRIVS
Todos os privilégios em objetos para usuários e regras.
ROLE_ROLE_PRIVS
Regras atribuídas a regras.
ROLE_SYS_PRIVS
Privilégios de sistemas atribuídos a regras.
ROLE_TAB_PRIVS
Privilégios de tabela atribuídos a regras.
SESSION_ROLES
Regras disponíveis para o usuário atual.

Resumindo:

  • Uma regra é criada com o comando CREATE ROLE;
  • Regras podem ser atribuídas com GRANT ADMIN OPTION, permitindo que a mesma seja repassada a outros usuários;
  • Regras existem fora do NAMESPACE do usuário;
  • Uma regra é uma coleção de privilégios e outras regras;
  • Uma regra pode ser atribuída a outras regras;

Distinguindo privilégios e regras


Regras não representam um privilégio necessariamente, elas podem inclusive existir sem possuir um privilégio associado, ela é uma coleção de privilégios. Outro fato importante é que privilégios presentes em uma regra não substituem regras que um usuário tenha, logo se um usuário recebe o privilegio de criar uma tabela, por exemplo, sendo que ele já possuía esse privilegio ao remover a regra o direito de criar tabelas não é removido, para tal o privilegio concedido anteriormente à regra deve ser revogado de forma explicita.

Resumindo:

  • Privilégios atribuídos diretamente a um usuário existem independentes de um privilégio atribuído por uma regra;
  • Se um privilégio for revogado diretamente de um usuário que já possua uma regra que contenha esse privilégio em questão, a regra permanece igual e o usuário continua com o privilégio;
  • O oposto da situação descrita acima também ocorre, se uma regra for revogada, privilégios atribuídos de forma individual permanecem válidos;

quarta-feira, 25 de julho de 2012

O que devemos conhecer sobre SQL/Oracle Parte 17: Suporte a expressões regulares

Utilizando metacharacters



Expressões regulares são utilizadas por varias linguagens de programação e em diversos sistemas operacionais, e o Oracle não é exceção, ele oferece esse poderoso recurso em sua linguagem. São formadas por diversos símbolos e códigos conhecidos como metacharacters, e são utilizados para buscar partes de um determinado texto. A seguir veremos três quadros com os operadores, classes POSIX e intervalos de caracteres:



Operadores das expressões regulares
Operador
Descrição
( )
Trata a expressão ou o conjunto de literais como uma subexpressão.
[...]
O par de colchetes delimita uma lista de uma ou mais expressões: combinações de elementos, símbolos, classes equivalentes, classes de caractere ou expressões de dimensão.
[^...]
Uma expressão de não igualdade. Indica que a lista de expressões dentro dos colchetes não deve ser encontrada.
[. ...]
O uso do ponto especifica uma combinação de elementos de acordo com o local. Muito útil em situações onde dois ou mais caracteres são necessários para especificar um elemento, como por exemplo, na especificação de um limite entre “a” e “ch” utilizaremos [a...[.ch.]].
[:...:]
Especifica uma classe de caracteres.
[=...=]
Especifica uma classe de equivalência, por exemplo, [=e=] representa “e”, “é”, “è”, “ë”.
.
O ponto combina qualquer caractere.
?
Combina zero ou uma ocorrência da subexpressão que o precede.
*
Combina zero ou mais ocorrências da subexpressão que o precede.
+
Combina zero ou mais ocorrências da subexpressão que o precede.
{n1}
Combina precisamente n1 ocorrências da subexpressão que o precede.
{n1,}
Combina n1 ou mais ocorrências da subexpressão que o precede.
{n1, n2}
Combina as ocorrências entre n1 e n2, inclusive os limites, da subexpressão que o precede.
\
Dependendo do contexto a contra barra é apenas uma contra barra, se estiver precedendo outro operador este é transformado em literal, por exemplo, \+ é o valor literal do mais.
\n1
Referencia anterior, repetição de “n1vezes” da subexpressão dentro da expressão anterior.
|
Operador lógico “OU”. Utilizado para separar duas expressões, onde uma delas é combinada.
^
Ancora de inicio de linha.
$
Ancora de fim de linha.

Classes de caracteres POSIX
Classes de caracteres
Tipos de caracteres
[:alnum:]
Caracteres alfanuméricos. Inclui letras e números, omitindo pontuação.
[:alpha:]
Caracteres do alfabeto. Apenas letras.
[:blank:]
Caracteres que formam espaços.
[:cntrl:]
Caracteres de controle (que não são impressos).
[:digit:]
Caracteres numéricos.
[:graph:]
Todas as classes de caracter combinadas, [:punct:], [:upper:], [:lower:], [:digit:].
[:lower:]
Caracteres minúsculos.
[:print:]
Caracteres que podem ser impressos.
[:punct:]
Caracteres de pontuação.
[:space:]
Caracteres de espaço que não podem ser impressos.
[:upper:]
Caracteres maiúsculos.
[:xdigit:]
Caracteres hexadecimais.

Intervalos de caracteres
Intervalo
Tipos de caractere
[A-Z]
Todos os caracteres do alfabeto maiúsculos.
[a-z]
Todos os caracteres do alfabeto minúsculos.
[0-9]
Todos os dígitos numéricos.
[1-9]
Todos os dígitos numéricos excluindo o zero.

Resumindo:

  • Operadores metacharacters formam o fundamento das expressões regulares;
  • Os padrões das expressões regulares são construídos com os operadores metacharacters;
  • Dependendo do contexto, certos caracteres literais podem ser operadores de expressões regulares com capacidades especiais;
  • Expressões regulares podem incluir caracteres literais;
  • Literais entre colchetes representam uma série de possíveis valores, ou uma lista a ser obedecida;
  • Parênteses agrupam expressões e subexpressões;
  • Uma expressão seguida de um sinal de mais, interrogação ou asterisco será interpretada como um padrão que deve ser repetido de acordo com as regras do operador;
  • É possível especificar faixas de caracteres;
  • Classes de caracteres servem como alternativa para faixas e provêem um melhor suporte a aplicações de vários idiomas;

Funções de expressões regulares


Existem várias funções do Oracle que estendem as capacidades das funções de texto como SUBSTR e INSTR, essas extensões consistem em funções que dão suporte as expressões regulares:

Funções de expressões regulares
Função
Parâmetros
Descrição
REGEXP_SUBSTR
s1 (uma string obrigatória).
Pattern1 (expressão regular obrigatória).
p1 (numero opcional, default 1).
n1 (numero opcional, default 1).
m1 (um ou mais dos parâmetros literais de correspondência).
Pesquisa dentro de s1 por qualquer correspondência definida em pattern1. Inicia a busca na posição p1 procurando pela n1 ocorrência do padrão. Realiza a combinação de acordo com as instruções de m1.
REGEXP_INSTR
S1 (uma string obrigatória).
pattern1 (expressão regular obrigatória).
p1 (numero opcional, default 1).
n1 (numero opcional, default 1).
opt1 (numero, limitado entre zero ou um, default zero).
m1 (um ou mais dos parâmetros literais de correspondência).
Procura em s1 por qualquer substring que seja igual ao padrão definido em pattern1. Inicia a busca na posição p1, procurando pela n1 ocorrência do padrão. Realiza a comparação de acordo com as instruções de m1. O resultado é um numero que representa a localização de pattern1 em s1. Se opt1 = 1, então é retornado a localização da primeira posição depois de pattern1.
REGEXP_REPLACE
S1 (uma string obrigatória).
pattern1 (expressão regular obrigatória).
repl (string opcional, nulo como default).
p1 (numero opcional, default 1).
o1 (numero opcional, default 0).
m1 (string literal que permite alterar o comportamento de igualdade, onde ‘c’ procura por correspondência ‘case-sensitive‘, ‘i’ por ‘case-insensitive’, ‘n’ correspondência para qualquer caractere, ‘m’ trata a fonte de dados como multilinha, se omitido é considerado como linha única, e ‘x’ ignora espaços).
Substitui o1 ocorrências de pattern1 de s1 por repl, iniciando da posição p1. Realiza a correspondência de acordo com as instruções de m1.
REGEXP_LIKE
s1 (string obrigatória).
pattern1 (expressão regular obrigatória).
m1 (um ou mais parâmetros literais).
Compara pattern1 com a string s1 e determina se existe igualdade. Realiza a correspondência de acordo com as instruções definidas em m1. A resposta é booleano, se verdadeiro encontrou correspondência, caso contrário falso (não deve-se utilizar os operadores ‘coringas’ do LIKE).

Para buscar uma determinada palavra em uma frase podemos fazer o seguinte:

SELECT REGEXP_SUBSTR('RUA ALBERTO DE OLIVEIRA N.9999', '[[:alpha:]]+', 1, 2) FROM DUAL;

No exemplo acima a segunda palavra será retornada, pois estamos procurando por uma sequência de caracteres, iniciando na primeira posição e que seja a segunda ocorrência.

Agora se a intenção for encontrar uma sequência de números:

SELECT REGEXP_SUBSTR('RUA ALBERTO DE OLIVEIRA N.9999', '[[:digit:]]+') FROM DUAL;

Do mesmo modo poderíamos mostrar não o numero mas em que posição ele ocorre em nosso texto:

SELECT REGEXP_INSTR('RUA ALBERTO DE OLIVEIRA N.9999', '[[:digit:]]+') FROM DUAL;

Resumindo:

  • Existem funções SQL que dão suporte a expressões regulares;
  • REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_LIKE e REGEXP_REPLACE são as funções em SQL que permitem o uso as expressões regulares;

Padrões de substituição


Como visto anteriormente, para substituição de caracteres podemos usar o REGEXP_REPLACE, que utiliza expressões regulares para substituição. Vejamos o primeiro exemplo, o padrão [.]+ indicaria que desejamos substituir o caractere ponto, ainda nessa expressão temos o sinal de mais que indica que a substituição deve ocorrer uma ou mais vezes consecutivas:

SELECT REGEXP_REPLACE(‘PADROES DE SUBSTITUICAO.....................CAP 02’, ‘[.]+’, ‘-’) FROM DUAL;

O comando acima teria como resultado a string ‘PADROES DE SUBSTITUICAO-CAP 02’.
Também é possível indicar mais de um caractere a ser substituído:

SELECT REGEXP_REPLACE('ESPECIAIS: ! @ ? # $', '[!@?#$]', '*') FROM DUAL;

No exemplo acima o resultado seria ‘ESPECIAIS: * * * * *’.
Um dos usos frequentes das expressões regulares é a substituição de espaços:

SELECT REGEXP_REPLACE('TEXTO     COM      ESPAÇO,    DEVE  SER                FORMATADO'            , '( ){2,}', ' ') FROM DUAL;

No exemplo acima a expressão regular inicia com espaço em branco entre parênteses, seguido do numero dois com vírgula entre chaves, o numero dois com vírgula indica que o padrão é o definido no caractere anterior, espaço, em duas ou mais ocorrências, com isso toda sequência de dois ou mais espaços é substituída por um único.

Outro exemplo de uso seria para o caso de se substituir certo conjunto de caracteres:

SELECT REGEXP_REPLACE('SAO PAULO, RP 601000', '(^[[:alpha:] ]+)', 'HABITANTES') FROM DUAL; 

No exemplo acima estamos substituindo parte do texto ('SAO PAULO’) pela palavra ‘HABITANTES’, a busca ocorre por qualquer caractere, repetindo a referencia com o sinal de mais, é importante ressaltar o espaço entre os colchetes finais, sem ele apenas a primeira palavra seria substituída.

Para finalizar os exemplos de substituição faremos algo relativamente complexo, vamos alterar a ordem em que as palavras da frase aparecem e ainda incluiremos uma marcação em uma dessas partes:

SELECT REGEXP_REPLACE('SAO PAULO, RP 601000', '(^[[:alpha:] ]+), ([[:alpha:]]{2}) ([[:digit:]]{6})', '\3 \2-"\1"') FROM DUAL;

No ultimo exemplo incluímos a nossa expressão mais duas, onde a segunda recupera uma sequencia de dois caracteres e a terceira uma sequencia de seis números, a substituição deve ocorrer da seguinte forma, o terceiro conjunto (números) deve aparecer primeiro, seguido do segundo (duas letras), e o ultimo deve ser o primeiro conjunto entre parênteses, observe que ainda entre o segundo e o primeiro conjunto temos agora um traço, o resultado seria ‘601000 RP-"SAO PAULO"’.

Resumindo:

  • A função REGEXP_REPLACE pode substituir substring de uma string utilizando expressões regulares;
  • O uso de expressões regulares com a tarefa de substituição de texto é uma alternativa poderosa ao uso da função REPLACE, que não suporta o uso de expressões regulares;
  • O operador backreference (contra barra mais um numero) pode ser usado como terceiro parâmetro para substituir um padrão, e especificar expressões agrupadas dentro de um padrão como parte de uma substituição;

Expressões regulares e a restrição CHECK


Outra utilização para as expressões regulares é na restrição CHECK, como já foi visto a restrição CHECK verifica o conteúdo de uma coluna, ele possui uma regra que deve ser obedecida para que o registro seja salvo. Vejamos um exemplo:

CREATE TABLE CLIENTES(
CODIGO NUMBER(10) PRIMARY KEY, 
DESCRICAO VARCHAR2(100), 
EMAIL VARCHAR2(120)
,CONSTRAINT CK_EMAIL_CLI CHECK (
REGEXP_LIKE(EMAIL, '^([[:alnum:]]+)@[[:alnum:]]+.(com|net|org|edu|gov|mil)$')));

O exemplo acima mostra o uso da expressão regular como condição da restrição CHECK, a expressão indica que qualquer caractere é permitido antes e depois do arroba ( o arroba é obrigatório), sendo que os caracteres posteriores devem ser seguidos de ponto e um dos termos listados em seguida, perceba que os valores listados estão separados pelo separador logico OU, onde apenas um deles é permitido.

Resumindo:

  • É possível criar restrições CHECK que usam expressões regulares;
  • Restrições CHECK podem usar expressões regulares para definir restrições e requisitos para os dados a serem inseridos/atualizados na tabela;
  • A condição REGEXP_LIKE é muito útil quando usada em uma restrição CHECK;