Bancos de dados

O Engine é uma plataforma de desenvolvimento fortemente integrada com bancos de dados relacionais, sendo requerida a configuração de ao menos uma base de dados para o seu funcionamento.

Atualmente são suportados os seguintes sistemas gerenciadores de base de dados (SGBD):

Veja em requisitos do sistema as versões suportadas desses SGBDs.

Configuração do Banco de Dados

Nos Engines servidores de aplicação, deve-se configurar o acesso à base de dados na página “Configuration > Databases” do Manage. Nela, deve ser definido um nome único para a base de dados composto apenas de letras maiúsculas, números e hífen, sem acentos ou outros símbolos. Esse identificador será utilizado nas demais configurações do Manage e nos Engines clientes.

Para simplificar a identificação das bases de dados, é recomendado que seja utilizado o nome da empresa sem espaços e acentos na base de produção. Para as bases de desenvolvimento e homologação deve ser utilizado esse mesmo nome acrescido dos prefixos “D” ou “H”. Exemplo: para uma base de produção chamada “EMPRESA”, devem ser utilizados os nomes “DEMPRESA” e “HEMPRESA” para as bases de desenvolvimento e homologação respectivamente.

Após a criação da base de dados, pode ser definido um título mais amigável para os usuários finais no processo “Admin > Base de dados > Configurações”. Nele, além de configurar o título da base de dados, também é possível definir um subtítulo, sendo esse último recomendado para indicar a finalidade das bases de dados que não são de produção, como as de “Desenvolvimento”, “Homologação” ou “Treinamento”.

Uma vez definido o nome da base de dados, devem ser informadas as seguintes configurações com a orientação do DBA responsável pelo SGBD:

  • Type: tipo do SGBD, podendo ser “PostreSQL”, “Oracle” ou “Microsoft SQL Server”.
  • Reference: identificação da base de dados no cliente do SGBD. Essa configuração muda de acordo com o SGBD utilizado, conforme instruções a seguir.
  • MDBC: quantidade máxima de conexões que o Engine irá estabelecer com o SGBD. Esse valor deve ser definido de acordo com a capacidade de antedimento do servidor da base de dados. O DBA deve considerar que a quantidade total de requisições a partir do sistema será a soma dos MDBC de todos os Engines configurados como servidores de aplicação.
  • Username: nome do usuário do SGBD que o Engine irá utilizar para se conectar. A conta de usuário informada deve ter privilégios de modificar livremente o esquema da base de dados. Esses privilégios são necessários para a criação, alteração ou remoção de novas tabelas, colunas e índices durante a atualização do sistema. No entanto, por motivo de segurança, o usuário informado nunca deve ter acesso aos outros esquemas de dados existentes no mesmo servidor.
  • Password: senha do usuário do SGBD utilizado pelo Engine. Devido ao acesso do Engine ao SGBD ser direto, sem interação humana, a senha configurada não deve expirar ou ter programação de troca automática.

PostgreSQL

Em sistemas operacionais Windows, o Engine embarca um cliente nativo do PostgreSQL, não sendo necessárias instalações ou configurações adicionais. No Linux, deve ser instalado o cliente adequado para a versão do PostgreSQL utilizada, conforme documentação https://www.postgresql.org/download/linux/.

Após a instalação do cliente, deve ser informado o campo Reference na configuração de base de dados do Manage utilizando a seguinte sintaxe:

<server_address>[:<port>]:<database_name>

Conexões encriptadas

Para habilitar a criptografia na conexão com o banco de dados PostgreSQL, é necessário preencher as variáveis abaixo no arquivo de configuração “postgresql.conf”:

  • ssl: preencher com o valor “on” para ativar a criptografia.
  • ssl_cert_file: caminho do arquivo de certificado do servidor.
  • ssl_key_file: caminho do arquivo de chave privada do servidor.

Após a alteração no arquivo de configuração o banco de dados deve ser reiniciado. Para maiores detalhes consulte a documentação oficial.

Para confirmar que a conexão com o PostgreSQL está encriptada, procure pela mensagem “PostgreSQL SSL connections enabled” no arquivo “engine.log”. Caso não tenha acesso ao Manage para consulta aos arquivos de log, é possível confirmar se a conexão está encriptada utilizando a consulta abaixo:

