我正在尝试通过存储过程更新Products
表的数量。
我在SQL Developer中使用Oracle数据库。
create or replace procedure alter_products
(
pid in number :=''
,qty in number :=''
)
as
begin
UPDATE PRODUCTS
SET P_QUANTITY = (select P_QUANTITY from PRODUCTS where PID = pid) - qty
WHERE PID = pid;
end alter_products;
存储过程已成功编译,但在尝试运行它时,我收到此错误:
ORA-01427:单行子查询返回多行 ORA-06512:在" DB_NAME.ALTER_PRODUCTS",第7行 ORA-06512:第8行
答案 0 :(得分:2)
您的更新声明应该是这样的:
UPDATE PRODUCTS p
SET p.P_QUANTITY = p.P_QUANTITY - qty
WHERE p.PID = p_pid; --argument should have a different name than the column
-- to keep it clean.
编辑:有关详细解释,请参阅@william Robertson的回答。
答案 1 :(得分:1)
参数pid
与表中的列具有相同的名称(Oracle标识符名称不区分大小写,因此以大写形式写入其中一个对您没有帮助),所以您有条件的地方
where pid = pid
对于表中的每一行都是如此,因为pid
总是等于它自己(除非它是null,并且你在注释中提到它是PK,所以它不能为null)。因此,您需要重命名参数或以前缀:
create or replace procedure alter_products
( pid in number
, qty in number )
as
begin
update products p
set p_quantity =
( select p_quantity
from products p1
where p1.pid = alter_products.pid ) - qty
where p.pid = alter_products.pid;
end alter_products;
但是如果products.pid
是products
的PK,那么您尝试在子查询中查找的行就是您已有的行,因此子查询是多余的。为什么不呢:
create or replace procedure alter_products
( in_pid in products.pid%type
, in_qty in products.p_quantity%type )
as
begin
update products p
set p_quantity = p_quantity - in_qty
where p.pid = in_pid;
end alter_products;
参数的通常命名约定是p_
,例如p_pid
,但是您的表容易混淆地有一个名为p_quantity
的列,因此我使用了in_
作为前缀
我还将参数设置为强制参数,因为它们似乎没有任何意义,因为它们在原始版本中是可选的,并将它们锚定到相应的列类型。