【问题标题】:ORACLE PL/SQL Function is created successfully but the execution body is not workingORACLE PL/SQL 函数创建成功但执行体不工作
【发布时间】:2017-08-26 06:21:08
【问题描述】:

这些是我创建的表的列表,并为创建的表插入了值:

CREATE TABLE DEPARTMENT
(DEPARTMENT_ID NUMBER PRIMARY KEY,
 DEPARTMENT_NAME VARCHAR(30) NOT NULL
 );

 CREATE TABLE JOBS
 (JOB_ID NUMBER PRIMARY KEY,
  JOB_TITLE VARCHAR(35) NOT NULL,
  MIN_SALARY DECIMAL NOT NULL,
  MAX_SALARY DECIMAL NOT NULL
  );

 CREATE TABLE EMPLOYEES
(EMPLOYEE_ID NUMBER PRIMARY KEY,
 FIRST_NAME VARCHAR(20) NOT NULL,
 LAST_NAME VARCHAR(25) NOT NULL,
 EMAIL VARCHAR(25) NOT NULL,
 PHONE_NUMBER VARCHAR(20) NOT NULL,
 HIRE_DATE DATE NOT NULL,
 JOB_ID NUMBER NOT NULL,
 SALARY DECIMAL NOT NULL,
 DEPARTMENT_ID NUMBER NOT NULL,
 CONSTRAINT emp_job_fk FOREIGN KEY(JOB_ID) REFERENCES JOBS(JOB_ID),
 CONSTRAINT emp_department_fk FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(DEPARTMENT_ID)
 );

INSERT INTO DEPARTMENT (DEPARTMENT_ID,DEPARTMENT_NAME)
VALUES(1,'IT');
INSERT INTO DEPARTMENT (DEPARTMENT_ID,DEPARTMENT_NAME)
VALUES(2,'Sales');

INSERT INTO JOBS (JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY)
VALUES (1,'IT Administrator',250000.00,50000.00);
INSERT INTO JOBS (JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY)
VALUES (2,'Salesman',200000.00,40000.00);

INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (1,'Tony','Starc','starc@gmail.com','0123456789',TO_DATE('15/1/2008','DD/MM/YYYY'),1,45000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (2,'Bruce','Wayne','bruce@gmail.com','0123456788',TO_DATE('15/1/2009','DD/MM/YYYY'),1,40000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (3,'Larry','Ellison','larry@gmail.com','0123456787',TO_DATE('15/1/2010','DD/MM/YYYY'),1,30000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (4,'Steve','Jobs','steve@gmail.com','0123456786',TO_DATE('15/1/2011','DD/MM/YYYY'),2,35000.00,2);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (5,'Remy','Lebeau','remy@gmail.com','0123456785',TO_DATE('15/1/2012','DD/MM/YYYY'),2,30000.00,2);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (6,'Clark','Kent','clark@gmail.com','0123456784',TO_DATE('15/1/2013','DD/MM/YYYY'),2,35000.00,2);

现在在我的作业问题中,我被要求解决以下问题: 编写一个名为 fn_emps_per_dept_jc450912 的函数来检索具有给定 DEPARTMENT_ID 的 EMPLOYEE_ID、FIRST_NAME、LAST_NAME 和 JOB_TITLE。这个函数应该有 DEPARTMENT_ID 作为输入参数,这个函数应该有 EMPLOYEE_ID、FIRST_NAME、LAST_NAME 和 JOB_TITLE 作为输出参数。如果找到它应该返回 TRUE,如果没有找到则返回 FALSE。

为了显示特定部门员工的信息,我写了以下函数:

CREATE OR REPLACE FUNCTION fn_emps_per_dept_jc450912 (f_dept_id IN NUMBER,f_emp_id OUT NUMBER,f_first_name OUT VARCHAR,f_last_name OUT VARCHAR,f_job_title OUT VARCHAR)
RETURN BOOLEAN
AS
BEGIN
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
INTO f_emp_id,f_first_name,f_last_name,f_job_title
FROM EMPLOYEES,JOBS,DEPARTMENT
WHERE DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
AND JOBS.JOB_ID = EMPLOYEES.JOB_ID
AND EMPLOYEES.DEPARTMENT_ID = f_dept_id;
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE('Employee not found');
RETURN FALSE;
END fn_emps_per_dept_jc450912;

Function FN_EMPS_PER_DEPT_JC450912 compiled

从上面可以看出,函数已经编译成功了。

然后我尝试执行函数:

DECLARE
f_dept_id NUMBER;
f_emp_id NUMBER;
f_first_name VARCHAR(30) ;
f_last_name VARCHAR(30) ;
f_job_title VARCHAR(30);
f_return BOOLEAN;
BEGIN
f_dept_id := 1;
f_return := fn_emps_per_dept_jc450912(f_dept_id,f_emp_id,f_first_name,f_last_name,f_job_title);
DBMS_OUTPUT.PUT_LINE('Employee_ID: ' || f_emp_id);
DBMS_OUTPUT.PUT_LINE('First Name: ' || f_first_name);
DBMS_OUTPUT.PUT_LINE('Last Name: ' || f_last_name);
DBMS_OUTPUT.PUT_LINE('Job: ' || f_job_title);
END;

我收到以下错误:

Error report -
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYSTEM.FN_EMPS_PER_DEPT_JC450912", line 5
ORA-06512: at line 10
01422. 00000 -  "exact fetch returns more than requested number of rows"
*Cause:    The number specified in exact fetch is less than the rows returned.
*Action:   Rewrite the query or change number of rows requested

我需要执行体的解决方案代码来修复这个错误。

【问题讨论】:

  • 你最后插入的INSERT INTO EMPLOYEES (EMPLOYEE ...... TO_DATE('15/1/2013','DD/MM/YYYY')不完整,导致解析错误SQL Error: ORA-00917: missing comma
  • 我已经编辑并修复了它。但是,我正在寻找执行主体的解决方案代码。这是我唯一需要解决的问题。函数创建成功。但是,我坚持执行语法。如果您能提供执行部分的解决方案代码将会很有帮助。
  • 实际上你还没有解决所有问题 - 超人仍然缺少 Job_ID、salary 和 department_id
  • 软件测试不会因为编译成功而停止。你发现的是runtime error

标签: sql oracle plsql


【解决方案1】:

首先请使用现代连接语法(自 92 以来的 ANSI 标准!)。

所以你的 SELECT 应该是:

SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
INTO f_emp_id,f_first_name,f_last_name,f_job_title
FROM EMPLOYEES INNER JOIN JOBS ON JOBS.JOB_ID = EMPLOYEES.JOB_ID
INNER JOIN DEPARTMENT ON DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
WHERE EMPLOYEES.DEPARTMENT_ID = f_dept_id;

接下来当你遇到这样的问题时,你应该在查询窗口中运行查询,如下所示:

SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
FROM EMPLOYEES INNER JOIN JOBS ON JOBS.JOB_ID = EMPLOYEES.JOB_ID
INNER JOIN DEPARTMENT ON DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
WHERE EMPLOYEES.DEPARTMENT_ID = 1;

这将揭示问题的原因,因为输出看起来像这样

EMPLOYEE_ID FIRST_NAME           LAST_NAME                 JOB_TITLE                         
----------- -------------------- ------------------------- -----------------------------------
          1 Tony                 Starc                     IT Administrator                   
          2 Bruce                Wayne                     IT Administrator                   
          3 Larry                Ellison                   IT Administrator                   

即字段 employees.department_id 不是唯一的。因此,在执行时,存储过程会尝试将多个值放入单个变量中。这是它无法做到的,因此出现了错误。程序编译成功,因为在编译时,程序可能不知道它会被传递一个导致结果集中有多个记录的参数。

【讨论】:

  • 我已经重新编辑并添加了 clark kent(超人)的工作 ID 和薪水。另一方面,分配问题要求我创建一个函数,其中部门 id 作为输入参数,其他选定的列作为输出参数。我只是卡在执行部分。如果您可以仅提供执行部分的解决方案,那将非常有帮助。
  • 请阅读我的回答。鉴于您的数据,不可能有解决方案。我最好的猜测是你的任务错了。输入参数应该是employee_id(而不是department_id),或者您应该有一个输出参数,它是一个记录集(使用sys_refcursor)。
  • 我已经删除了部门 id 并将员工 id 作为输入参数,然后我应用了我的函数执行逻辑它起作用了,我通过输入有效的员工 id 号并在输入时出错来获得结果无效的员工 ID。当我使用员工 ID 作为输入参数时,它运行良好。但是,当我将部门 ID 作为输入参数来获取员工详细信息时,它会显示错误。这是不应该的,因为我已经指定了 EMPLOYEES.DEPARTMENT_ID = f_dept_id 。所以这对我来说很奇怪。
  • @learningIT Department_ID 在员工表中不是唯一的。它是 Department 的外键,在此是唯一的。因此,指定 where employees.department_id = f_dept_id 不会产生单个结果集。因此你的错误。我能把这个变得更简单吗?
  • 我的荣幸。请通过单击答案旁边的勾号将问题标记为已回答。它应该变成绿色!
猜你喜欢
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 2018-09-06
  • 2020-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多