SELECT SSL FROM PG_STAT_SSL WHERE PID = PG_BACKEND_PID()

A conexão estará criptografada se o valor da coluna “SSL” for “true”.

Oracle

Um cliente do banco de dados Oracle deve ser instalado com a mesma arquitetura (64 ou 32 bits) utilizada pelo Engine servidor. No diretório do cliente instalado, o DBA deverá configurar um listener local no arquivo tnsnames.ora. Por exemplo, para o Oracle Instant Client em um servidor Windows deverá ser criado o arquivo C:\oracle\instantclient_n_n\network\admin\tnsnames.ora com o conteúdo abaixo:

<oracle_service_name> =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = <oracle_server_address>)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = <oracle_service_name>)
    )
  )

O Oracle deve estar configurado para utilizar um charset compatível com a codificação utilizada pelo Engine (windows-1252), como AL32UTF8 ou WE8MSWIN1252. Não deve ser utilizada a codificação WE8ISO8859P1, que é comumente confundida com a windows-1252, pois ela não suporta todo o conjunto de caracteres usado pelo Engine e sua utilização acarreta em falhas de integridade no sistema. Também é necessário que o parâmetro NLS_LANG do cliente esteja configurado com a codificação windows-1252 esperada pelo Engine, independente do charset utilizado no Oracle. Essa configuração pode ser feita no registro do Windows ou via variável de ambiente conforme exemplo abaixo:

NLS_LANG=American_America.WE8MSWIN1252

No campo Reference da configuração da base de dados do Manage, deve ser informado o nome do serviço local configurado no arquivo tnsnames.ora. É importante observar que o conceito de base de dados do sistema e de outros bancos de dados, como o PostgresSQL e o Microsoft SQL Server, é diferente do empregado pelo Oracle. Múltiplas bases de dados em um mesmo servidor Oracle são normalmente isoladas por meio de esquemas de dados distintos e o identificador do serviço do Oracle não determina o esquema de dados a ser utilizado pelo Engine. Essa identificação ocorre indiretamente ao associar um esquema de dados padrão ao usuário utilizado pelo Engine na conexão ao Oracle. Dessa forma, as consultas SQL realizadas pelo sistema, sem a indicação explícita de um esquema de dados, serão executadas corretamente no esquema de dados utilizado pela base de dados. Em resumo, são recomendadas as seguintes práticas:

  1. Crie um esquema de dados distinto para cada base de dados.
  2. Crie um usuário que utilize esse esquema por padrão. Esse usuário deverá ter privilégios de modificar livremente esse esquema, para criar, alterar ou remover novas tabelas, colunas e índices durante a atualização do sistema, mas não deverá ter acesso a nenhum outro esquema de dados no mesmo servidor por motivo de segurança.
  3. Configure o Engine para acessar esse servidor por meio de um listener local configurado no arquivo tnsnames.ora informando o nome do serviço no campo Reference e utilize as credenciais vinculadas ao esquema da base de dados.

Além da permissão completa às tabelas criadas no esquema da base de dados, também é necessário dar permissão de SELECT às seguintes visões de sistema do Oracle:

  • USER_TAB_COLUMNS
  • USER_TABLES
  • USER_VIEWS
  • USER_SEQUENCES
  • NLS_DATABASE_PARAMETERS

Importante: o diretório de instalação da biblioteca do Oracle oci.dll (Windows) ou libclntsh.so (Linux) deve estar acessível no PATH no caso do Windows ou no LD_LIBRARY_PATH no caso do Linux. As opções de instalação do Oracle Instant Client via arquivos zip não irão realizar essa configuração automaticamente, sendo necessária a configuração dessas variáveis de ambiente para incluir o diretório onde os arquivos do zip foram extraídos.

Conexões encriptadas

Para habilitar a criptografia na conexão com o banco de dados Oracle, devem ser criadas “carteiras” (wallets) tanto no ambiente do servidor quanto no ambiente do cliente. As carteiras são utilizadas para armazenar os arquivos de certificado. O Oracle não acessa os certificados diretamente do sistema de arquivos e sim por meio das carteiras.

Os passos para configurar a conexão criptografada no servidor são:

  • Criar uma carteira no servidor e adicionar nela o certificado do servidor.
  • Exportar da carteira o certificado do servidor gerando um arquivo que deve ser copiado para o ambiente cliente.
  • O certificado do cliente deve ser adicionado na carteira do servidor.
  • O arquivo “sqlnet.ora” deve ser ajustado para informar a localização da carteira.
  • O arquivo “listener.ora” deve ser ajustado para informar a localização da carteira e para adicionar na lista de endereços uma nova entrada indicando a utilização o protocolo encriptado.

Os passos para configurar a conexão criptografada no cliente são:

  • Criar uma carteira e adicionar nela o certificado do cliente.
  • Exportar da carteira o certificado do cliente gerando um arquivo que deve ser copiado para o servidor.
  • O certificado do servidor deve ser adicionado na carteira do cliente.
  • O arquivo “sqlnet.ora” deve ser ajustado para informar a localização da carteira.
  • O arquivo “tnsnames.ora” deve ser ajustado adicionando uma entrada referente ao serviço do listener que recebe conexões com o protocolo encriptado.

Os detalhes dessas configurações podem ser consultados na seguinte documentação.

Para confirmar que a conexão com o Oracle está encriptada, procure pela mensagem “Oracle SSL connections enabled” no arquivo “engine.log”. Caso não tenha acesso ao Manage para consulta aos arquivos de log, é possível confirmar se a conexão está encriptada utilizando a consulta abaixo:

SELECT SYS_CONTEXT(''USERENV'', ''NETWORK_PROTOCOL'') as PROTOCOL FROM DUAL

A conexão estará criptografada se o valor da coluna “PROTOCOL” for “TCPS”.

Monitoramento

Para monitorar as operações em execução no banco de dados é possível utilizar a visão V$SESSION. Nas conexões ao Oracle o Engine preenche as informações de sessão adicionais abaixo:

  • MODULE: preenchida com o valor do campo ireferrer, que contém a informação de qual processo originou a requisição.
  • CLIENT_INFO: preenchida com o usuário do sistema que está utilizando a conexão no momento.

Essas informações, em conjunto com outras fornecidas por essa visão como MACHINE e PROGRAM, ajudam a rastrear usuário, processo e instância do Engine que possam apresentar comportamento inesperado.

Microsoft SQL Server

Instale o Microsoft ODBC Driver com a mesma arquitetura (64 ou 32 bits) utilizada pelo Engine servidor. As seguintes versões são suportadas:

Após a instalação do cliente, deve ser informado o campo Reference na configuração de base de dados do Manage utilizando a seguinte sintaxe:

<server_address>[:<port>]:<database_name>

Conexões encriptadas

Para habilitar a criptografia no Microsoft SQL Server versão Linux, é necessário preencher as variáveis abaixo no arquivo de configuração “mssql.conf” ou utilizando a ferramenta mssql-conf:

  • tlscert: caminho do arquivo de certificado do servidor.
  • tlskey: caminho do arquivo de chave privada do servidor.
  • forceencryption: preencher com o valor “1” para ativar a criptografia.
  • tlsprotocols: lista separada por vírgula dos protocolos TLS permitidos. O valor recomendado é “1.2”.

O SQL Server versão Linux cria automaticamente um certificado autoassinado que pode ser utilizado para a encriptação. Esse certificado é mantido apenas em memória e nunca é gravado no sistema de arquivos do servidor. Para ativar a encriptação utilizando esse certificado o procedimento é o mesmo descrito acima, mas bastando preencher as variáveis “forceencryption” e “tlsprotocols”.

Para mais detalhes sobre a configuração consulte a documentação oficial:

Para confirmar que a conexão com o Microsoft SQL Server está encriptada, procure pela mensagem “SQL Server SSL connections enabled” no arquivo “engine.log”. Caso não tenha acesso ao Manage para consulta aos arquivos de log, é possível confirmar se a conexão está encriptada utilizando a consulta abaixo:

SELECT ENCRYPT_OPTION FROM SYS.DM_EXEC_CONNECTIONS WHERE SESSION_ID = @@SPID

A conexão estará criptografada se o valor da coluna “ENCRYPT_OPTION” for “true”.

Normalização das expressões SQL

Nas consultas à base de dados, o desenvolvedor sempre deve utilizar o padrão ISO SQL, tendo que ter atenção em utilizar apenas as funcionalidades que são implementadas por todos os SGBDs suportados pelo Engine.

