查询过程的结果,PL / SQL(Oracle DBMS)

时间:2014-02-05 20:56:08

标签: sql oracle stored-procedures

我已经写了一个程序来检查一个房产的空房数量。

CREATE OR REPLACE PROCEDURE prop_vacancy_query(
p_property_id       properties.tracking_id%TYPE
)
IS
property_refcur     SYS_REFCURSOR;
v_prop_rooms        properties.num_rooms%TYPE;
BEGIN
OPEN property_refcur FOR 
    'SELECT COUNT(room_status) FROM rooms 
     JOIN properties ON
     properties.property_id = rooms.property_id
     WHERE room_status = :status AND properties.tracking_id = :track_id' USING     'VACANT', p_property_id;
LOOP
    FETCH property_refcur INTO v_prop_rooms;
    EXIT WHEN property_refcur%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('Available Rooms: ' || v_prop_rooms);
END LOOP;
CLOSE property_refcur;
END;

我想在触发器中使用此过程,当可用房间数量返回为0时,自动将属性的状态设置为“OCCUPIED”。

我试过了

IF prop_vacancy_query(:NEW.property_status) = 0 THEN
   :NEW.property_status := 'OCCUPIED';
END IF;

但这不起作用。我如何在触发器中使用条件逻辑调用此过程?或者这是不可能的。

注意:我也担心这可能带来的性能问题,我不确定如何在DB更新时处理自动更新,任何指向我如何解决这个问题的指针都将非常感激。

2 个答案:

答案 0 :(得分:2)

首先,如果您有一段代码,其唯一目的是运行查询并返回值,请使用FUNCTION,而不是PROCEDURE。程序应该对数据进行某种操作。

其次,如果您不需要动态SQL,请不要使用动态SQL。它通常有点慢,但更重要的是,编写,支持和调试要困难得多。另外,您将编译时异常转换为运行时异常,因此在尝试运行代码之前,您将无法找到语法错​​误。

您可以相当简化代码

CREATE OR REPLACE FUNCTION get_num_vacancies(
    p_property_id       properties.tracking_id%TYPE
  )
  RETURN NUMBER
IS
  v_prop_rooms        properties.num_rooms%TYPE;
BEGIN
  SELECT COUNT(room_status) 
    INTO v_prop_rooms
    FROM rooms 
         JOIN properties ON
         properties.property_id = rooms.property_id
   WHERE room_status = 'VACANT'
     AND properties.tracking_id = p_property_id;

  RETURN v_prop_rooms;
END;

然后你可以按照你原来想要的方式调用这个函数

IF prop_vacancy_query(:NEW.property_status) = 0 THEN
   :NEW.property_status := 'OCCUPIED';
END IF;

答案 1 :(得分:1)

CREATE OR REPLACE PROCEDURE prop_vacancy_query(
p_property_id       properties.tracking_id%TYPE
status      OUT   NUMBER
)
.
.
.
status := 0
END;
/

并以这种方式打电话

outstatus NUMBER:= -1;

prop_vacancy_query(:NEW.property_id,outstatus);
IF out status = 0 THEN
   :NEW.property_status := 'OCCUPIED';
END IF;