01427. 00000 - “单行子查询返回多行”

时间:2014-01-17 09:19:53

标签: mysql sql oracle oracle-sqldeveloper

我正在获取01427. 00000 - 执行以下过程时“单行子查询返回多行”错误。这个问题,我相信,是在子查询中

SELECT paymentterm FROM temp_pay_term WHERE pid = d.xProject_id

但我怎么能摆脱它。现在,我已经添加了完整的代码。请检查并让我知道错误告诉我是否有更多信息。将被提供。

CREATE OR REPLACE PROCEDURE paytermupdate IS
  recordcount    INT;
  vardid         NUMBER(38);
  varpaymentterm VARCHAR2(200 CHAR);
  BEGIN
    recordcount := 0;

    SELECT COUNT(1) INTO recordcount
    FROM temp_pay_term;

    IF recordcount > 0 THEN
      FOR x IN (SELECT DISTINCT r.ddocname
                FROM temp_pay_term p, docmeta d, revisions r
                WHERE TO_CHAR(p.pid) = d.xproject_id AND r.did = d.did             )
      LOOP
        SELECT MAX(did) INTO vardid
        FROM revisions r
        WHERE r.ddocname = x.ddocname
        GROUP BY r.ddocname;

        UPDATE docmeta d
        SET paymentterm = (
          SELECT paymentterm
          FROM temp_pay_term
          WHERE pid = d.xproject_id
        )
        WHERE d.did = vardid;

        INSERT INTO documenthistory (dactionmillis, dactiondate, did, drevclassid,
                                     duser, ddocname, daction, dsecuritygroup, paymentterm)
          SELECT
            to_number(TO_CHAR(systimestamp, 'FF')) AS dactionmillis,
            TRUNC(systimestamp, 'dd')              AS dactiondate,
            did,
            drevclassid,
            'sysadmin'                             AS duser,
            ddocname,
            'Update'                               AS daction,
            dsecuritygroup,
            paymentterm
          FROM revisions
          WHERE did = vardid;

      END LOOP;

      COMMIT;
    END IF;
  END paytermupdate;

3 个答案:

答案 0 :(得分:0)

你使用类似

的东西吗?

从?

中选择x,y,z,(子查询)

如果您正在获得ORA-01427,您应该考虑如何使子查询中的过滤条件更具限制性,并且这些限制应该是商业上合理的,而不仅仅是“和rownum< = 1”。

答案 1 :(得分:0)

如果您想通过该子查询更新记录,则应在其中添加更多过滤条件。您可以根据要在外部查询中的表中更新的值来决定过滤条件。如果有更多的值满足条件(我认为这不是理想的,只是以防万一),那么rownum< = 1就足够了。

答案 2 :(得分:0)

我想到了两个基本选项。我将从最简单的开始。

首先,在子查询中添加distinct。

SET paymentterm =
    (SELECT distinct paymentterm
    FROM temp_pay_term
    WHERE pid   = d.xProject_id
)

其次,如果您从子查询中收到多个不同的值,那么您将需要(a)重新编写脚本以不使用子查询或(b)使用更多过滤条件返回的限制值(如@Baljeet所示)或(c)使用聚合函数选择您想要的多个不同值中的哪一个。

使用聚合方法,我猜测PaymentTerm是几个月或几年?即使它是一个n / varchar字段(即“6个月”),你仍然可以使用MIN()和MAX()聚合(或至少你可以在t-sql中)。如果它是一个数字字段,您也可以使用平均值。您必须弄清楚哪种方法最适合您的业务需求。