尝试插入记录

时间:2015-10-25 13:24:20

标签: oracle stored-procedures plsql

当我尝试通过我的程序插入数据时出现此错误:

Error starting at line : 48 in command -
BEGIN
  OPEN_CLASS('PRAC_4', 'ISYS224', 'Tue', '09:00', 'P', 'E6A123');
END;
Error report -
ORA-01427: single-row subquery returns more than one row
ORA-06512: at "43053327.OPEN_CLASS", line 18
ORA-06512: at line 2
01427. 00000 -  "single-row subquery returns more than one row"
*Cause:    
*Action:

我目前的程序是(到目前为止所有其他测试运行正常):

CREATE OR REPLACE PROCEDURE OPEN_CLASS(
    p_class IN TUTPRAC.CLASSID%TYPE,
    p_unitc IN TUTPRAC.UNITCODE%TYPE,
    p_classd IN TUTPRAC.CLASS_DAY%TYPE,
    p_classt IN TUTPRAC.CLASS_TIME%TYPE,
    p_classtp IN TUTPRAC.CLASS_TYPE%TYPE,
    p_roomnm IN TUTPRAC.ROOMNUM%TYPE)

    IS

    -- Variables    
    x number:=0;
    y number:=0;  
    CLASS_OVERLAPS EXCEPTION;

BEGIN
    -- checks
    SELECT nvl((SELECT 1 FROM TUTPRAC WHERE UNITCODE = p_unitc and CLASS_DAY = p_classd or CLASS_DAY = p_classd and CLASS_TIME = p_classt and ROOMNUM = p_roomnm) , 0) INTO x FROM dual;
    SELECT nvl((SELECT 1 FROM UNITSTREAM WHERE UNITCODE = p_unitc and DAY = p_classd or DAY = p_classd and TIME = p_classt and LOCATION = p_roomnm) , 0) INTO y FROM dual;

    -- insert
    IF (x = 0 and y = 0) THEN
      INSERT INTO TUTPRAC (CLASSID, UNITCODE, CLASS_DAY, CLASS_TIME, CLASS_TYPE, ROOMNUM) 
      VALUES (p_class, p_unitc, p_classd, p_classt, p_classtp, p_roomnm);
    ELSE
       RAISE CLASS_OVERLAPS;
    END IF;

    EXCEPTION
      WHEN CLASS_OVERLAPS
      THEN
      RAISE_APPLICATION_ERROR(-20001,'The class you have tried to insert is clashing with an existing class.');

END OPEN_CLASS;

我的程序检查插入的类记录是否与表中已有的类冲突。这个程序适用于我迄今为止尝试的每个测试用例,除了这个。

1 个答案:

答案 0 :(得分:1)

ORA-01427: single-row subquery returns more than one row
ORA-06512: at "43053327.OPEN_CLASS", line 18

错误是由于您的 SELECT .. INTO 语句提供了多行,但是它应该只生成一行。

执行不带INTO子句的 SQL 来检查返回的行数,并放入所需的文件管理器。如果您想选择一行,则可以使用 ROWNUM 将行限制为1

SELECT COUNT(*) FROM
(
SELECT nvl((SELECT 1 FROM TUTPRAC WHERE UNITCODE = p_unitc 
and CLASS_DAY = p_classd or CLASS_DAY = p_classd 
and CLASS_TIME = p_classt and ROOMNUM = p_roomnm) , 0) FROM dual
);

SELECT COUNT(*) FROM
(
SELECT nvl((SELECT 1 FROM UNITSTREAM WHERE UNITCODE = p_unitc 
and DAY = p_classd or DAY = p_classd and TIME = p_classt 
and LOCATION = p_roomnm) , 0) FROM dual
);

SELECT 1并不意味着它会返回一行,它只会为每个提取的行返回值1。如果要限制行数,则:

  • ROWNUM
  • 12c
  • 中的行限制功能 FETCH

<强>更新

根据OP的评论, COUNT 是必需的。

SELECT COUNT(*) 
INTO x 
FROM TUTPRAC 
WHERE UNITCODE = p_unitc 
AND CLASS_DAY = p_classd or CLASS_DAY = p_classd 
AND CLASS_TIME = p_classt and ROOMNUM = p_roomnm;

SELECT COUNT(*) 
INTO y     
FROM UNITSTREAM 
WHERE UNITCODE = p_unitc 
AND DAY = p_classd or DAY = p_classd 
AND TIME = p_classt and LOCATION = p_roomnm;