创建或替换程序proc_video_search

时间:2018-03-03 17:09:19

标签: plsql

创建一个名为proc_video_search的过程来搜索视频并显示视频副本的名称,副本ID,格式和状态。此外,还会显示未签回副本的结帐日期和截止日期。损坏的副本(状态=' D')将排除在输出中。按视频名称(名称)排序输出,然后按副本ID(CopyID)排序。

    $ CREATE OR REPLACE PROCEDURE proc_video_search  (
         p_VideoName        VARCHAR2, 
         p_FormatName       VARCHAR2 DEFAULT NULL)    as
      v_Count             NUMBER;
      v_TotalCopies   NUMBER; v_Avalb  NUMBER;v_FormatName  VARCHAR2(100);
      v_VideoName   VARCHAR2(100); v_CopyID  VARCHAR2(100);v_DueDate DATE;
      v_Status    VARCHAR2(100); v_CheckoutDate DATE;
     CURSOR asdf IS 
       SELECT T_VIDEO.Name, T_COPY.CopyID, Status,T_VIDEO_FORMAT.NAME
       FROM T_VIDEO
       INNER JOIN T_COPY  ON T_VIDEO.VideoID = T_COPY.VideoID
       INNER JOIN T_VIDEO_FORMAT  ON T_VIDEO_FORMAT.FormatID = 
            T_VIDEO.FormatID
       WHERE Status !='D' AND UPPER(T_VIDEO.Name) like '%' || 
                    UPPER(p_VideoName) ||  '%'
       OR UPPER(T_VIDEO_FORMAT.NAME)= UPPER(p_FormatName) 
       ORDER BY T_VIDEO.Name,  T_COPY.CopyID;

    BEGIN
       SELECT       COUNT(*)
       INTO     v_Count
       FROM     T_VIDEO  
        WHERE UPPER(T_VIDEO.Name) like '%' || UPPER(p_VideoName) ||  '%'  ;

      IF v_count = 0 THEN     
       DBMS_OUTPUT.PUT_LINE('****  '||v_Count|| ' results found for ' || 
           p_VideoName||'.  *****');   
        RETURN;
      END IF;

        SELECT   count(T_COPY.CopyID) INTO   v_TotalCopies
        FROM T_COPY INNER JOIN T_VIDEO ON T_COPY.VideoID = T_VIDEO.VideoID
        INNER JOIN T_VIDEO_FORMA ON T_VIDEO_FORMAT.FormatID =
                              T_VIDEO.FormatID
        WHERE Status !='D' AND UPPER(T_VIDEO.Name) like '%' || 
             UPPER(p_VideoName) ||'%'
                 OR UPPER(T_VIDEO_FORMAT.NAME)=UPPER(p_FormatName);

        SELECT   count(T_COPY.CopyID)INTO   v_Avalb FROM T_COPY
        INNER JOIN T_VIDEO  ON T_COPY.VideoID = T_VIDEO.VideoID
        INNER JOIN T_VIDEO_FORMAT ON T_VIDEO_FORMAT.FormatID = 
                      T_VIDEO.FormatID
         WHERE Status ='A' AND UPPER(T_VIDEO.Name) like '%' || 
                    UPPER(p_VideoName) ||'%'
          OR UPPER(T_VIDEO_FORMAT.NAME)=UPPER(p_FormatName);    

         IF v_TotalCopies >=0 THEN
            IF  p_FormatName IS NULL THEN
            DBMS_OUTPUT.PUT_LINE(v_TotalCopies||' results found for '|| 
           p_VideoName||' . (Available copies:'|| v_Avalb|| ')' );
        ELSE
            DBMS_OUTPUT.PUT_LINE(v_TotalCopies||' results found for '|| 
              p_VideoName||'('|| p_FormatName||') . (Available copies:'|| 
                     v_Avalb|| ')' );
        end if;

        OPEN asdf;
          LOOP
               FETCH asdf INTO   v_VideoName, v_CopyID, v_Status, 
                  v_FormatName ;  exit when asdf%NOTFOUND ;

              SELECT COUNT(CheckoutDate)  
              INTO v_Count FROM  T_RENTAL WHERE CopyID = v_CopyID;

             IF v_Count = 1 THEN
               SELECT  CheckoutDate,DueDate
               INTO v_CheckoutDate,v_DueDate
               FROM  T_RENTAL
               WHERE CopyID = v_CopyID; 
             end if;

             DBMS_OUTPUT.PUT_LINE(RPAD('-', 53, '-'));
           DBMS_OUTPUT.PUT_LINE(RPAD('Name:',30) || RPAD(v_VideoName,15));
           DBMS_OUTPUT.PUT_LINE(RPAD('CopyID:',30) ||   RPAD(v_CopyID,15));
           DBMS_OUTPUT.PUT_LINE(RPAD('Format:',30) ||   
               RPAD(v_FormatName,15));
              IF v_Status = 'A' THEN v_Status := 'Available';END IF;
              IF v_Status = 'R' THEN v_Status := 'Rented'; END IF;
           DBMS_OUTPUT.PUT_LINE(RPAD('Status:',30) ||   RPAD(v_Status,15));  
              IF v_Status ='Available' THEN
           DBMS_OUTPUT.PUT_LINE(RPAD('CheckoutDate:',30) 
                ||'****************************');
           DBMS_OUTPUT.PUT_LINE(RPAD('DueDate:',30) 
               ||'****************************');
          ELSE
              DBMS_OUTPUT.PUT_LINE(RPAD('CheckoutDate:',30) 
               ||RPAD(TO_CHAR(v_CheckoutDate, 'DD-MON-YYYY'),15));
                DBMS_OUTPUT.PUT_LINE(RPAD('DueDate:',30) ||RPAD(TO_CHAR( 
              v_DueDate, 'DD-MON-YYYY'),15));
        END IF;   END LOOP;  CLOSE asdf;   END IF; END proc_video_search ;

EXEC proc_video_search('另一个',' DVD')`

enter image description here

1 个答案:

答案 0 :(得分:0)

The problem is with this line of your cursor asdf

 OR UPPER(T_VIDEO_FORMAT.NAME)= UPPER(p_FormatName)

Because it says OR, the query can choose to ignore this criteria if it evaluates to false. That is why you are getting results with all the formats; it ignores the filtering.

You have to wrap the OR statement in another AND clause, like so

WHERE Status !='D' 
AND UPPER(T_VIDEO.Name) like '%' || UPPER(p_VideoName) ||  '%'
AND ( /* OR clause here */ ) 

And then you can handle the case of p_formatName being null or not.