【问题标题】:How to write PL/SQL to check if record exists first, before inserting如何编写 PL/SQL 在插入之前先检查记录是否存在
【发布时间】:2015-10-23 04:50:51
【问题描述】:

背景:我有桌子:

TUTPRAC: CLASSID、UNITCODE、STAFFNO、CLASSDAY、CLASSTIME、CLASSTYPE、ROOMNUM

UNITSTREAM: STREAMID、UNITCODE、STAFFNO、日期、时间、位置

问题:所以我有一个数据库和表,我试图创建一个函数,在打开一个新类之前检查一个类是否打开,这 程序必须确保两者之间没有任何重叠(在时间、日期或位置方面的冲突) 该特定单元的流(讲座),辅导课程和实践课程。 TUTPRACS 包含教程和实践的记录,而 UNITSTREAM 包含流(讲座)的记录。

我也希望程序也 引发一个名为 CLASS_OVERLAPS 的异常,在发生冲突时打印一条警报消息。

我对 PL/SQL 还很陌生,因此我们将不胜感激。

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
    BEGIN

      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);

      COMMIT;

    END;

【问题讨论】:

    标签: sql oracle stored-procedures plsql


    【解决方案1】:

    你可以这样试试:

    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
        BEGIN
    
    DECLARE
        x NUMBER:=0;
    BEGIN
        -- checks
        SELECT nvl((SELECT 1 FROM TUTPRAC WHERE CLASSID = p_class and UNITCODE  = p_unitc and CLASS_DAY = p_classd and CLASS_TIME = p_classt and CLASS_TYPE = p_classtp and ROOMNUM = p_roomnm) , 0) INTO x FROM dual;
    
        -- insert
        IF (x = 1) 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);
        END IF;
    
    END;
    

    或者你可以像这样使用 EXISTS:

        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
            BEGIN
    
              INSERT INTO TUTPRAC ("CLASSID", "UNITCODE", "CLASS_DAY", "CLASS_TIME", "CLASS_TYPE", "ROOMNUM") 
    INSERT INTO table
    SELECT p_class, p_unitc, p_classd, p_classt, p_classtp, p_roomnm
      FROM dual 
     WHERE NOT EXISTS (SELECT NULL 
                         FROM TUTPRAC 
                        WHERE CLASSID = p_class and UNITCODE  = p_unitc and CLASS_DAY = p_classd and CLASS_TIME = p_classt and CLASS_TYPE = p_classtp and ROOMNUM = p_roomnm
                      )
    

    【讨论】:

    • 我正要尝试一下这个和上面的评论,我还想检查插入的类是否与 UNITSTREAM 表中的流(讲座)发生冲突。本质上,我正在做的是确保输入到 TUTPRAC 表中的 TUT 或 PRAC 不会发生冲突或有任何重复,也不会与其自己的流(讲座)日期/时间/和房间发生冲突。 @Rahul Tripathi
    • @CM25:- 您可以尝试再创建一个变量,然后像SELECT nvl((SELECT 1 FROM UNITSTREAM WHERE CLASSID = p_class and UNITCODE = p_unitc and CLASS_DAY = p_classd and CLASS_TIME = p_classt and CLASS_TYPE = p_classtp and ROOMNUM = p_roomnm) , 0) INTO x FROM dual; 一样检查您的表,然后在您的 IF 条件下,您可以使用和条件来检查两个变量是否都有值 = 1.
    • 我在输入您发送给我的第一个解决方案时遇到此错误 = "Error(23,4): PLS-00103: Encountered the symbol "end-of-file" when expecting one of the以下: ( begin case declare end exception exit for goto if loop mod null pragma raise return select update while with
    【解决方案2】:

    你知道合并吗? Merge

    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
        BEGIN
       merge into TUTPRAC a
       using (select p_class CLASSID,
                     p_unitc UNITCODE,
                     p_classd CLASS_DAY,
                     p_classt CLASS_TIME,
                     p_classtp CLASS_TYPE,
                     p_roomnm ROOMNUM from dual) b
          on (a.CLASSID = b.CLASSID
              and a.UNITCODE = b.UNITCODE
              and a.CLASS_DAY = b.CLASS_DAY
              and a.CLASS_TYPE = b.CLASS_TYPE
              and a.ROOMNUM = b.ROOMNUM)
       WHEN NOT MATCHED THEN INSERT (a.CLASSID ,a.UNITCODE, a.CLASS_DAY, a.CLASS_TYPE, a.ROOMNUM)
       values  ( b.CLASSID
              , b.UNITCODE
              , b.CLASS_DAY
              , b.CLASS_TYPE
              , b.ROOMNUM);
       if sql%ROWCOUNT = 0 then
        dbms_output.put_line('Class alredy exists');
       else
       dbms_output.put_line('Class added');
       end if;
      commit;
    END;
    /
    

    【讨论】:

    • 有没有办法同时检查 TUTPRAC 中的相同字段,但来自 UNITSTREAMS 表? UNITSTREAMS 表包含相同单元的讲座,而 TUTPRAC 包含 TUTES 和 PRACS。所以我需要确保 tutes 和 pracs 也不会与他们自己存储在 UNITSTREAM 中的讲座发生冲突。 @Arkadiusz Łukasiewicz
    • 这段代码是否也会检测到同一房间/时间/天中 2 个不同班级之间的冲突?因此,如果星期三下午 6.45 在 A 房间有数学课,我们尝试在同一时间在那个房间添加科学课,上面的代码会检测到这种冲突吗? @Arkadiusz Łukasiewicz
    猜你喜欢
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 2017-06-08
    • 1970-01-01
    相关资源
    最近更新 更多