使用过程中的SELECT和IF语句检查冲突数据

时间:2014-12-16 10:31:51

标签: sql oracle stored-procedures

我正在使用SELECT语句从我的处方表中选择冲突的处理,并且我正在使用IF语句来检查所选数据与我在运行程序时输入的数据。我希望这个程序要做的是禁止同一个客户在同一天预订相互冲突的治疗。但是,当我运行我的程序时,我收到一个错误"确切的提取返回超过请求的行数"。如果我自己运行select语句,它的工作原理如上所述。这是我的程序:

CREATE OR REPLACE PROCEDURE FPRESC (
    FP_ID VARCHAR2,
    FTREAT_ID VARCHAR2,
    FCLIENT_ID VARCHAR2,
    FDOC_ID VARCHAR2,
    FP_DATE DATE)
AS
   V_CLIENT_ID PRESCRIPTION.CLIENT_ID%TYPE;
   V_CONFLICT TREATMENTS.CONFLICT%TYPE;
   V_P_DATE PRESCRIPTION.P_DATE%TYPE;
   V_TREAT_ID TREATMENTS.TREAT_ID%TYPE;
BEGIN
    SELECT P.CLIENT_ID, T.CONFLICT, P.P_DATE, T.TREAT_ID
    INTO V_CLIENT_ID, V_CONFLICT, V_P_DATE, V_TREAT_ID
    FROM PRESCRIPTION P, TREATMENTS T
    WHERE P.TREAT_ID=T.TREAT_ID
    AND T.CONFLICT IS NOT NULL;

    IF FP_DATE = V_P_DATE AND FCLIENT_ID = V_CLIENT_ID AND FTREAT_ID = V_TREAT_ID THEN 
         DBMS_OUTPUT.PUT_LINE('CONFLICT');
    ELSE
         INSERT INTO PRESCRIPTION (P_ID, TREAT_ID, CLIENT_ID, DOC_ID, P_DATE)
         VALUES (FP_ID, FTREAT_ID, FCLIENT_ID, FDOC_ID, FP_DATE);
    END IF;
END FPRESC;
/

以及我尝试为新处方输入的数据示例(注意:此数据存在冲突,因此输入时应该输入错误):

 EXEC FPRESC ('P00011', 'T016', 'C00017', 'D006', '28-NOV-14');

如果可能的话,将非常感谢一些见解

1 个答案:

答案 0 :(得分:1)

"确切的提取返回超过请求的行数"是一个非常明确的消息,可能是指你的select语句。使用select ... into您的查询必须返回一行,因为您只指定了一组变量。此消息表明您的查询返回多行。

我认为最好的解决方案是在查询中进行检查。然后你可以返回或不查询匹配任何东西(在这种情况下存在冲突)。即使执行检查的子查询返回的冲突超过1次,此查询也将始终返回一个指示冲突与否的1或0的记录。

SELECT
    CASE WHEN EXISTS
        (SELECT 'X'
        FROM 
          PRESCRIPTION P
          INNER JOIN TREATMENTS T ON T.TREAT_ID = P.TREAT_ID
        WHERE 
          FP_DATE = P.P_DATE 
          AND FCLIENT_ID = P.CLIENT_ID 
          AND FTREAT_ID = T.TREAT_ID 
          AND T.CONFLICT IS NOT NULL) THEN
        1
    ELSE
        0
    END
INTO
    V_EXISTS
FROM DUAL;

IF V_EXISTS = 1 THEN
    RAISE_APPLICATION_ERROR(-20000, 'Conflict'); -- Actual exception, if you like
ELSE
    INSERT INTO PRESCRIPTION (P_ID, TREAT_ID, CLIENT_ID, DOC_ID, P_DATE)
         VALUES (FP_ID, FTREAT_ID, FCLIENT_ID, FDOC_ID, FP_DATE);
END IF;

顺便说一句,如果您需要从查询中读取多行,您可以将其作为游标打开,逐个处理。使用for loop可以轻松访问。

或者您可以使用bulk collect into将所有数据读入一个类似于表的变量。