我正在运行一些Oracle SQL并收到错误“ORA-01422:精确提取返回超过请求的行数”。我理解为什么通常会抛出这个错误,但是我正在请求一行,实际上只返回了一行。 (我无法为此创建一个SQL小提琴,因为我一直收到一个错误,即我的架构创建语法不正确,尽管它在SQL Plus中成功运行)
我的代码如下。该函数创建成功,不会抛出任何错误。但是,当我尝试运行验证码时,我收到上述错误。手动运行select语句只返回一行,即使错误声明返回了多行。我的代码导致此错误有什么问题?
数据库架构:
create table Employee
(
fname varchar(15),
minit varchar(1),
lname varchar(15),
ssn char(9),
bdate date,
address varchar(30),
sex varchar(1) CHECK(sex = 'M' or sex = 'F'),
salary number CHECK(salary >= 20000 and salary <= 100000),
super_ssn char(9),
dno number DEFAULT 0,
constraint EMPPK
primary key(ssn),
constraint EMPSUPERVRFK
foreign key(super_ssn) references Employee(ssn)
ON DELETE SET NULL
);
create table Department
(
dname varchar(15) NOT NULL,
dnumber number,
mgr_ssn char(9) DEFAULT '000000000',
mgr_start_date date,
constraint DEPTPK
primary key(dnumber),
constraint DEPTMGRFK
foreign key(mgr_ssn) references Employee(ssn)
ON DELETE SET NULL
);
insert into Employee values ('James','E','Borg','888665555','10-NOV-1937','450 Stone, Houston, TX','M',55000,null,1);
insert into Employee values ('Franklin','T','Wong','333445555','08-DEC-1955','638 Voss, Houston, TX','M',40000,'888665555',5);
insert into Employee values ('John','B','Smith','123456789','09-JAN-1965','731 Fondren, Houston, TX','M',30000,'333445555',5);
insert into Employee values ('Jennifer','S','Wallace','987654321','20-JUN-1941','291 Berry, Bellaire, TX','F',43000,'888665555',4);
insert into Employee values ('Alicia','J','Zelaya','999887777','19-JAN-1968','3321 Castle, Spring, TX','F',25000,'987654321',4);
insert into Employee values ('Ramesh','K','Narayan','666884444','15-SEP-1962','975 Fire Oak, Humble, TX','M',38000,'333445555',5);
insert into Employee values ('Joyce','A','English','453453453','31-JUL-1972','5631 Rice, Houston, TX','F',25000,'333445555',5);
insert into Employee values ('Ahmad','V','Jabbar','987987987','29-MAR-1969','980 Dallas, Houston, TX','M',25000,'987654321',4);
insert into Department values ('Research',5,'333445555','22-MAY-1988');
insert into Department values ('Administration',4,'987654321','01-JAN-1995');
insert into Department values ('Headquarters',1,'888665555','19-JUN-1981');
功能(创建没有错误):
create or replace function getManagerNameDnameFunc(DNAME in department.dname%type)
return varchar
is
name varchar(50);
begin
name := '';
select e.fname || ' ' || e.lname into name from employee e, department d
where d.dname = DNAME and d.mgr_ssn = e.ssn;
return(name);
exception
when NO_DATA_FOUND then
dbms_output.put_line('No data found');
return(name);
end;
/
show errors
测试代码:
declare
rs varchar(10);
pr varchar(10);
begin
rs := 'Research';
pr := 'Printing';
dbms_output.put_line('Manager of Research department is ' || getManagerNameDnameFunc(rs));
dbms_output.put_line('Manager of Printing department is ' || getManagerNameDnameFunc(pr));
end;
/
select e.fname || ' ' || e.lname from employee e, department d where d.dname = 'Research' and d.mgr_ssn = e.ssn;
的确切输出(此名称是应为输出的研究部门经理的名称):
E.FNAME||''||E.LNAME
-------------------------------
Franklin Wong
答案 0 :(得分:3)
问题是函数参数的名称。在您的查询中,当您编写
时where d.dname = DNAME
我假设您的目的是将dname
表中的Department
与传入的dname
进行比较。但是,这不是您的代码所做的事情。由于右侧标识符不合格,因此Oracle首先尝试将其解析为其中一个表中列的名称。由于dname
表格中有department
列,因此dname
指的是where d.dname = d.DNAME
。所以,你实质上是编写了一个无操作的
p_
一个常见的解决方案是提出一个标准约定,用于命名参数和不与列名冲突的局部变量。就个人而言,我使用l_
和create or replace function getManagerNameDnameFunc(p_dname in department.dname%type)
return varchar
is
name varchar(50);
begin
select e.fname || ' ' || e.lname
into name from employee e, department d
where d.dname = p_dname
and d.mgr_ssn = e.ssn;
的局部变量作为前缀,这是一个非常常见的惯例。
select e.fname || ' ' || e.lname
into name
from employee e, department d
where d.dname = getManagerNameDnameFunc.DNAME
and d.mgr_ssn = e.ssn;
不太常见的是,您可以使用过程名称
明确地为标识符添加前缀{{1}}