Seção 1 – PL/SQL Fundamentos - Bloco Anônimo
Um bloco anônimo é um trecho de código PL/SQL executado uma única vez, sem ser armazenado no banco de dados.
Estrutura Básica:
DECLARE
-- Declarações de variáveis e constantes
BEGIN
-- Lógica principal
EXCEPTION
-- Tratamento de exceções
END;
Exemplo:
DECLARE
v_nome VARCHAR2(50) := 'João';
BEGIN
DBMS_OUTPUT.PUT_LINE('Olá, ' || v_nome);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Erro: ' || SQLERRM);
END;
Seção 2 – Declaração de Identificadores
Variáveis
DECLARE
v_id NUMBER := 10; -- Tipo NUMBER
v_data DATE := SYSDATE; -- Tipo DATE
v_texto VARCHAR2(100); -- Variável não inicializada
BEGIN
v_texto := 'Texto dinâmico';
END;
Constantes
DECLARE
c_pi CONSTANT NUMBER := 3.1415;
BEGIN
DBMS_OUTPUT.PUT_LINE('Valor de PI: ' || c_pi);
END;
Tipos de Dados
-
NUMBER
,VARCHAR2
,DATE
,BOOLEAN
, etc.
Variável Bind
Variáveis declaradas fora do bloco PL/SQL (em SQL*Plus ou SQL Developer):
VARIABLE g_id NUMBER
BEGIN
:g_id := 100;
END;
/
PRINT g_id;
Seção 3 – Sintaxe e Diretrizes
Exemplo com Função:
DECLARE
v_total NUMBER;
BEGIN
SELECT COUNT(*) INTO v_total FROM employees;
DBMS_OUTPUT.PUT_LINE('Total de empregados: ' || v_total);
END;
Blocos Aninhados:
DECLARE
v_global NUMBER := 1;
BEGIN
DECLARE
v_local NUMBER := 2;
BEGIN
DBMS_OUTPUT.PUT_LINE(v_global + v_local); -- Resultado: 3
END;
END;
Seção 4 – Comandos SQL no PL/SQL
SELECT INTO
DECLARE
v_nome employees.first_name%TYPE;
BEGIN
SELECT first_name INTO v_nome
FROM employees
WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE(v_nome);
END;
INSERT
BEGIN
INSERT INTO employees (employee_id, first_name, last_name)
VALUES (1000, 'Maria', 'Silva');
COMMIT;
END;
Cursor Implícito
BEGIN
UPDATE employees SET salary = salary * 1.1;
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' linhas atualizadas.');
END;
Seção 5 – Estruturas de Controle
IF-THEN-ELSE
DECLARE
v_nota NUMBER := 75;
BEGIN
IF v_nota >= 70 THEN
DBMS_OUTPUT.PUT_LINE('Aprovado');
ELSE
DBMS_OUTPUT.PUT_LINE('Reprovado');
END IF;
END;
CASE
DECLARE
v_dia VARCHAR2(10) := 'Segunda';
BEGIN
CASE v_dia
WHEN 'Segunda' THEN DBMS_OUTPUT.PUT_LINE('Dia útil');
ELSE DBMS_OUTPUT.PUT_LINE('Fim de semana');
END CASE;
END;
LOOP Básico
DECLARE
i NUMBER := 1;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE(i);
i := i + 1;
EXIT WHEN i > 5;
END LOOP;
END;
Seção 6 – Tipos Compostos (Records)
DECLARE
TYPE t_empregado IS RECORD (
id employees.employee_id%TYPE,
nome employees.first_name%TYPE
);
v_emp t_empregado;
BEGIN
SELECT employee_id, first_name INTO v_emp
FROM employees
WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE(v_emp.nome);
END;
%ROWTYPE
DECLARE
v_emp employees%ROWTYPE;
BEGIN
SELECT * INTO v_emp
FROM employees
WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE(v_emp.first_name);
END;
Seção 7 – Collections
Associative Array
DECLARE
TYPE t_nomes IS TABLE OF VARCHAR2(50) INDEX BY PLS_INTEGER;
v_lista t_nomes;
BEGIN
v_lista(1) := 'Maria';
v_lista(2) := 'João';
DBMS_OUTPUT.PUT_LINE(v_lista(1));
END;
Bulk Collect
DECLARE
TYPE t_emp_ids IS TABLE OF employees.employee_id%TYPE;
v_ids t_emp_ids;
BEGIN
SELECT employee_id BULK COLLECT INTO v_ids
FROM employees
WHERE department_id = 50;
DBMS_OUTPUT.PUT_LINE(v_ids.COUNT || ' registros.');
END;
Seção 8 – Cursor Explícito
Cursor com Parâmetros
DECLARE
CURSOR c_emp (p_dept_id NUMBER) IS
SELECT * FROM employees WHERE department_id = p_dept_id;
v_emp employees%ROWTYPE;
BEGIN
OPEN c_emp(50);
LOOP
FETCH c_emp INTO v_emp;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_emp.first_name);
END LOOP;
CLOSE c_emp;
END;
Seção 9 – Tratamento de Exceções
DECLARE
v_div NUMBER;
BEGIN
v_div := 10 / 0; -- Divisão por zero
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('Erro: Divisão por zero.');
END;
Seção 10 – Procedures
Criando uma Procedure
CREATE OR REPLACE PROCEDURE aumentar_salario (
p_emp_id IN NUMBER,
p_percentual IN NUMBER
) AS
BEGIN
UPDATE employees
SET salary = salary * (1 + p_percentual/100)
WHERE employee_id = p_emp_id;
COMMIT;
END aumentar_salario;
Chamando a Procedure:
BEGIN
aumentar_salario(100, 10); -- Aumenta 10% para o empregado 100
END;
Seção 11 – Funções
Criando uma Função
CREATE OR REPLACE FUNCTION calcular_idade (
p_data_nasc DATE
) RETURN NUMBER AS
v_idade NUMBER;
BEGIN
v_idade := TRUNC(MONTHS_BETWEEN(SYSDATE, p_data_nasc) / 12);
RETURN v_idade;
END calcular_idade;
Usando a Função em SQL:
SELECT first_name, calcular_idade(birth_date) AS idade
FROM employees;
Seção 12 – Packages
Package Specification
CREATE OR REPLACE PACKAGE pkg_emp AS
PROCEDURE aumentar_salario(p_emp_id NUMBER, p_percentual NUMBER);
FUNCTION calcular_idade(p_data_nasc DATE) RETURN NUMBER;
END pkg_emp;
Package Body
CREATE OR REPLACE PACKAGE BODY pkg_emp AS
PROCEDURE aumentar_salario(p_emp_id NUMBER, p_percentual NUMBER) IS
BEGIN
UPDATE employees
SET salary = salary * (1 + p_percentual/100)
WHERE employee_id = p_emp_id;
COMMIT;
END;
FUNCTION calcular_idade(p_data_nasc DATE) RETURN NUMBER IS
v_idade NUMBER;
BEGIN
v_idade := TRUNC(MONTHS_BETWEEN(SYSDATE, p_data_nasc) / 12);
RETURN v_idade;
END;
END pkg_emp;
Seção 13 – Triggers DML
Trigger a Nível de Linha
CREATE OR REPLACE TRIGGER trg_audit_salary
BEFORE UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
INSERT INTO salary_audit (employee_id, old_salary, new_salary)
VALUES (:OLD.employee_id, :OLD.salary, :NEW.salary);
END;
Seção 14 – Bulk Collect com LIMIT
DECLARE
TYPE t_emp_ids IS TABLE OF employees.employee_id%TYPE;
v_ids t_emp_ids;
CURSOR c_emp IS SELECT employee_id FROM employees;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp BULK COLLECT INTO v_ids LIMIT 100;
EXIT WHEN v_ids.COUNT = 0;
-- Processar 100 registros por vez
END LOOP;
CLOSE c_emp;
END;
Seção 15 – SQL Dinâmico
EXECUTE IMMEDIATE
DECLARE
v_sql VARCHAR2(200);
v_emp_id NUMBER := 100;
v_salary NUMBER;
BEGIN
v_sql := 'SELECT salary FROM employees WHERE employee_id = :id';
EXECUTE IMMEDIATE v_sql INTO v_salary USING v_emp_id;
DBMS_OUTPUT.PUT_LINE(v_salary);
END;
Seção 16 – LOBs (BLOB)
DECLARE
v_blob BLOB;
v_bfile BFILE := BFILENAME('DIR_IMAGENS', 'foto.jpg');
BEGIN
INSERT INTO imagens (id, imagem)
VALUES (1, EMPTY_BLOB())
RETURNING imagem INTO v_blob;
DBMS_LOB.OPEN(v_bfile, DBMS_LOB.LOB_READONLY);
DBMS_LOB.LOADFROMFILE(v_blob, v_bfile, DBMS_LOB.GETLENGTH(v_bfile));
DBMS_LOB.CLOSE(v_bfile);
COMMIT;
END;
Top comments (0)