[英]ORA-01427: single-row subquery returns more than one row in Update Statement
[英]SQL error ORA 01427 - Subquery returns more than 1 row resulted from update statement
任何人都可以帮助我更正以下此SQL查询吗? 我收到错误消息说子查询返回多于1行。 谢谢。
UPDATE LINEITEM a
SET a.l_manufacturer_name=(with NAMES as (SELECT CASE
WHEN MOD(b.L_PARTKEY,2)=0 THEN (SELECT M_NAME FROM MANUFACTURER m WHERE ROWNUM=1)
WHEN MOD(b.L_PARTKEY,2)=1 THEN (SELECT M_NAME FROM (SELECT M_NAME, ROWNUM AS MYROW FROM (SELECT M_NAME, ROWNUM FROM MANUFACTURER m)) WHERE MYROW=2)
END AS MANUFACTURER_NAME FROM LINEITEM b)
SELECT MANUFACTURER_NAME FROM NAMES N WHERE N.L_PARTKEY=A.L_PARTKEY;
实际上,错误消息是显而易见的( 由于至少一个select语句的返回结果具有多于一行而引发Too_Many_Rows异常 )。 在这种情况下,汇总函数可能会根据我们的情况为我们提供帮助:
SQL> CREATE TABLE MANUFACTURER(M_NAME varchar2(75));
SQL> CREATE TABLE LINEITEM(l_manufacturer_name varchar2(75),l_partkey int);
SQL> INSERT INTO MANUFACTURER VALUES('abc');
SQL> INSERT INTO MANUFACTURER VALUES('def');
SQL> INSERT INTO LINEITEM VALUES('abc',1);
SQL> INSERT INTO LINEITEM VALUES('def',2);
SQL> INSERT INTO LINEITEM VALUES('abc',1);
SQL> INSERT INTO LINEITEM VALUES('def',2);
SQL> UPDATE LINEITEM a
SET a.l_manufacturer_name =
(SELECT CASE
WHEN MOD(b.L_PARTKEY, 2) = 0 THEN
(SELECT M_NAME FROM MANUFACTURER m WHERE ROWNUM = 1)
WHEN MOD(b.L_PARTKEY, 2) = 1 THEN
(SELECT M_NAME
FROM (SELECT M_NAME, ROWNUM AS MYROW
FROM (SELECT M_NAME, ROWNUM FROM MANUFACTURER m))
WHERE MYROW = 2)
END AS MANUFACTURER_NAME
FROM LINEITEM b
WHERE a.l_partkey = b.l_partkey);
ORA-01427: single-row subquery returns more than one row
SQL> UPDATE LINEITEM a
SET a.l_manufacturer_name =
(SELECT CASE
WHEN MOD(max(b.L_PARTKEY), 2) = 0 THEN
(SELECT M_NAME FROM MANUFACTURER m WHERE ROWNUM = 1)
WHEN MOD(max(b.L_PARTKEY), 2) = 1 THEN
(SELECT M_NAME
FROM (SELECT M_NAME, ROWNUM AS MYROW
FROM (SELECT M_NAME, ROWNUM FROM MANUFACTURER m))
WHERE MYROW = 2)
END AS MANUFACTURER_NAME
FROM LINEITEM b
WHERE a.l_partkey = b.l_partkey
GROUP BY b.L_PARTKEY );
4 row updated.
看起来您在MOD(b.L_PARTKEY,2)=0
情况的最内层查询中使用的是ROWNUM
。
ROWNUM的工作方式基本上是在评估WHERE
子句后将其分配给结果中的一行。
这意味着当您在WHERE
子句中引用ROWNUM=1
时,您尝试在分配它之前进行比较。
在其它CASE
用MOD(b.L_PARTKEY,2)=1
你具有内选择一个返回ROWNUM
,则然后参照其与MYROW=2
即内部查询之外。 那行得通,因为那时ROWNUM
已分配给该结果中的每一行。
您应该考虑对第一个CASE
进行与对第二个CASE
相同的操作:
UPDATE LINEITEM a
SET a.l_manufacturer_name = (
SELECT
CASE
WHEN MOD(b.L_PARTKEY,2)=0
THEN (
SELECT
M_NAME
FROM (
SELECT
M_NAME,
ROWNUM AS MYROW
FROM (
SELECT
M_NAME,
ROWNUM
FROM MANUFACTURER m
)
)
WHERE
MYROW=1)
WHEN MOD(b.L_PARTKEY,2)=1
THEN (
SELECT
M_NAME
FROM (
SELECT
M_NAME,
ROWNUM AS MYROW
FROM (
SELECT
M_NAME,
ROWNUM
FROM MANUFACTURER m
)
)
WHERE
MYROW=2)
END AS MANUFACTURER_NAME
FROM LINEITEM b
WHERE
a.l_partkey=b.l_partkey);
这应该确保任一情况下仅返回一行,并且您的分配应该起作用。
谢谢大家 我意识到我的错误。 这是因为匹配期间必须有一个主键。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.