簡體   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