Na prática isso significa que deve ser adotado o menor denominador comum das funcionalidades dos SGBDs suportados. Em casos excepcionais, essa regra pode ser contornada realizando tratamentos específicos para cada SGBD. No entanto, essa alternativa não é recomendada, pois outros SGBDs podem ser suportados pelo Engine no futuro. Caso ela realmente seja necessária, sempre adicione uma condição else com a sintaxe SQL padrão para os bancos que a suportem ou que sejam desconhecidos, permitindo assim que os futuros SGBDs suportados pelo Engine sejam eventualmente tratados por essa condição.

A fim de melhorar a interoperabilidade dos SGBDs, o Engine realiza transformações nas expressões SQL, implementando funcionalidades não suportadas nativamente pelos SGBDs ou normalizando comportamentos distintos entre eles. Essa funcionalidade pode ser desligada adicionando o comentário /*$RAW-SQL*/ no início da expressão SQL. Desative-a apenas em códigos que sejam específicos para um SGBD.

Tipos de dados normalizados

Segue a relação dos tipos suportados pelo Engine e os equivalentes nativos para cada SGBD:

Padrão SQL PostgreSQL Oracle MS SQL Server DataSet
CHAR(N) CHAR(N) CHAR(N) CHAR(N) string
VARCHAR(N) VARCHAR(N) VARCHAR2(N) VARCHAR(N) string
CLOB TEXT CLOB VARCHAR(max) memo
INTEGER INTEGER NUMBER(10) INT int32
BIGINT BIGINT NUMBER(19) BIGINT int64
NUMERIC NUMERIC(38, 10) NUMBER(38, 10) NUMERIC(38, 10) number
NUMERIC(N) NUMERIC(N) NUMBER(N) NUMERIC(N) number
DOUBLE PRECISION DOUBLE PRECISION BINARY_DOUBLE FLOAT(53) number
DATE DATE DATE¹ DATE datetime²
TIMESTAMP³ TIMESTAMP TIMESTAMP DATETIME2 datetime
TIMESTAMP WITH TIME ZONE³ TIMESTAMP WITH TIME ZONE TIMESTAMP WITH TIME ZONE DATETIMEOFFSET datetime

Observações:

  1. O tipo DATE no Oracle armazena também uma componente de hora. Essa componente é removida na leitura e gravação das colunas no acesso à base de dados.
  2. Por motivos históricos, colunas do tipo DATE da base de dados são representadas pelo tipo datetime no DataSet. Idealmente o tipo deveria ser date, garantindo que a componente de hora fosse truncada na atribuição ao campo do DataSet. No entanto, há inúmeros scripts que deixariam de funcionar se esse comportamento fosse alterado. Na prática, o DataSet permitirá que o campo tenha uma precisão de hora que será perdida na gravação dos dados e na consulta à base de dados. Por esse motivo, é recomendado que campos do tipo DATE tenham a hora truncada antes de serem gravados no DataSet pela função truncateTimePart ou código equivalente.
  3. Os tipos TIMESTAMP e TIMESTAMP WITH TIME ZONE são suportados apenas na leitura de dados, não podendo ser utilizados em operações de gravações (applyUpdates).

Tipos mantidos apenas para fins de compatibilidade e que não devem ser mais utilizados, pois não são especificados pelo padrão SQL ou não são suportados por todos os SGBDs:

Tipo PostgreSQL Oracle MS SQL Server
MEMO TEXT CLOB VARCHAR(max)
BLOB Não é suportado CLOB VARCHAR(max)
BLOB(N) Não é suportado CLOB Não é suportado
NUMBER(N) NUMERIC(N) NUMBER(N) NUMERIC(N)
NUMBER NUMERIC(38, 10) NUMBER(38, 10) NUMERIC(38, 10)

Importante: por motivos legados, o modelo de dados do sistema não utiliza colunas booleanas e datas são armazenadas sem a sua componente de hora. Por convenção, valores booleanos são armazenados em colunas do tipo CHAR(1) e a presença de qualquer valor (normalmente 'T' ou 'S') indica um valor verdadeiro e NULL representa um valor falso. No caso das datas e horas, utiliza-se uma coluna para armazenar a data e uma outra coluna, do tipo VARCHAR(5) ou VARCHAR(8), para armazenar a hora utilizando o formato 'hh:nn:ss'. O nome da coluna que armazena a hora normalmente é o nome da coluna que armazena a data, acrescido do sufixo “H”.

