PL/SQL ORA-01422 SELECT INTO 错误,Oracle 匿名块(NOVA 环境)
Posted
技术标签:
【中文标题】PL/SQL ORA-01422 SELECT INTO 错误,Oracle 匿名块(NOVA 环境)【英文标题】:PL/SQL ORA-01422 Error for SELECT INTO, Oracle Anonymous Block (NOVA Environment) 【发布时间】:2018-02-07 18:46:20 【问题描述】:出现以下错误:ORA-01422:精确提取返回的行数超过了请求的行数 ORA-6512
PL/SQL 新手,虽然我知道应该通过标准 SQL 执行此查询,但我正在尝试弄清楚如何使用 PL/SQL 完成此操作。
我需要查询返回邮政编码为“20636”的客户的销售总数
这里是表格/输入:
CREATE TABLE CUSTOMERS
(customerID INT PRIMARY KEY,
customerZip VARCHAR(15) NOT NULL);
CREATE TABLE SALES
(saleID INT PRIMARY KEY,
customerID INT,
CONSTRAINT SALES_FK1 FOREIGN KEY (customerID) REFERENCES CUSTOMERS(customerID));
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (1, '20636');
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (2, '20619');
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (3, '20650');
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (4, '20670');
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (5, '20636');
INSERT INTO SALES (saleID, customerID) VALUES (1, 1);
INSERT INTO SALES (saleID, customerID) VALUES (2, 2);
INSERT INTO SALES (saleID, customerID) VALUES (3, 3);
INSERT INTO SALES (saleID, customerID) VALUES (4, 4);
INSERT INTO SALES (saleID, customerID) VALUES (5, 5);
这是我为 PL/SQL 匿名块编写的代码:
DECLARE
customerZip INTEGER;
totalSales INTEGER;
BEGIN
SELECT customerID INTO customerZip from CUSTOMERS where customerZip = '20636';
SELECT COUNT(*) INTO totalSales from SALES where customerID = customerZip;
DBMS_OUTPUT.put_line('We sold ' || totalSales || ' Cars to customers in Zip Code ' || customerZip ||'.');
END;
/
如果我在没有将两个 customerZIP 属性设置为“20636”的情况下运行它,它可以正常工作。当我输入多个邮政编码为“20636”的客户记录时,我就会收到错误消息。
您能否解释一下我在这里做错了什么以及如何解决它?谢谢!
SQL Fiddle 链接(如果有帮助):http://sqlfiddle.com/#!4/10fc1
【问题讨论】:
This: SELECT customerID INTO customerZip ... 返回超过 1 个 customerID 。要解决此问题,您可以批量收集到某个集合中,或使用 row_number 之类的分析来仅选择 1 个客户 ID。 没错,因为基于我提供的数据的两个客户 ID(1 和 5)的邮政编码为 20636。如何修改代码以便选择多个客户 ID?换句话说,由于我表中的多个客户居住在 20636 中,因此需要考虑每个客户。我猜是某种循环? 您可以将该选择转换为游标并循环遍历它们(或使用嵌套表之类的集合)。或者,在这种情况下,只需执行 GROUP BY 查询(select zip、sum(whatever)、count(*) from my_table where ... group by zip) 【参考方案1】:您可以使用这样的声明:
SQL> set serveroutput on;
SQL> DECLARE
v_customerZip CUSTOMERS.customerZip%type:='20636';
v_customerID CUSTOMERS.customerID%type;
totalSales INTEGER:=0;
Sales INTEGER;
BEGIN
for c in ( SELECT customerID from CUSTOMERS where customerZip = v_customerZip )
loop
v_customerID := c.customerID;
SELECT COUNT(1) INTO Sales from SALES where customerID = v_customerID;
totalSales := totalSales + Sales;
end loop;
dbms_output.put_line('We sold ' || totalSales || ' Cars to customers in Zip Code ' || v_customerZip ||'.');
END;
/
We sold 2 Cars to customers in Zip Code 20636.
并从声明部分更改变量 v_customerZip 的值。
或者你可以创建一个程序来完成这个任务:
SQL> CREATE OR REPLACE PROCEDURE GET_SALES( v_customerZip CUSTOMERS.customerZip%type ) IS
v_customerID CUSTOMERS.customerID%type;
totalSales INTEGER:=0;
Sales INTEGER;
BEGIN
for c in ( SELECT customerID from CUSTOMERS where customerZip = v_customerZip )
loop
v_customerID := c.customerID;
SELECT COUNT(1) INTO Sales from SALES where customerID = v_customerID;
totalSales := totalSales + Sales;
end loop;
dbms_output.put_line('We sold ' || totalSales || ' Cars to customers in Zip Code ' || v_customerZip ||'.');
END;
/
SQL> exec get_sales('&cZ');
Enter value for cz: 20636
We sold 2 Cars to customers in Zip Code 20636.
【讨论】:
成功了。谢谢!很棒的信息...希望这会开始告诉我...与 PL/SQL 相比,SQL 很容易。以上是关于PL/SQL ORA-01422 SELECT INTO 错误,Oracle 匿名块(NOVA 环境)的主要内容,如果未能解决你的问题,请参考以下文章
返回多于 1 行的 SELECT INTO - ORA-01422
WHILE循环出错:ORA-01422:精确提取返回的请求行数多于请求的行数
PL/SQl sqldeveloper想在plsql中输出多行