创建一个名为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')`
答案 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.