繁体   English   中英

SQL错误ORA 01427-子查询返回更新语句导致的多于1行

[英]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时,您尝试在分配它之前进行比较。

在其它CASEMOD(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM