Oracle SQL 23c: Novas funcionalidades e exemplos práticos
A versão 23c do Oracle SQL introduz várias novas funcionalidades que visam melhorar a produtividade, a flexibilidade e a performance dos desenvolvedores e dos aplicativos que usam o banco de dados Oracle. Neste artigo, vamos explorar algumas dessas novas funcionalidades e ver como elas podem ser usadas na prática.
Tipo de dados BOOLEAN
O Oracle SQL 23c introduz o novo tipo de dados BOOLEAN, que permite usar colunas ou variáveis verdadeiramente booleanas, em vez de simular com um valor numérico. A possibilidade de escrever predicados booleanos simplifica a sintaxe das instruções SQL.
Veja um exemplo:
-- Criando uma tabela com uma coluna booleana
CREATE TABLE funcionarios (
id NUMBER PRIMARY KEY,
nome VARCHAR2(50) NOT NULL,
salario NUMBER NOT NULL,
ativo BOOLEAN NOT NULL
);
-- Inserindo alguns dados na tabela
INSERT INTO funcionarios VALUES (1, 'Ana', 5000, TRUE);
INSERT INTO funcionarios VALUES (2, 'Bruno', 4000, FALSE);
INSERT INTO funcionarios VALUES (3, 'Carlos', 6000, TRUE);
INSERT INTO funcionarios VALUES (4, 'Daniela', 4500, FALSE);
-- Consultando os dados da tabela usando predicados booleanos
SELECT * FROM funcionarios WHERE ativo; -- Retorna os funcionários ativos
SELECT * FROM funcionarios WHERE NOT ativo; -- Retorna os funcionários inativos
SELECT * FROM funcionarios WHERE salario > 5000 AND ativo; -- Retorna os funcionários ativos com salário maior que 5000
O novo tipo de dados BOOLEAN também vem com a função TO_BOOLEAN(), que converte um valor para um valor booleano. Alguns valores textuais, como ‘TRUE’, ‘FALSE’, ‘YES’, ‘NO’, serão convertidos para um valor booleano. Qualquer valor numérico que não seja 0 será convertido para TRUE, e valores 0 para FALSE. Veja um exemplo:
-- Usando a função TO_BOOLEAN() para converter valores para booleanos
SELECT TO_BOOLEAN('TRUE') FROM DUAL; -- Retorna TRUE
SELECT TO_BOOLEAN('NO') FROM DUAL; -- Retorna FALSE
SELECT TO_BOOLEAN(1) FROM DUAL; -- Retorna TRUE
SELECT TO_BOOLEAN(0) FROM DUAL; -- Retorna FALSE
Cláusula FROM – agora opcional
O Oracle SQL 23c permite executar consultas SELECT sem uma cláusula FROM. Essa nova funcionalidade melhora a portabilidade e a facilidade de uso do código SQL para os desenvolvedores. Veja um exemplo:
-- Executando uma consulta SELECT sem uma cláusula FROM
SELECT SYSDATE, USER, 2 + 2 AS soma FROM DUAL; -- Antes do Oracle SQL 23c
SELECT SYSDATE, USER, 2 + 2 AS soma; -- A partir do Oracle SQL 23c
Apelidos na cláusula GROUP BY
O Oracle SQL 23c permite usar apelidos na cláusula GROUP BY de uma instrução SELECT. Isso evita a repetição de expressões longas ou complexas na cláusula GROUP BY e torna o código mais legível e conciso. Veja um exemplo:
-- Usando apelidos na cláusula GROUP BY
SELECT SUBSTR(nome, 1, 1) AS inicial, COUNT(*) AS quantidade
FROM funcionarios
GROUP BY inicial; -- Antes do Oracle SQL 23c era necessário usar GROUP BY SUBSTR(nome, 1, 1)
Grafos operacionais em SQL
O Oracle SQL 23c permite criar e consultar grafos operacionais diretamente no banco de dados Oracle, utilizando suas capacidades de segurança, alta disponibilidade e performance. Um grafo é uma estrutura de dados que representa entidades (vértices) e seus relacionamentos (arestas). Os grafos são úteis para modelar e analisar redes complexas, como redes sociais, rotas de transporte, recomendações de produtos, etc.
Veja um exemplo:
-- Criando uma tabela para armazenar os vértices do grafo
CREATE TABLE pessoas (
id NUMBER PRIMARY KEY,
nome VARCHAR2(50) NOT NULL,
idade NUMBER NOT NULL
);
-- Inserindo alguns dados na tabela de vértices
INSERT INTO pessoas VALUES (1, 'Alice', 25);
INSERT INTO pessoas VALUES (2, 'Bob', 30);
INSERT INTO pessoas VALUES (3, 'Charlie', 35);
INSERT INTO pessoas VALUES (4, 'David', 40);
INSERT INTO pessoas VALUES (5, 'Eve', 45);
-- Criando uma tabela para armazenar as arestas do grafo
CREATE TABLE amizades (
id NUMBER PRIMARY KEY,
pessoa1 NUMBER NOT NULL REFERENCES pessoas(id),
pessoa2 NUMBER NOT NULL REFERENCES pessoas(id),
desde DATE NOT NULL
);
-- Inserindo alguns dados na tabela de arestas
INSERT INTO amizades VALUES (1, 1, 2, DATE '2020-01-01'); -- Alice e Bob são amigos desde 2020-01-01
INSERT INTO amizades VALUES (2, 1, 3, DATE '2020-02-01'); -- Alice e Charlie são amigos desde 2020-02-01
INSERT INTO amizades VALUES (3, 2, 3, DATE '2020-03-01'); -- Bob e Charlie são amigos desde 2020-03-01
INSERT INTO amizades VALUES (4, 3, 4, DATE '2020-04-01'); -- Charlie e David são amigos desde 2020-04-01
INSERT INTO amizades VALUES (5, 4, 5, DATE '2020-05-01'); -- David e Eve são amigos desde 2020-05-01
-- Criando um grafo a partir das tabelas de vértices e arestas
CREATE PROPERTY GRAPH pg_amigos ON SCHEMA hr (
VERTEX TABLES (
pessoas KEY(id) PROPERTIES(nome, idade)
),
EDGE TABLES (
amizades KEY(id) SOURCE KEY(pessoa1) REFERENCES pessoas TARGET KEY(pessoa2) REFERENCES pessoas PROPERTIES(desde)
)
);
-- Consultando o grafo usando a linguagem PGQL
SELECT a.nome AS amigo1, b.nome AS amigo2
FROM MATCH (a)-[e]->(b) ON pg_amigos
WHERE a.idade > b.idade; -- Retorna os pares de amigos em que o primeiro tem idade maior que o segundo
-- Consultando o grafo usando a linguagem SQL/PGQL
SELECT a.nome AS amigo1, b.nome AS amigo2
FROM pessoas a CROSS JOIN LATERAL (
SELECT b.nome FROM pg_amigos.PG_EDGES e JOIN pessoas b ON e.TARGET = b.id WHERE e.SOURCE = a.id AND a.idade > b.idade
) b; -- Retorna os pares de amigos em que o primeiro tem idade maior que o segundo
Stored Procedures em JavaScript
O Oracle SQL 23c permite criar Stored Procedures usando JavaScript no banco de dados. Essa funcionalidade também permite aos desenvolvedores aproveitar o grande número de bibliotecas JavaScript disponíveis.
Veja um exemplo:
-- Criando um módulo JavaScript com uma função para calcular o fatorial de um número
CREATE OR REPLACE MODULE factorial.js IS {
function factorial(n) {
if (n == 0 || n == 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}
};
-- Criando uma especificação PL/SQL para chamar a função JavaScript do módulo
CREATE OR REPLACE FUNCTION factorial(n NUMBER) RETURN NUMBER IS LANGUAGE JAVASCRIPT NAME 'factorial.js.factorial(n)';
-- Chamando a função PL/SQL que invoca a função JavaScript
SELECT factorial(5) FROM DUAL; -- Retorna 120
Reservas sem bloqueio de colunas
As reservas sem bloqueio de colunas permitem que os aplicativos reservem parte de um valor em uma coluna sem bloquear a linha; por exemplo, reservar parte de um saldo de conta bancária ou reservar um item em estoque sem bloquear todas as outras operações na conta ou no item. As reservas sem bloqueio são mantidas nas linhas em vez de bloqueá-las. Elas verificam se as atualizações podem ter sucesso e adiam as atualizações até o momento do commit da transação.
Veja um exemplo de como usar as reservas sem bloqueio de colunas:
-- Criando uma tabela para armazenar os dados de contas bancárias
CREATE TABLE contas (
id NUMBER PRIMARY KEY,
titular VARCHAR2(50) NOT NULL,
saldo NUMBER NOT NULL
);
-- Inserindo alguns dados na tabela de contas
INSERT INTO contas VALUES (1, 'Alice', 1000);
INSERT INTO contas VALUES (2, 'Bob', 2000);
INSERT INTO contas VALUES (3, 'Charlie', 3000);
-- Criando uma função PL/SQL para transferir dinheiro entre contas usando reservas sem bloqueio
CREATE OR REPLACE FUNCTION transferir(origem NUMBER, destino NUMBER, valor NUMBER) RETURN BOOLEAN IS
BEGIN
-- Reservando o valor da conta de origem sem bloquear a linha
UPDATE contas SET saldo = saldo - valor WHERE id = origem AND saldo >= valor RETURNING ROWID INTO NOLOCK;
IF SQL%ROWCOUNT = 0 THEN -- Se a reserva falhar, retorna falso e cancela a transação
RETURN FALSE;
END IF;
-- Reservando o valor da conta de destino sem bloquear a linha
UPDATE contas SET saldo = saldo + valor WHERE id = destino RETURNING ROWID INTO NOLOCK;
IF SQL%ROWCOUNT = 0 THEN -- Se a reserva falhar, retorna falso e cancela a transação
RETURN FALSE;
END IF;
-- Confirmando as reservas no momento do commit da transação
COMMIT NOLOCK;
RETURN TRUE; -- Se as reservas forem bem sucedidas, retorna verdadeiro e confirma a transação
EXCEPTION
WHEN OTHERS THEN -- Em caso de qualquer erro, retorna falso e cancela a transação
ROLLBACK;
RETURN FALSE;
END;
-- Chamando a função PL/SQL para transferir dinheiro entre contas
SELECT transferir(1, 2, 500) FROM DUAL; -- Retorna TRUE e transfere 500 da conta 1 para a conta 2
SELECT transferir(2, 3, 3000) FROM DUAL; -- Retorna FALSE e não transfere nada, pois a conta 2 não tem saldo suficiente
Conclusão
O Oracle SQL 23c traz muitas novidades que podem facilitar e melhorar o trabalho dos desenvolvedores que usam o banco de dados Oracle. Neste artigo, vimos algumas dessas novidades, como o tipo de dados BOOLEAN, a cláusula FROM opcional, os apelidos na cláusula GROUP BY, os grafos operacionais em SQL, as stored procedures em JavaScript e as reservas sem bloqueio de colunas. Essas funcionalidades podem tornar o código SQL mais simples, mais legível, mais portável e mais performático.
Espero que este artigo tenha sido útil e que você possa aproveitar as novidades do Oracle SQL 23c em seus projetos.
Abs
Fontes