我已经写了一个程序来检查一个房产的空房数量。
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更新时处理自动更新,任何指向我如何解决这个问题的指针都将非常感激。
答案 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;