Usando Registros e Cursores
O conteúdo do script nesta página é para navegação apenas e não altera o conteúdo de nenhuma forma.
Você pode armazenar valores de dados em registros e usar um cursor como um ponteiro para um conjunto de resultados e informações de processamento relacionadas.
Consulte Também: Referência da Linguagem PL/SQL do Oracle Database para mais informações sobre registros
Sobre Registros
Um registro é uma variável composta PL/SQL que pode armazenar valores de dados de tipos diferentes. Você pode tratar componentes internos (campos) como variáveis escalares. Você pode passar registros inteiros como parâmetros de subprograma. Os registros são úteis para manter dados de linhas de tabelas, ou de determinadas colunas das linhas da tabela.
Um registro é uma variável composta PL/SQL que pode armazenar valores de dados de diferentes tipos, semelhantes a um tipo de estrutura em C, C++ ou Java. Os componentes internos de um registro são chamados campos. Para acessar um campo de registro, você usa notação de ponto : record_name.field_name.
É possível tratar campos de registro como variáveis escalares. Você também pode passar registros inteiros como parâmetros de subprograma.
Os registros são úteis para manter dados de linhas de tabelas, ou de determinadas colunas das linhas da tabela. Cada campo de registro corresponde a uma coluna da tabela.
Existem três maneiras de criar um registro:
-
Declare um tipo RECORD e declare uma variável desse tipo.
Use a seguinte sintaxe:
TYPE record_name IS RECORD ( field_name data_type [:= initial_value] [, field_name data_type [:= initial_value ] ]... ); variable_name record_name; -
Declare uma variável do tipo table_name%ROWTYPE.
Os campos do registro têm os mesmos nomes e tipos de dados das colunas da tabela.
-
Declare uma variável do tipo cursor_name%ROWTYPE.
Os campos do registro têm os mesmos nomes e tipos de dados que as colunas da tabela na cláusula FROM da instrução SELECT do cursor.
Consulte também:
-
Referência de Linguagem PL/SQL do Oracle Database para mais informações sobre como definir tipos RECORD e declarar registros desse tipo
-
Referência de Linguagem PL/SQL do Oracle Database para a sintaxe de uma definição de tipo RECORD
-
Referência de Linguagem do Oracle Database PL/SQL para mais informações sobre o atributo %ROWTYPE
-
Referência de Linguagem do Oracle Database PL/SQL para a sintaxe do atributo %ROWTYPE
Tutorial: Declarando um Tipo de REGISTRO
As etapas a seguir mostram como usar a Edição da ferramenta SQL Developer para declarar um tipo RECORD, sal_info, cujos campos podem conter informações de salário para um funcionário—ID da tarefa, salário mínimo e máximo para esse ID da tarefa, salário atual e aumento sugerido.
Etapas para declarar RECORD type sal_info:
-
No quadro Conexões, expanda hr_conn.
No ícone hr_conn, uma lista de tipos de objeto de esquema é exibida.
-
Expanda Pacotes.
É exibida uma lista de pacotes.
-
Clique com o mouse em EMP_EVAL.
Uma lista de opções é exibida.
-
Selecione Editar.
O painel EMP_EVAL é aberto, mostrando a instrução
CREATE PACKAGEque criou o pacote:CREATE OR REPLACE PACKAGE EMP_EVAL AS PROCEDURE eval_department(dept_id IN NUMBER); FUNCTION calculate_score(evaluation_id IN NUMBER , performance_id IN NUMBER) RETURN NUMBER; END EMP_EVAL; -
No painel EMP_EVAL, imediatamente antes do
END EMP_EVAL, adicione este código:TYPE sal_info IS RECORD ( j_id jobs.job_id%type , sal_min jobs.min_salary%type , sal_max jobs.max_salary%type , sal employees.salary%type , sal_raise NUMBER(3,3) );O título do painel está em itálico, indicando que as alterações não foram salvas no banco de dados.
-
Selecione o ícone Compilar.
A especificação de package alterada é compilada e salva no banco de dados. O título do painel EMP_EVAL não está mais na fonte em itálico.
Agora você pode declarar registros do tipo sal_info, como em "Tutorial: Criando e Chamando um Subprograma com um Parâmetro de Registro".
Tutorial: Criando e Chamando um Subprograma com um Parâmetro de Registro
As etapas a seguir mostram como usar a ferramenta de Edição do SQL Developer para criar e chamar um subprograma com um parâmetro do tipo de registro sal_info.
O tipo de registro sal_info foi criado no "Tutorial: Declaring a RECORD Type".
Este tutorial mostra como usar a ferramenta Editar do SQL Developer para concluir as seguintes tarefas:
-
Crie um procedimento, SALARY_SCHEDULE, que tenha um parâmetro do tipo
sal_info. -
Altere a função EVAL_FREQUENCY para que declare um registro, emp_sal, do tipo
sal_info, preencha seus campos e passe-o para o procedimento SALARY_SCHEDULE.
Como EVAL_FREQUENCY chamará SALARY_SCHEDULE, a declaração SALARY_SCHEDULE deverá preceder a declaração EVAL_FREQUENCY (caso contrário, o pacote não será compilado). No entanto, a definição de SALARY_SCHEDULE pode ser qualquer lugar no corpo do pacote.
Etapas para criar SALARY_SCHEDULE e alterar EVAL_FREQUENCY:
-
No quadro Conexões, expanda hr_conn.
-
Na lista de tipos de objeto de esquema, expanda Pacotes.
-
Na lista de pacotes, expanda EMP_EVAL.
-
Na lista de opções, clique com o botão direito do mouse em Corpo EMP_EVAL.
-
Na lista de opções, selecione Editar.
O painel Corpo EMP_EVAL é exibido, mostrando o código do corpo do pacote.
-
No painel Corpo de EMP_EVAL, imediatamente antes da
END EMP_EVAL, adicione a seguinte definição do procedimento SALARY_SCHEDULE:PROCEDURE salary_schedule (emp IN sal_info) AS accumulating_sal NUMBER; BEGIN DBMS_OUTPUT.PUT_LINE('If salary ' || emp.sal || ' increases by ' || ROUND((emp.sal_raise * 100),0) || '% each year, it will be:'); accumulating_sal := emp.sal; WHILE accumulating_sal <= emp.sal_max LOOP accumulating_sal := accumulating_sal * (1 + emp.sal_raise); DBMS_OUTPUT.PUT_LINE(ROUND(accumulating_sal,2) ||', '); END LOOP; END salary_schedule;O título do painel está em itálico, indicando que as alterações não foram salvas no banco de dados.
-
No painel Corpo EMP_EVAL, insira a função eval_frequency e os procedimentos salary_schedule e add_eval na seguinte posição:
CREATE OR REPLACE PACKAGE BODY EMP_EVAL AS FUNCTION eval_frequency (emp_id EMPLOYEES.EMPLOYEE_ID%TYPE) RETURN PLS_INTEGER; PROCEDURE salary_schedule(emp IN sal_info); PROCEDURE add_eval(employee_id IN employees.employee_id%type, today IN DATE); PROCEDURE eval_department (dept_id IN NUMBER) AS -
Edite a função
EVAL_FREQUENCY, fazendo as seguintes alterações:FUNCTION eval_frequency (emp_id EMPLOYEES.EMPLOYEE_ID%TYPE) RETURN PLS_INTEGER AS h_date EMPLOYEES.HIRE_DATE%TYPE; today EMPLOYEES.HIRE_DATE%TYPE; eval_freq PLS_INTEGER; emp_sal SAL_INFO; -- replaces sal, sal_raise, and sal_max BEGIN SELECT SYSDATE INTO today FROM DUAL; SELECT HIRE_DATE INTO h_date FROM EMPLOYEES WHERE EMPLOYEE_ID = eval_frequency.emp_id; IF ((h_date + (INTERVAL '120' MONTH)) < today) THEN eval_freq := 1; /* populate emp_sal */ SELECT j.JOB_ID, j.MIN_SALARY, j.MAX_SALARY, e.SALARY INTO emp_sal.j_id, emp_sal.sal_min, emp_sal.sal_max, emp_sal.sal FROM EMPLOYEES e, JOBS j WHERE e.EMPLOYEE_ID = eval_frequency.emp_id AND j.JOB_ID = eval_frequency.emp_id; emp_sal.sal_raise := 0; -- default CASE emp_sal.j_id WHEN 'PU_CLERK' THEN emp_sal.sal_raise := 0.08; WHEN 'SH_CLERK' THEN emp_sal.sal_raise := 0.07; WHEN 'ST_CLERK' THEN emp_sal.sal_raise := 0.06; WHEN 'HR_REP' THEN emp_sal.sal_raise := 0.05; WHEN 'PR_REP' THEN emp_sal.sal_raise := 0.05; WHEN 'MK_REP' THEN emp_sal.sal_raise := 0.04; ELSE NULL; END CASE; IF (emp_sal.sal_raise != 0) THEN salary_schedule(emp_sal); END IF; ELSE eval_freq := 2; END IF; RETURN eval_freq; END eval_frequency; -
Selecione Compilar.
Sobre Cursores
Ao executar uma instrução SQL, o Oracle Database armazena o conjunto de resultado e processa informações em uma área SQL privada sem nome. Um ponteiro para essa área não nomeada, chamada de cursor, permite recuperar o conjunto de resultados uma linha por vez. Atributos do cursor retornam informações sobre o estado do cursor.
Toda vez que você executa uma instrução SQL DML ou uma instrução PL/SQL SELECT INTO, a PL/SQL abre um cursor implícito. Você pode obter informações sobre esse cursor ou sobre seus atributos, mas não é possível controlá-lo. Após a execução da instrução, o banco de dados fecha o cursor; no entanto, os valores do atributo permanecem disponíveis até outra instrução DML ou SELECT INTO ser executada.
O PL/SQL também permite declarar cursores. Um cursor declarado tem um nome e é associado a uma consulta (instrução SQL SELECT), geralmente uma que retorna várias linhas. Depois de declarar um cursor, você deve processá-lo, implícita ou explicitamente. Para processar o cursor implicitamente, use um cursor FOR LOOP. A sintaxe é:
FOR record_name IN cursor_name LOOP
statement
[ statement ]...
END LOOP;
Para processar o cursor explicitamente, abra-o (com a instrução OPEN), extraia linhas do conjunto de resultados uma de cada vez ou em massa (com a instrução FETCH) e feche o cursor (com a instrução CLOSE). Depois de fechar o cursor, não será possível extrair registros do conjunto de resultados nem ver os valores de atributo do cursor.
A sintaxe para o valor de um atributo de cursor implícito é SQL%attribute (por exemplo, SQL%FOUND). SQL%attribute sempre se refere à instrução DML ou SELECT INTO executada mais recentemente.
A sintaxe para o valor de um atributo de cursor declarado é cursor_name%attribute (por exemplo, c1%FOUND). A Tabela 1 lista os atributos do cursor e os valores que eles podem retornar. (Cursores implícitos têm atributos adicionais que estão além do escopo deste documento.)
Tabela 1 - Valores de Atributo do Cursor
| Atributo | Valores para Cursor Declarado | Valores para Cursor Implícito |
|---|---|---|
| %ENCONTRADO | Se o cursor estiver aberto (Nota de Rodapé 1), mas não houver tentativa de extração, NULO. Se a extração mais recente retornar uma linha, VERDADEIRO. Se a extração mais recente não tiver retornado uma linha, FALSO. |
Se nenhuma instrução DML ou SELECT INTO tiver sido executada, NULL. Se a instrução DML ou SELECT INTO mais recente tiver retornado uma linha TRUE. Se a instrução DML ou SELECT INTO mais recente não tiver retornado uma linha, FALSO. |
| %NÃO ENCONTRADO | Se o cursor estiver aberto (Nota de Rodapé 1), mas não houver tentativa de extração, NULO. Se a extração mais recente tiver retornado uma linha, FALSO. Se a extração mais recente não tiver retornado uma linha, TRUE. |
Se nenhuma instrução DML ou SELECT INTO tiver sido executada, NULL. Se a instrução DML ou SELECT INTO mais recente tiver retornado uma linha, Se a instrução DML ou SELECT INTO mais recente não tiver retornado uma linha, |
| %CONTAGEM DE LINHAS | Se o cursor estiver aberto (Nota de Rodapé 1), um número maior ou igual a zero. | NULL se nenhuma instrução DML ou SELECT INTO for executada; caso contrário, um número maior ou igual a zero. |
| %ISABERTO | Se o cursor estiver aberto, TRUE; caso contrário, FALSE. | Sempre FALSO. |
Rodapé 1: Se o cursor não estiver aberto, o atributo gerará a exceção predefinida INVALID_CURSOR.
Consulte também:
-
Referência de Linguagem PL/SQL do Oracle Database para saber mais sobre a instrução SELECT INTO
-
Referência de Linguagem PL/SQL do Oracle Database para mais informações sobre o gerenciamento de cursores em PL/SQL
Usando um Cursor Declarado para Recuperar Linhas do Conjunto de Resultados Um de Cada Vez
Você pode usar um cursor declarado para recuperar as linhas do conjunto de resultados, uma de cada vez.
O procedimento a seguir usa cada instrução necessária na sua forma mais simples, mas fornece referências à sua sintaxe completa.
Etapas para usar um cursor declarado a fim de recuperar as linhas do conjunto de resultados, uma de cada vez:
-
Na parte declarativa:
-
Declare o cursor:
CURSOR cursor_name IS query;Para obter a sintaxe completa da declaração de cursor declarada, consulte Referência da Linguagem PL/SQL do Oracle Database.
-
Declare um registro para armazenar a linha retornada pelo cursor:
record_name cursor_name%ROWTYPE;Para obter uma sintaxe completa do %ROWTYPE, consulte Referência de Linguagem PL/SQL do Oracle Database.
-
-
Na parte executável:
-
Abra o cursor:
OPEN cursor_name;Para obter uma sintaxe completa da instrução OPEN, consulte Referência da Linguagem PL/SQL do Oracle Database.
-
Extraia linhas do cursor (linhas do grupo de resultados) uma de cada vez, usando uma instrução LOOP que tenha sintaxe semelhante à seguinte:
LOOP FETCH cursor_name INTO record_name; EXIT WHEN cursor_name%NOTFOUND; -- Process row that is in record_name: statement; [ statement; ]... END LOOP;Para obter toda a sintaxe da instrução FETCH, consulte Referência de Linguagem PL/SQL do Oracle Database.
-
Feche o cursor:
CLOSE cursor_name;
-
Para obter uma sintaxe completa da instrução CLOSE, consulte Referência de Linguagem PL/SQL do Oracle Database.
Tutorial: Usando Um Cursor Declarado para Recuperar Linhas do Conjunto de Resultados Uma de Cada Vez
As etapas a seguir mostram como implementar o procedimento EMP_EVAL.EVAL_DEPARTMENT, que usa um cursor declarado, emp_cursor.
Etapas para implementar o procedimento EMP_EVAL.EVAL_DEPARTMENT:
-
Na especificação do pacote EMP_EVAL, altere a declaração do procedimento EVAL_DEPARTMENT conforme mostrado:
PROCEDURE eval_department(dept_id IN employees.department_id%TYPE); -
No corpo do pacote EMP_EVAL, altere a definição do procedimento EVAL_DEPARTMENT conforme mostrado no seguinte exemplo:
PROCEDURE eval_department (dept_id IN employees.department_id%TYPE) AS CURSOR emp_cursor IS SELECT * FROM EMPLOYEES WHERE DEPARTMENT_ID = eval_department.dept_id; emp_record EMPLOYEES%ROWTYPE; -- for row returned by cursor all_evals BOOLEAN; -- true if all employees in dept need evaluations today DATE; BEGIN today := SYSDATE; IF (EXTRACT(MONTH FROM today) < 6) THEN all_evals := FALSE; -- only new employees need evaluations ELSE all_evals := TRUE; -- all employees need evaluations END IF; OPEN emp_cursor; DBMS_OUTPUT.PUT_LINE ( 'Determining evaluations necessary in department # ' || dept_id ); LOOP FETCH emp_cursor INTO emp_record; EXIT WHEN emp_cursor%NOTFOUND; IF all_evals THEN add_eval(emp_record.employee_id, today); ELSIF (eval_frequency(emp_record.employee_id) = 2) THEN add_eval(emp_record.employee_id, today); END IF; END LOOP; DBMS_OUTPUT.PUT_LINE('Processed ' || emp_cursor%ROWCOUNT || ' records.'); CLOSE emp_cursor; END eval_department;(Para obter um exemplo passo-a-passo de como alterar o corpo de um pacote, consulte "Tutorial: Declarando Variáveis e Constantes em um Subprograma").
-
Compile a especificação do pacote EMP_EVAL.
-
Compile o corpo de pacote EMP_EVAL.
Sobre Variáveis do Cursor
Uma variável de cursor é como um cursor que não se limita a uma consulta. É possível abrir uma variável do cursor para uma consulta, processar o conjunto de resultados e usar a variável do cursor para outra consulta. As variáveis do cursor são úteis para transmitir resultados de consulta entre subprogramas.
Para obter informações sobre cursores, consulte "About Cursors".
Para declarar uma variável do CURSOR, declare um tipo REF CURSOR e, em seguida, declare uma variável desse tipo (portanto, uma variável do CURSOR é frequentemente chamada de REF CURSOR). Um tipo CURSOR REF pode ser forte ou fraco.
Um tipo de CURSOR de REF forte especifica um tipo de retorno, que é o tipo RECORD de suas variáveis de CURSOR. O compilador PL/SQL não permite que você use essas variáveis de cursor fortemente digitadas para consultas que retornam linhas que não são do tipo retorno. Tipos de CURSOR REF fortes são menos propensos a erros que os fracos, mas os fracos são mais flexíveis.
Um tipo de CURSOR de REF fraco não especifica um tipo de retorno. O compilador PL/SQL aceita variáveis de cursor digitadas fracamente em qualquer consulta. Os tipos de CURSOR de REF fracos são intercambiáveis; portanto, em vez de criar tipos de CURSOR de REF fracos, você pode usar o tipo predefinido SYS_REFCURSOR de CURSOR fraco.
Depois de declarar uma variável do cursor, você deve abri-la para uma consulta específica (com a instrução OPEN FOR), extrair linhas, uma de cada vez, do grupo de resultados (com a instrução FETCH) e, em seguida, fechar o cursor (com a instrução CLOSE) ou abri-lo para outra consulta específica (com a instrução OPEN FOR). Abrir a variável de cursor para outra consulta a fecha para a consulta anterior. Depois de fechar uma variável de cursor para uma consulta específica, não é possível extrair registros do conjunto de resultados dessa consulta nem ver os valores de atributo do cursor para essa consulta.
Consulte também:
-
Referência de Linguagem PL/SQL do Oracle Database para mais informações sobre como usar variáveis de cursor
-
Referência de Linguagem PL/SQL do Oracle Database para a sintaxe da declaração da variável do cursor
Usando uma Variável de Cursor para Recuperar Linhas do Conjunto de Resultados Uma por Vez
Você pode usar uma variável de cursor para recuperar as linhas do conjunto de resultados uma de cada vez.
O procedimento seguinte usa cada uma das instruções necessárias em sua forma mais simples, mas fornece referências à sua sintaxe completa.
Etapas para usar uma variável de cursor para recuperar as linhas do conjunto de resultados uma de cada vez:
-
Na parte declarativa:
-
Declare o tipo de CURSOR REF:
TYPE cursor_type IS REF CURSOR [ RETURN return_type ];Para obter a sintaxe completa da declaração de tipo REF CURSOR, consulte Referência de Linguagem PL/SQL do Oracle Database.
-
Declare uma variável de cursor desse tipo:
cursor_variable cursor_type;Para obter a sintaxe completa da declaração da variável de cursor, consulte Referência da Linguagem PL/SQL do Oracle Database.
-
Declare um registro para armazenar a linha retornada pelo cursor:
record_name return_type;Para obter informações completas sobre sintaxe de declaração do registro, consulte Referência de Linguagem PL/SQL do Oracle Database.
-
-
Na parte executável:
-
Abra a variável de cursor para uma consulta específica:
OPEN cursor_variable FOR query;Para obter informações completas sobre uma sintaxe de instrução OPEN FOR, consulte Referência de Linguagem PL/SQL do Oracle Database.
-
Extraia linhas da variável do cursor (linhas do grupo de resultados) uma de cada vez, usando uma instrução LOOP que tenha sintaxe semelhante a esta:
LOOP FETCH cursor_variable INTO record_name; EXIT WHEN cursor_variable%NOTFOUND; -- Process row that is in record_name: statement; [ statement; ]... END LOOP;Para obter informações completas sobre uma sintaxe de instrução FETCH, consulte Referência de Linguagem PL/SQL do Oracle Database.
-
Feche a variável de cursor:
CLOSE cursor_variable;Alternativamente, é possível abrir a variável de cursor para outra consulta, que a fecha para a consulta atual.
Para obter informações completas sobre uma sintaxe de instrução CLOSE, consulte Referência de Linguagem PL/SQL do Oracle Database.
-
Tutorial: Usando uma Variável do Cursor para Recuperar as Linhas do Conjunto de Resultados Uma por Vez
Esta etapa mostra como alterar o procedimento EMP_EVAL.EVAL_DEPARTMENT para que ele use uma variável de cursor em vez de um cursor declarado (que permite processar vários departamentos) e como tornar EMP_EVAL.EVAL_DEPARTMENT e EMP_EVAL.ADD_EVAL mais eficientes.
Como este tutorial torna EMP_EVAL.EVAL_DEPARTMENT e EMP_EVAL.ADD_EVAL mais eficientes: Em vez de passar um campo de um registro para ADD_EVAL e fazer com que ADD_EVAL use três consultas para extrair outros três campos do mesmo registro, EVAL_DEPARTMENT passa todo o registro para ADD_EVAL e ADD_EVAL usa notação de pontos para acessar os valores dos outros três campos.
Etapas para alterar o procedimento EMP_EVAL.EVAL_DEPARTMENT a fim de usar uma variável de cursor:
-
Na especificação do pacote EMP_EVAL, adicione a declaração de procedimento e a definição de tipo REF CURSOR, conforme mostrado no seguinte exemplo:
CREATE OR REPLACE PACKAGE emp_eval AS PROCEDURE eval_department (dept_id IN employees.department_id%TYPE); PROCEDURE eval_everyone; FUNCTION calculate_score(eval_id IN scores.evaluation_id%TYPE , perf_id IN scores.performance_id%TYPE) RETURN NUMBER; TYPE SAL_INFO IS RECORD ( j_id jobs.job_id%type , sal_min jobs.min_salary%type , sal_max jobs.max_salary%type , salary employees.salary%type , sal_raise NUMBER(3,3)); TYPE emp_refcursor_type IS REF CURSOR RETURN employees%ROWTYPE; END emp_eval; -
No corpo do pacote EMP_EVAL, adicione uma declaração de encaminhamento para o procedimento EVAL_LOOP_CONTROL e altere a declaração do procedimento ADD_EVAL, conforme mostrado:
CREATE OR REPLACE PACKAGE BODY EMP_EVAL AS FUNCTION eval_frequency (emp_id IN EMPLOYEES.EMPLOYEE_ID%TYPE) RETURN PLS_INTEGER; PROCEDURE salary_schedule(emp IN sal_info); PROCEDURE add_eval(emp_record IN EMPLOYEES%ROWTYPE, today IN DATE); PROCEDURE eval_loop_control(emp_cursor IN emp_refcursor_type); ...(Para obter um exemplo passo-a-passo de como alterar o corpo de um pacote, consulte "Tutorial: Declarando Variáveis e Constantes em um Subprograma").
-
Altere o procedimento EVAL_DEPARTMENT para recuperar três conjuntos de resultado separados com base no departamento e chamar o procedimento EVAL_LOOP_CONTROL, conforme mostrado no seguinte exemplo:
PROCEDURE eval_department(dept_id IN employees.department_id%TYPE) AS emp_cursor emp_refcursor_type; current_dept departments.department_id%TYPE; BEGIN current_dept := dept_id; FOR loop_c IN 1..3 LOOP OPEN emp_cursor FOR SELECT * FROM employees WHERE current_dept = eval_department.dept_id; DBMS_OUTPUT.PUT_LINE ('Determining necessary evaluations in department #' || current_dept); eval_loop_control(emp_cursor); DBMS_OUTPUT.PUT_LINE ('Processed ' || emp_cursor%ROWCOUNT || ' records.'); CLOSE emp_cursor; current_dept := current_dept + 10; END LOOP; END eval_department; -
Altere o procedimento ADD_EVAL conforme mostrado:
PROCEDURE add_eval(emp_record IN employees%ROWTYPE, today IN DATE) AS -- (Delete local variables) BEGIN INSERT INTO EVALUATIONS ( evaluation_id, employee_id, evaluation_date, job_id, manager_id, department_id, total_score ) VALUES ( evaluations_sequence.NEXTVAL, -- evaluation_id emp_record.employee_id, -- employee_id today, -- evaluation_date emp_record.job_id, -- job_id emp_record.manager_id, -- manager_id emp_record.department_id, -- department_id 0 -- total_score ); END add_eval; -
Antes do
END EMP_EVAL, adicione o seguinte procedimento, que extrai os registros individuais do grupo de resultados e os processa:PROCEDURE eval_loop_control (emp_cursor IN emp_refcursor_type) AS emp_record EMPLOYEES%ROWTYPE; all_evals BOOLEAN; today DATE; BEGIN today := SYSDATE; IF (EXTRACT(MONTH FROM today) < 6) THEN all_evals := FALSE; ELSE all_evals := TRUE; END IF; LOOP FETCH emp_cursor INTO emp_record; EXIT WHEN emp_cursor%NOTFOUND; IF all_evals THEN add_eval(emp_record, today); ELSIF (eval_frequency(emp_record.employee_id) = 2) THEN add_eval(emp_record, today); END IF; END LOOP; END eval_loop_control; -
Antes da
END EMP_EVAL, adicione o seguinte procedimento, que recupera um conjunto de resultado que contém todos os funcionários da empresa:PROCEDURE eval_everyone AS emp_cursor emp_refcursor_type; BEGIN OPEN emp_cursor FOR SELECT * FROM employees; DBMS_OUTPUT.PUT_LINE('Determining number of necessary evaluations.'); eval_loop_control(emp_cursor); DBMS_OUTPUT.PUT_LINE('Processed ' || emp_cursor%ROWCOUNT || ' records.'); CLOSE emp_cursor; END eval_everyone; -
Compile a especificação do pacote
EMP_EVAL. -
Compile o corpo de pacote
EMP_EVAL.