【问题标题】:Checking conflicting data with SELECT and IF statements in a procedure在过程中使用 SELECT 和 IF 语句检查冲突数据
【发布时间】:2014-12-16 10:31:50
【问题描述】:

我正在使用 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');

如果可能的话,我们将不胜感激一些见解

【问题讨论】:

  • 我强烈怀疑您的select 语句返回了多行。我不清楚你说的是否不正确。

标签: sql oracle stored-procedures


【解决方案1】:

“exact fetch returns more than requested number of rows”是一个非常明确的消息,可能是指您的 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 将所有数据读入一个类似表格的变量中。

【讨论】:

  • 不知道为什么,因为这个查询似乎有效,但是当我输入冲突数据时,它仍然将它添加到表中而没有错误
猜你喜欢
  • 2012-08-31
  • 1970-01-01
  • 2012-01-16
  • 2023-03-22
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 2021-04-02
相关资源
最近更新 更多