Oracle: Как обернуть курсор внутри функции? - PullRequest
1 голос
/ 14 января 2020

Я работаю над заданием, и мне требуется поместить курсор в функцию. Теперь мой курсор работает нормально, но мне трудно поместить его в функцию, как я могу это сделать?

Предполагается, что функция имеет тот же аргумент, что и курсор.

Код:

DECLARE
    CURSOR c_emp_salary (v_job_title VARCHAR2)
    IS
    SELECT employee_id, first_name, salary, min_salary FROM employees e JOIN jobs j ON
    e.job_id = j.job_id
    AND j.job_title = v_job_title;

    v_emp_id employees.employee_id%TYPE;
    v_emp_first_name employees.first_name%TYPE;
    v_emp_salary employees.salary%TYPE;
    v_min_salary jobs.min_salary%TYPE;

BEGIN
OPEN c_emp_salary('Shipping Clerk'); --I WANT THIS VALUE TO BE FROM A FUNCTION.

  LOOP
        FETCH c_emp_salary INTO v_emp_id, v_emp_first_name, v_emp_salary, v_min_salary;
        EXIT WHEN c_emp_salary%NOTFOUND;
        dbms_output.put_line('Employee ID: ' || v_emp_id);
        dbms_output.put_line('Employee First Name: ' || v_emp_first_name);
        dbms_output.put_line('Employee Salary: ' || v_emp_salary);
        dbms_output.put_line('Job Min Salary: ' || v_min_salary);
        dbms_output.put('Result? ');
        IF v_emp_salary = v_min_salary THEN dbms_output.put('Yes');
        ELSE dbms_output.put('No');
        END IF;
        dbms_output.put_line(NULL);
        dbms_output.put_line('++++++++++++++++++++++++');
  END LOOP;
END;  


Описание назначения : Напишите функцию, которая принимает job_title и проверяет всех сотрудников на этой работе, если у сотрудника зарплата равна min_salary. Print «yes» иначе выведите «нет». Используйте курсор

Ответы [ 3 ]

0 голосов
/ 14 января 2020

Полагаю, вам нужно что-то вроде:

(необходимо было заменить SCHEMA_NAME и FUNCTION_NAME)

(Если return не требуется, можно использовать процедуру и операторы return должны быть удалены)

(я не запускаю этот пример)

CREATE OR REPLACE function SCHEMA_NAME.FUNCTION_NAME( v_job_title VARCHAR2) return number is

    CURSOR c_emp_salary 
    IS
    SELECT employee_id, first_name, salary, min_salary FROM employees e JOIN jobs j ON
    e.job_id = j.job_id
    AND j.job_title = v_job_title;

    v_emp_id employees.employee_id%TYPE;
    v_emp_first_name employees.first_name%TYPE;
    v_emp_salary employees.salary%TYPE;
    v_min_salary jobs.min_salary%TYPE;

    result number;
BEGIN
  OPEN c_emp_salary('Shipping Clerk'); --I WANT THIS VALUE TO BE FROM A FUNCTION.

  LOOP
        FETCH c_emp_salary INTO v_emp_id, v_emp_first_name, v_emp_salary, v_min_salary;
        EXIT WHEN c_emp_salary%NOTFOUND;
        dbms_output.put_line('Employee ID: ' || v_emp_id);
        dbms_output.put_line('Employee First Name: ' || v_emp_first_name);
        dbms_output.put_line('Employee Salary: ' || v_emp_salary);
        dbms_output.put_line('Job Min Salary: ' || v_min_salary);
        dbms_output.put('Result? ');
        IF v_emp_salary = v_min_salary THEN 
             dbms_output.put('Yes');
             result := 1;
        ELSE dbms_output.put('No');
             result := 0;
        END IF;
        dbms_output.put_line(NULL);
        dbms_output.put_line('++++++++++++++++++++++++');
        return result;
  END LOOP;
END; 
0 голосов
/ 14 января 2020

ОП первоначально спросил:

Мне трудно поместить [курсор] в функцию, как я могу это сделать?

и

OPEN c_emp_salary('Shipping Clerk'); --I WANT THIS VALUE TO BE FROM A FUNCTION.

Приведенный ниже код решает проблему, изначально заданную в вопросе; он не предназначен для решения вопроса о назначении, который был отредактирован позднее, поскольку они не являются одним и тем же (что оставлено в качестве упражнения для OP).

Oracle Настройка :

CREATE TABLE employees (
  employee_id NUMBER,
  first_name  VARCHAR2(50),
  salary      NUMBER(10,2),
  job_id      NUMBER
);

CREATE TABLE jobs (
  job_id     NUMBER,
  job_title  VARCHAR2(50),
  min_salary NUMBER(10,2)
);

INSERT INTO employees VALUES ( 1, 'Alice', 300, 1 );
INSERT INTO jobs VALUES ( 1, 'Shipping Clerk', 200 );

PL / SQL Блок :

DECLARE
  v_emp_id         employees.employee_id%TYPE;
  v_emp_first_name employees.first_name%TYPE;
  v_emp_salary     employees.salary%TYPE;
  v_min_salary     jobs.min_salary%TYPE;
  c_emp_cursor     SYS_REFCURSOR;

  FUNCTION get_cursor(
    v_job_title IN JOBS.JOB_TITLE%TYPE
  ) RETURN SYS_REFCURSOR
  IS
    c_emp_salary SYS_REFCURSOR;
  BEGIN
    OPEN c_emp_salary FOR
    SELECT employee_id,
           first_name,
           salary,
           min_salary
    FROM   employees e
           JOIN jobs j
           ON (   e.job_id = j.job_id
              AND j.job_title = v_job_title );

    RETURN c_emp_salary;
  END;
BEGIN
  c_emp_cursor := get_cursor('Shipping Clerk');

  LOOP
    FETCH c_emp_cursor INTO v_emp_id, v_emp_first_name, v_emp_salary, v_min_salary;
    EXIT WHEN c_emp_cursor%NOTFOUND;
    dbms_output.put_line('Employee ID: ' || v_emp_id);
    dbms_output.put_line('Employee First Name: ' || v_emp_first_name);
    dbms_output.put_line('Employee Salary: ' || v_emp_salary);
    dbms_output.put_line('Job Min Salary: ' || v_min_salary);
    dbms_output.put('Result? ');
    IF v_emp_salary = v_min_salary THEN dbms_output.put('Yes');
      ELSE dbms_output.put('No');
    END IF;
    dbms_output.put_line(NULL);
    dbms_output.put_line('++++++++++++++++++++++++');
  END LOOP;
END;  
/

Выход :

Employee ID: 1
Employee First Name: Alice
Employee Salary: 300
Job Min Salary: 200
Result? No
++++++++++++++++++++++++

дБ <> скрипка здесь

0 голосов
/ 14 января 2020

«Использовать курсор» бессмысленно, потому что каждый оператор DML или SELECT является курсором.

В любом случае, я полагаю, вы ищете это:

CREATE OR REPLACE FUNCTION WRITE_SALARY(v_job_title IN VARCHAR2) AS
    CURSOR c_emp_salary IS
    SELECT employee_id, first_name, salary, min_salary 
    FROM employees e 
       JOIN jobs j ON e.job_id = j.job_id 
    WHERE j.job_title = v_job_title;

    v_emp_id employees.employee_id%TYPE;
    v_emp_first_name employees.first_name%TYPE;
    v_emp_salary employees.salary%TYPE;
    v_min_salary jobs.min_salary%TYPE;

BEGIN
OPEN c_emp_salary;
...
...