【问题标题】:creating a procedure with 2 parameters and throwing an exception创建具有 2 个参数的过程并引发异常
【发布时间】:2015-12-18 03:26:43
【问题描述】:

我如何创建一个带有 2 个参数 func 和 sal 的过程来验证员工的薪水在 min_salary 和 max_salary 之间(来自 JOBS 表的 2 个列),如果它们不在其中,则需要抛出异常? 另外我正在使用员工表中的行(salary,employee_id,job_id)到目前为止我得到了这个:

CREATE OR REPLACE PROCEDURE check_sal(func employees.job_id%type,sal employees.salary%type)
IS
max_sal jobs.max_salary%type;
min_sal jobs.min_salary%type;
empid employees.employee_id%type;
BEGIN
SELECT e.employee_id,e.salary,e.job_id,j.max_salary,j.min_salary INTO empid,sal,func,max_sal,min_sal
FROM employees e JOIN jobs j ON e.job_id = j.job_id
ORDER by e.employee_id;
FOR i IN empid.FIRST..empid.LAST LOOP
IF(sal < min_sal) OR (sal > max_sal) THEN RAISE_APPLICATION_ERROR(-20000,'OUT OF BOUND');
ELSE DMBS_OUTPUT.PUT_LINE('OK');
END IF;
END LOOP;
END;

我在第 10 行收到错误错误:PL/SQL:语句被忽略。我做错了什么?

【问题讨论】:

  • 为什么需要使用employees表中的行?除非我误解了,否则您真正需要做的就是查询作业表。
  • 因为你需要从Employees表行中提取salary中的行,所以我们需要将每个员工与作为Jobs表中的行的min_salary和max_salary进行比较

标签: plsql


【解决方案1】:
  1. 您似乎想要逐行处理,但只提取 1 条记录。我想你会得到太多行异常。
  2. Empid 是序数变量,但不是集合。您应该创建一个记录表并遍历它,以便您的脚本在 FOR i IN empid.FIRST..empid.LAST LOOP 上失败。

【讨论】:

  • 好吧,我需要将每个员工的薪水与 min_salary 和 max_salary 进行比较,并通过 job_id 连接(员工有外键 job_id,工作有主键 job_id),这就是我尝试使用 FOR.Also 的原因有一点我的意思是在比较时我只需要当前员工的 1 条记录然后我转到下一条记录。在 empid 中我试图把所有的employee_id 行但是是的你是对的我不能把它们都放在一个简单的变量。感谢您指出这一点!
【解决方案2】:

嘿,我刚刚研究了这个问题,并在下面说明了一个 sn-p 这肯定会奏效。我没有工作空间,但是这个 应该管用。如有任何问题,请告诉我。

CREATE OR REPLACE PROCEDURE check_sal(
    func employees.job_id%type,
    sal employees.salary%type)
IS
TYPE max_sal_tab
IS
  TABLE OF jobs.max_salary%type;
  max_sal max_sal_tab;
TYPE empid_tab
IS
  TABLE OF employees.employee_id%type;
  empid empid_tab;
TYPE sal_tab
IS
  TABLE OF employees.salary%type;
  sal sal_tab;
TYPE jobid_tab
IS
  TABLE OF employees.job_id%type;
  func jobid_tab;
TYPE min_sal_tab
IS
  TABLE OF employees.min_salary%type;
  min_sal min_sal_tab;
BEGIN
  SELECT e.employee_id,
    e.salary,
    e.job_id,
    j.max_salary,
    j.min_salary BULK COLLECT
  INTO empid,
    sal,
    func,
    max_sal,
    min_sal
  FROM employees e
  JOIN jobs j
  ON e.job_id = j.job_id
  ORDER BY e.employee_id;
  FOR i IN empid.FIRST..empid.LAST
  LOOP
    IF(sal < min_sal(i)) OR (sal > max_sal(i)) THEN
      RAISE_APPLICATION_ERROR(-20000,'OUT OF BOUND',TRUE);
    ELSE
      DMBS_OUTPUT.PUT_LINE('OK');
      --Do not use dbms output in any prod env
    END IF;
  END LOOP;
END;

【讨论】:

    【解决方案3】:

    刚刚发现不需要使用 FOR 和 empid 变量,所以答案要简单得多:

    CREATE OR REPLACE PROCEDURE check_sal(func employees.job_id%TYPE,sal employees.salary%TYPE)
        AS
        max_sal jobs.max_salary%TYPE;
        min_sal jobs.min_salary%TYPE;
        BEGIN
        SELECT max_salary,min_salary into max_sal,min_sal 
        FROM JOBS 
        WHERE job_id=func;
        DBMS_OUTPUT.PUT_LINE(max_sal||' and '||min_sal);
        IF sal < min_sal OR sal > max_sal THEN RAISE_APPLICATION_ERROR(-20205,'Out of Bounds');
        END IF;
        END;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 1970-01-01
      相关资源
      最近更新 更多