Funções normalizadas

Função PostgreSQL Oracle MS SQL Server
SUBSTR(value, idx, size) SUBSTR(value, idx, size) SUBSTR(value, idx, size) SUBSTRING(value, idx, size)
EXTRACT(field¹ FROM source) EXTRACT(field FROM source) EXTRACT(field FROM source) DATEPART(field, source)
CHAR_LENGTH(value) CHAR_LENGTH(value) LENGTH(value) LEN(value)²

Observações:

  1. Valores de field na função EXTRACT que são compatíveis com todos os SGBDs suportados: YEAR, MONTH, DAY, HOUR, MINUTE e SECOND. Nos SGBDs Oracle e PostgresSQL, SECOND retorna a fração de segundos, caso haja uma. No Microsoft SQL Server, apenas a parte inteira é retornada.
  2. A função LEN utilizada no Microsoft SQL Server como equivalente à função CHAR_LENGTH ignora espaços em branco no final do valor, comportamento distinto do observado nos demais SGBDs.

Formato literal de datas

A representação literal das datas em uma expressão SQL varia de acordo com o tipo:

  • DATE: devem ser formatadas no padrão americano 'MM/DD/YYYY'.
  • TIMESTAMP: devem formatadas no padrão ANSI 'YYYY-MM-DD hh:mm:ss[.nnnnnnn]'.
  • TIMESTAMP WITH TIME ZONE: devem formatadas no padrão ANSI 'YYYY-MM-DD hh:mm:ss[.nnnnnnn][{+|-}hh:mm]'.

O padrão ANSI adotado pela especificação SQL é semelhante ao padrão ISO 8601. Para fins de legibilidade, ele substitui o separador 'T' por um espaço (' '), conforme exemplo abaixo:

  • ISO 8601: 2020-03-06T17:04:19.849-03:00
  • ANSI SQL: 2020-03-06 17:04:19.849-03:00

Importante: para garantir a interoperabilidade com todos os SGBDs, não insira um espaço separando a componente de tempo e a diferença do fuso horário em relação ao UTC.

Comportamentos específicos dos SGBDs

PostgreSQL

  • Colunas textuais que são resultados de funções ou geradas a partir de um UNION têm o tamanho fixo de 65523. Exemplo: SELECT UPPER(iName) FROM iGroupUser.
  • Os valores das colunas do tipo CHAR têm os espaços à direita removidos (TrimRight).

Oracle

  • O comentário especial /*+ RULE */ sempre é removido das consultas.
  • O Oracle não suporta nativamente os tipos INTEGER e BIGINT e são utilizados os tipos NUMBER(10) e NUMBER(19) com o objetivo de emular o seu comportamento. No entanto, em operações de agregação, o Oracle remove a precisão do tipo NUMBER, provocando a “conversão” dos tipos INTEGER e BIGINT em NUMERIC. É necessário o uso de um cast caso seja necessário preservar o tipo original das colunas.
  • Os valores das colunas do tipo VARCHAR e CHAR têm os espaços à direita removidos (TrimRight).

Microsoft SQL Server

  • Os valores das colunas do tipo VARCHAR e CHAR têm os espaços à direita removidos (TrimRight).

Funcionalidades suportadas por todos os SGBDs

Além da sintaxe básica do SELECT, há recursos mais avançados definidos no padrão SQL que são evitados pelo receio deles não serem implementados em todos os SGBDs suportados pelo Engine. Com o objetivo de potencializar o uso desses recursos, a seguir são relacionadas funcionalidades que são compatíveis em todos os SGBDs que atendam os requisitos mínimos exigidos pelo Engine.

Common Table Expressions (CTE) não recursivas

WITH iRecentlyUserAppSession (iUser, iCreatedAt)  
AS  
(  
  SELECT s.iUser, MAX(s.iCreatedAt) AS iCreatedAt
  FROM iApplicationSession s
  WHERE s.iStatus <> -1898140238 /* Destruída */
    AND s.iUser <> -1 /* anonymous */
  GROUP BY s.iUser
)

