Oracle SQL学术问题。游标,循环和函数

时间:2013-10-16 01:27:31

标签: sql oracle plsql

这些是问题的要求:

创建名为findtotalcarmodels的PL / SQL函数以返回总计 属于特定型号的汽车数量。该函数应该有单个 IN参数为 model_name。然后,您应该使用显式游标来计算 属于该车型的汽车数量并返回最终计数。您必须 使用任何隐式游标,表联接,子查询,集合运算符,组函数或SQL 函数(如COUNT)来创建这个函数。

现在,编写ONE PL / SQL匿名块,提供有关汽车详细信息的报告。 创建PL / SQL匿名块的完整规范如下:

•使用显式游标,检索所有汽车注册,成本和型号名称 I_CAR表中的详细信息(注册,成本和模型名称)。

•如果汽车的成本低于或等于50,000美元,我们会确定汽车成本 类别为“预算车”。如果汽车成本在50,000美元到100,000美元之间, 汽车成本类别是“标准汽车”。对于所有其他汽车成本超过 $ 100,000,汽车成本类别是“高级汽车”。声明一个局部变量 v_carcategory as VARCHAR2(40)用于存储汽车费用类别。

•调用函数findtotalcarmodels以获取汽车总数 属于汽车的型号名称并将它们存储在局部变量中 名为v_totalcars

•使用带有接受汽车注册的参数的显式游标进行查找 最近在汽车上预订。你将不得不看看 date_reserved表中的I_BOOKING列。你不能使用 MAX功能。比较所有相关日期以找到最新日期。

•显示报告,显示汽车注册,汽车成本类别,汽车型号名称, 属于该型号的汽车总数和最近的预订 在那辆车上制造。

•最后,创建一个异常处理程序,在没有找到行时触发。该 异常处理程序应该将以下消息输出到屏幕:“不 行找到“。

重要说明:

•您不能使用任何隐式游标,表连接,子查询,集合运算符, 组函数或SQL函数(如COUNT)来创建PL / SQL 函数或PL / SQL匿名块。

•PL / SQL匿名块必须仅为一个块。别写了 阻止执行上述规范的每个任务。

到目前为止,我所知道的是迄今为止我所知道的甚至不是很有趣:

功能:

CREATE OR REPLACE Function findtotalcarmodels
    (model_name_in IN varchar2)
RETURN NUMBER
IS
    counter INTEGER := 0;
    CURSOR car_count_cur IS
      SELECT model_name FROM i_car WHERE model_name = model_name_in;
        Rec_car_details car_count_cur%ROWTYPE;
BEGIN
    OPEN car_count_cur;
    LOOP
        FETCH car_count_cur INTO Rec_car_details;
        EXIT WHEN car_count_cur%NOTFOUND;
        counter := counter + 1;
    END LOOP;

    CLOSE car_count_cur;
    RETURN counter;
END;

PL / SQL:

SET SERVEROUTPUT ON FORMAT WRAP SIZE 12000 
Declare 
v_model VARCHAR2(40);
v_cost NUMBER;
v_reg VARCHAR2(10);
v_carcategory VARCHAR2(40);
v_totalcars NUMBER;
cursor carcur IS 
SELECT * FROM i_car;
v_car carcur%ROWTYPE;
Begin 
FOR v_car IN carcur LOOP
Select Registration, cost, model_name, findtotalcarmodels(model_name)
INTO v_reg, v_cost, v_model,v_totalcars
from i_car
WHERE registration = v_car.registration;
If v_cost <=50000 THEN v_carcategory := 'Budget Car';
End IF;
If v_cost BETWEEN 50000 AND 100000 THEN v_carcategory := 'Standard Car';
End IF;
If v_cost >100000 THEN v_carcategory := 'Premium Car';
End If;
DBMS_OUTPUT.PUT_LINE('Registration:'|| ' '|| v_car.registration); 
DBMS_OUTPUT.PUT_LINE('Cost:'|| '$' ||v_car.Cost); 
DBMS_OUTPUT.PUT_LINE('Model Name:'|| ' '||v_car.model_name); 
DBMS_OUTPUT.PUT_LINE('Car Category:'|| ' '||v_carcategory);
DBMS_OUTPUT.PUT_LINE('Total number of Cars:'|| ' '||v_totalcars);
DBMS_OUTPUT.NEW_LINE; 
END LOOP; 
End;

编辑:上面的代码就是我现在所处的位置。剩下的唯一问题是在那里获得第二个显式游标以返回最近的租赁日期。这是让我难过的主要部分。

1 个答案:

答案 0 :(得分:3)

您可以使用以下显式光标来获取最近的租借日期,只需比较不存在大于最近data_reserved的data_reserved

CURSOR c1(v_car_registration VARCHAR2) IS 
  SELECT * from i_booking a
  WHERE a.registration=v_car_registration
  and not exists(select 1 from i_booking b 
  where b.registration=v_car_registration
  and b.date_reserved > a.date_reserved);

你可以调用显式游标,其中l_car_registration是传递给游标的变量,如下所示

FOR rec in c1(l_car_registration)
LOOP
--code here 
END LOOP;

EDIT1: - 使用PLSQL找到最近的日期

DECLARE
l_max_date DATE:=TO_DATE(1, 'J');--minimum date that can be entered in oracle database
cursor carcur IS 
SELECT * FROM i_car;
CURSOR c1(v_car_registration VARCHAR2) IS 
  SELECT * from i_booking a
  WHERE a.registration=v_car_registration;
 BEGIN
 For car_rec in carcur 
 LOOP
 l_max_date:=TO_DATE(1, 'J');
  for rec in c1(car_rec.registration)
  loop
   IF rec.date_reserved > l_max_date 
   then
    l_max_date:=rec.date_reserved ;
   end IF;
  end loop;
 dbms_output.put_line('car_registration--'||car_rec.registration||'the recent date--'||l_max_date);
 END LOOP;
 end;