Você está na página 1de 12

Complemento

DELETE . . . RETURNING
Esta opo do comando DELETE permite ler valores de linhas deletadas, eliminando a necessidade de fazer um SELECT antes do DELETE.
Exemplo : DECLARE my_empno emp.empno%TYPE; my_ename emp.ename%TYPE; my_job emp.job%TYPE; BEGIN ... DELETE FROM emp WHERE empno = my_empno RETURNING ename, job INTO my_ename, my_job; END;

UPDATE . . . RETURNING
Esta opo do comando UPDATE permite ler o valor modificado das linhas alteradas, eliminando a necessidade de fazer um SELECT aps o UPDATE.
Exemplo :
DECLARE my_sal emp.sal%TYPE; my_ename emp.ename%TYPE; BEGIN ... UPDATE emp SET sal = sal + 500 WHERE ename = MILLER RETURNING sal, ename INTO my_sal, my_ename; ... END;

Abrindo Cursores
possvel abrir um cursor sem que ele esteja declarado, definindo a query diretamente no comando OPEN ou no FOR LOOP.
Exemplo : DECLARE bonus number(7,2); TYPE tipo_cursor IS REF CURSOR; emp_cv tipo_cursor; BEGIN FOR reg IN (SELECT cd_empr, vl_salario, vl_comissao FROM empregados) LOOP bonus := (reg.vl_salario * 0.05) + (reg.vl_comissao * 0.25); INSERT INTO bonus VALUES (reg.cd_empr, bonus); END LOOP; COMMIT; OPEN emp_cv FOR SELECT * FROM emp WHERE comm IS NOT NULL; ... END;

Abrindo Cursores (cont.)


Outra alternativa passar a query como uma string, no momento da abertura do cursor :
DECLARE TYPE tipo_cursor IS REF CURSOR; c_emp tipo_cursor; v_nm_empr varchar2(15); v_vl_salario number := 1000; BEGIN OPEN c_emp FOR SELECT nm_empr, vl_salario || FROM empregados || WHERE vl_salario > :s USING my_sal; ... END;

DBMS_SQL
A package DBMS_SQL permite executar qualquer comando DML ou DDL de maneira dinmica.
Exemplo : declare v_cursor v_sql v_vl_pedido vl_total v_linhas

number; varchar2(4000); pedido.vl_pedido%type; pedido.vl_pedido%type; number(10);

begin v_cursor := dbms_sql.open_cursor; v_sql := 'select vl_pedido from pedido'; dbms_sql.parse(v_cursor, v_sql, dbms_sql.native); dbms_sql.define_column(v_cursor, 1, v_vl_pedido); v_linhas := dbms_sql.execute(v_cursor); loop if dbms_sql.fetch_rows(v_cursor)>0 then dbms_sql.column_value(v_cursor, 1, v_vl_pedido); vl_total := vl_total + v_vl_pedido; else exit; end if end loop; dbms_sql.close_cursor(v_cursor); end;

Execute Immediate
O comando EXECUTE IMMEDIATE compila e executa um comando SQL dinmico.
Exemplo :
DECLARE sql_stmt VARCHAR2(200); plsql_block VARCHAR2(500); emp_id NUMBER(4) := 7566; salary NUMBER(7,2); dept_id NUMBER(2) := 50; dept_name VARCHAR2(14) := PERSONNEL; location VARCHAR2(13) := DALLAS; emp_rec emp%ROWTYPE; BEGIN EXECUTE IMMEDIATE CREATE TABLE bonus (id NUMBER, amt NUMBER); sql_stmt := INSERT INTO dept VALUES (:1, :2, :3); EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location; sql_stmt := SELECT * FROM emp WHERE empno = :id; EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id; (cont...)

Execute Immediate
Exemplo (cont.) :
... plsql_block := BEGIN emp_pkg.raise_salary(:id, :amt); END;; EXECUTE IMMEDIATE plsql_block USING 7788, 500; sql_stmt := UPDATE emp SET sal = 2000 || WHERE empno = :1 RETURNING sal INTO :2; EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary; EXECUTE IMMEDIATE DELETE FROM dept WHERE deptno = :num USING dept_id; EXECUTE IMMEDIATE ALTER SESSION SET SQL_TRACE TRUE; END;

Definindo Mensagens de Erro


A procedure RAISE_APPLICATION_ERROR permite criar erros no padro do Oracle (ORA-xxxxx). Sintaxe :
RAISE_APPLICATION_ERROR ( nmero_erro, mensagem_erro) onde : nmero_erro mensagem_erro

nmero especificado pelo usurio, entre -20000 e -20999 mensagem do erro especificada pelo usurio

Definindo Mensagens de Erro (cont.)


Exemplo : Quando tentar remover um funcionrio, verificar se ele existe.
CREATE OR REPLACE PROCEDURE remove_empregado (p_nr_empr IN empregados.nr_empr%type) IS BEGIN DELETE FROM empregados WHERE nr_empr = p_nr_empr; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR (-20200, Funcionrio no existe.); END IF; COMMIT; END remove_empregado; SQL> EXECUTE remove_empregado(9999); BEGIN remove_empregado(9999);END; * ERROR at line 1: ORA-20200:Funcionrio no existe.

Definindo Mensagens de Erro (cont.)


Exemplo :
CREATE OR REPLACE PROCEDURE insere_empregado (p_nm_empr IN empregados.nm_empr%type, p_ds_funcao IN empregados.ds_funcao%type, p_nr_chefe IN empregados.nr_chefe%type, p_vl_salario IN empregados.vl_salario%type) IS v_dt_admissao empregados.dt_admissao%type; v_vl_comissao empregados.vl_comissao%type; v_nr_depto empregados.nr_depto%type; BEGIN ... SELECT nr_depto INTO v_nr_depto /*mesmo departamento do gerente*/ FROM empregados WHERE nr_empr = p_nr_chefe; ... COMMIT WORK; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20201,Gerente invlido.); END insere_empregado; SQL> EXECUTE insere_empregado(SANDRA,ANALISTA,9999,1500); BEGIN insere_empregado(SANDRA,ANALISTA,9999,1500);END; * ERROR at line 1: ORA-20201:Gerente invlido.

UTL_FILE
A package UTL_FILE permite que programas PL/SQL leiam e gravem arquivos TXT no servidor Oracle.
Example : declare cursor c_produto is select nm_produto from produto order by 1; v_arq_destino v_buffer utl_file.file_type; varchar2(2000) := '' ;

begin
v_arq_destino := utl_file.fopen('c:\temp\', 'produto.txt', 'w'); for reg in c_produto loop utl_file.put_line(v_arq_destino,reg.nm_produto); end loop; utl_file.fclose(v_arq_destino); end;