SELECT u.iName, s.iClientAddress, s.iUserAgent
FROM iRecentlyUserAppSession rs
  INNER JOIN iGroupUser u ON (u.iKey = rs.iUser)
  INNER JOIN iApplicationSession s ON (s.iUser = rs.iUser AND s.iCreatedAt = rs.iCreatedAt)

Concatenação de textos

SELECT CONCAT(CONCAT(CONCAT(iFullName, ' <'), iEMailAddress), '>') AS iRecipient 
FROM iGroupUser 
WHERE iEmailAddress IS NOT NULL

O CONCAT é limitado a dois argumentos no Oracle. As seguintes alternativas não funcionam em todos os SGBDs:

  • ||: não é suportado no Microsoft SQL Server 2019 ou inferior.
  • +: não é suportado no Oracle e no PostgresSQL.

Funções analíticas

ROW_NUMBER

-- Exemplo: usuários ordenados pela quantidade de logins em um determinado mês.
SELECT iUser, ROW_NUMBER() OVER (ORDER BY iQty DESC) AS iRowNum
FROM (
  SELECT iUser, Count(*) AS iQty 
  FROM iLog 
  WHERE iType = -1898145928 /* Acesso ao sistema */
    AND iDate >= '01/01/2020' AND iDate <= '01/31/2020'
  GROUP BY iUser
) iLog

Funcionalidades conhecidas por não serem compatíveis em todos os SGBDs

A seguir são documentados recursos que não são suportados pelos SGBDs em suas versões mínimas requeridas pelo Engine.

Common Table Expressions (CTE) recursivas

WITH iClassTree (iKey, iParent, iLevel, iName, iPath)  
AS  
( 
  SELECT c.CHAVE, c.MAE, 0 AS iLevel, CAST('/' AS VARCHAR(256)), CAST('/' AS VARCHAR(4000))
  FROM CLASSE c 
  WHERE c.CHAVE = -2010000000 /* Raiz */
  UNION ALL
  SELECT c.CHAVE, c.MAE, t.iLevel + 1, CAST(c.NOME AS VARCHAR(256)), CAST(CONCAT(CONCAT(t.iPath, c.NOME), '/') AS VARCHAR(4000))
  FROM CLASSE c, iClassTree t 
  WHERE c.MAE = t.iKey
)

SELECT * FROM iClassTree ORDER by iPath

O PostgreSQL exige que a recursão da CTE seja indicada por meio da sintaxe WITH RECURSIVE em vez de WITH.

FETCH FIRST (LIMIT)

SELECT * FROM iLog 
WHERE iTableClass = -1898187811 /* Grupos, Papéis e Usuários */ 
ORDER BY iDate DESC, iHour DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY

A sintaxe padrão FETCH FIRST somente é suportada no Oracle 12c ou superior. No Microsoft SQL Server, ela é suportada apenas na cláusula ORDER BY, em conjunto com o OFFSET.

SELECT sem FROM

SELECT CURRENT_TIMESTAMP

Até a versão 19c do Oracle, o FROM é obrigatório. Nesse SGBD há alternativa de utilizar o FROM dual, mas essa abordagem não é compatível com os demais SGBDs. Os demais SGBDs suportam essa sintaxe.

Limites conhecidos

Os SGBDs têm limites de utilização que devem ser respeitados pelo modelo de dados do sistema. Abaixo são relacionados alguns limites conhecidos:

Limite PostgreSQL Oracle MS SQL Server
Colunas em uma tabela 250 a 1600¹ 1000 1024
Colunas em um índice 32 32 32
Tamanho identificador 63 caracteres 30 bytes² 128 caracteres
Tamanho VARCHAR 1GB 4000 bytes 8000 bytes

Notas:

  1. O limite máximo de 1600 colunas do PostgreSQL é reduzido na prática pelo tamanho do bloco utilizado. Considerando o bloco padrão de 8kb, o limite é reduzido para menos de 1024 colunas do tipo bigint (8 bytes) ou 455 colunas do tipo varchar (mínimo de 18 bytes). Esse limite irá variar de acordo com o tipo e o valor gravado na coluna, sendo 250 o limite inferior para blocos de 8kb.
  2. O limite de 30 bytes do Oracle foi alterado para 128 a partir do Oracle 12 R2.

Documentação de referência: