oracle PL/SQL 存储函数 ORA-01422 和 ORA-06512
oracle PL/SQL stored function ORA-01422 and ORA-06512
我想编写一个 PL/SQL 存储函数,它将 driver 的员工编号作为参数,returns driver 的全名,城市他以嵌套形式访问过这座城市以及他访问过多少次 table。
我写了函数,编译成功。这是嵌套 table:
的代码
CREATE OR REPLACE TYPE C_V
AS OBJECT
( FULLNAME VARCHAR(150),
CITIES_VISITED VARCHAR(30),
TOT_VISITS NUMBER(3)
);
CREATE OR REPLACE TYPE D_V_C
IS TABLE OF C_V;
函数如下:
CREATE OR REPLACE FUNCTION DRIVERVISITEDCITIES ( D_E# NUMBER)
RETURN D_V_C
IS
D_FULLNAME VARCHAR(150);
CITIES_VISITED_BY VARCHAR (30);
TOTAL_VISITS NUMBER(3);
CITY_VIS_DETAIL D_V_C := D_V_C();
BEGIN
CITY_VIS_DETAIL.EXTEND();
SELECT DISTINCT EMPLOYEE.FNAME || EMPLOYEE.INITIALS || EMPLOYEE.LNAME AS FULLNAME,
UPPER(TRIPLEG.DESTINATION),
COUNT(TRIPLEG.DESTINATION)
INTO
D_FULLNAME,
CITIES_VISITED_BY,
TOTAL_VISITS
FROM EMPLOYEE
INNER JOIN DRIVER
ON DRIVER.E# = EMPLOYEE.E#
INNER JOIN TRIP
ON TRIP.L# = DRIVER.L#
INNER JOIN TRIPLEG
ON TRIPLEG.T# = TRIP.T#
WHERE EMPLOYEE.E# = D_E#
GROUP BY EMPLOYEE.FNAME||EMPLOYEE.INITIALS||EMPLOYEE.LNAME, TRIPLEG.DESTINATION
ORDER BY COUNT(TRIPLEG.DESTINATION) DESC;
RETURN CITY_VIS_DETAIL;
END;
然而,当我尝试测试它显示的功能时:
Error starting at line 1 in command:
SELECT DRIVERVISITEDCITIES(1) FROM DUAL
Error report:
SQL Error: ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYS.DRIVERVISITEDCITIES", line 13
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
谁能帮我解决这个问题?
SELECT DISTINCT EMPLOYEE.FNAME || EMPLOYEE.INITIALS || EMPLOYEE.LNAME AS FULLNAME,
UPPER(TRIPLEG.DESTINATION),
COUNT(TRIPLEG.DESTINATION)
INTO
D_FULLNAME,
CITIES_VISITED_BY,
TOTAL_VISITS
FROM EMPLOYEE
您的查询正在返回多个值并将其存储到标量变量中。用您的对象类型变量替换标量变量并使用批量收集。
您已经定义了一个 collection 变量,但您没有填充它。相反,您 select 进入标量变量。很明显,您的查询 returns 不止一行(因为一个 driver 已经进行了不止一次旅行),这就是您得到 TOO_MANY_ROWS 异常的原因。
您需要 select 进入那个 collection。最简单的方法是使用 BULK COLLECT:
SELECT DISTINCT EMPLOYEE.FNAME || EMPLOYEE.INITIALS || EMPLOYEE.LNAME AS FULLNAME,
UPPER(TRIPLEG.DESTINATION),
COUNT(TRIPLEG.DESTINATION)
bulk collect into city_vis_detail -- populate the collection like this
D_FULLNAME,
CITIES_VISITED_BY,
TOTAL_VISITS
FROM EMPLOYEE
INNER JOIN DRIVER
ON DRIVER.E# = EMPLOYEE.E#
INNER JOIN TRIP
ON TRIP.L# = DRIVER.L#
INNER JOIN TRIPLEG
ON TRIPLEG.T# = TRIP.T#
WHERE EMPLOYEE.E# = D_E#
GROUP BY EMPLOYEE.FNAME||EMPLOYEE.INITIALS||EMPLOYEE.LNAME, TRIPLEG.DESTINATION
ORDER BY COUNT(TRIPLEG.DESTINATION) DESC;
我想编写一个 PL/SQL 存储函数,它将 driver 的员工编号作为参数,returns driver 的全名,城市他以嵌套形式访问过这座城市以及他访问过多少次 table。
我写了函数,编译成功。这是嵌套 table:
的代码 CREATE OR REPLACE TYPE C_V
AS OBJECT
( FULLNAME VARCHAR(150),
CITIES_VISITED VARCHAR(30),
TOT_VISITS NUMBER(3)
);
CREATE OR REPLACE TYPE D_V_C
IS TABLE OF C_V;
函数如下:
CREATE OR REPLACE FUNCTION DRIVERVISITEDCITIES ( D_E# NUMBER)
RETURN D_V_C
IS
D_FULLNAME VARCHAR(150);
CITIES_VISITED_BY VARCHAR (30);
TOTAL_VISITS NUMBER(3);
CITY_VIS_DETAIL D_V_C := D_V_C();
BEGIN
CITY_VIS_DETAIL.EXTEND();
SELECT DISTINCT EMPLOYEE.FNAME || EMPLOYEE.INITIALS || EMPLOYEE.LNAME AS FULLNAME,
UPPER(TRIPLEG.DESTINATION),
COUNT(TRIPLEG.DESTINATION)
INTO
D_FULLNAME,
CITIES_VISITED_BY,
TOTAL_VISITS
FROM EMPLOYEE
INNER JOIN DRIVER
ON DRIVER.E# = EMPLOYEE.E#
INNER JOIN TRIP
ON TRIP.L# = DRIVER.L#
INNER JOIN TRIPLEG
ON TRIPLEG.T# = TRIP.T#
WHERE EMPLOYEE.E# = D_E#
GROUP BY EMPLOYEE.FNAME||EMPLOYEE.INITIALS||EMPLOYEE.LNAME, TRIPLEG.DESTINATION
ORDER BY COUNT(TRIPLEG.DESTINATION) DESC;
RETURN CITY_VIS_DETAIL;
END;
然而,当我尝试测试它显示的功能时:
Error starting at line 1 in command:
SELECT DRIVERVISITEDCITIES(1) FROM DUAL
Error report:
SQL Error: ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYS.DRIVERVISITEDCITIES", line 13
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
谁能帮我解决这个问题?
SELECT DISTINCT EMPLOYEE.FNAME || EMPLOYEE.INITIALS || EMPLOYEE.LNAME AS FULLNAME,
UPPER(TRIPLEG.DESTINATION),
COUNT(TRIPLEG.DESTINATION)
INTO
D_FULLNAME,
CITIES_VISITED_BY,
TOTAL_VISITS
FROM EMPLOYEE
您的查询正在返回多个值并将其存储到标量变量中。用您的对象类型变量替换标量变量并使用批量收集。
您已经定义了一个 collection 变量,但您没有填充它。相反,您 select 进入标量变量。很明显,您的查询 returns 不止一行(因为一个 driver 已经进行了不止一次旅行),这就是您得到 TOO_MANY_ROWS 异常的原因。
您需要 select 进入那个 collection。最简单的方法是使用 BULK COLLECT:
SELECT DISTINCT EMPLOYEE.FNAME || EMPLOYEE.INITIALS || EMPLOYEE.LNAME AS FULLNAME,
UPPER(TRIPLEG.DESTINATION),
COUNT(TRIPLEG.DESTINATION)
bulk collect into city_vis_detail -- populate the collection like this
D_FULLNAME,
CITIES_VISITED_BY,
TOTAL_VISITS
FROM EMPLOYEE
INNER JOIN DRIVER
ON DRIVER.E# = EMPLOYEE.E#
INNER JOIN TRIP
ON TRIP.L# = DRIVER.L#
INNER JOIN TRIPLEG
ON TRIPLEG.T# = TRIP.T#
WHERE EMPLOYEE.E# = D_E#
GROUP BY EMPLOYEE.FNAME||EMPLOYEE.INITIALS||EMPLOYEE.LNAME, TRIPLEG.DESTINATION
ORDER BY COUNT(TRIPLEG.DESTINATION) DESC;