Ниже приведен пример кода процедуры. Сампример немного громоздок, т.к. взят непосредственно из рабочей базы без каких-либо модификаций и упрощений:
create or replace procedure jlb_set_kr_by_phone
is
is_region_found NUMERIC(1,0);
pers sch2.jlb_pays_temp2.account%TYPE;
vcode_count NUMERIC(5,0);
valid_vcode NUMERIC(5,0);
begin
--перебираем лицевые
FOR c1 IN (SELECT phone
FROM sch2.jlb_pays_temp2
WHERE phone IS NOT NULL AND account IS NULL) LOOP
is_region_found := 0;
vcode_count := 0;
--ищем код района лицевого счета
FOR c2 IN (SELECT
z.vcode,
c.npers
FROM
BS.BSSUBSACCT SA,
bs.bstechnic t,
bs.bstechsubs ts,
bs.bsclient c,
bs.vbszone z
WHERE
sa.nsubs = c.nclient_id
and ts.nsubs=sa.nsubs
and t.ntech_id=ts.ntech
and t.vcode = c1.phone
and c.nzone = z.nzone_id) LOOP
--признак физ. или юр. лица
pers := c2.npers;
--запомним найденный код р-на
valid_vcode := c2.vcode;
--укажем, что код р-на такого лицевого был найден
is_region_found := 1;
--считаем кол-во найденных р-нов
vcode_count := vcode_count + 1;
END LOOP; --end c2
--если все в порядке
IF is_region_found = 1 AND vcode_count = 1 AND pers IS NOT NULL THEN
UPDATE sch2.jlb_pays_temp2 p
SET p.is_invalid = 0, p.reg_code = valid_vcode
WHERE p.phone = c1.phone;
END IF;
--если не найдено кодов района (т.е. телефон не найден ни в одном из р-нов)
IF is_region_found = 0 THEN
UPDATE sch2.jlb_pays_temp2 p
SET p.is_invalid = 6
WHERE p.phone = c1.phone;
END IF;
--если неск. кодов района - тоже ошибка
IF is_region_found = 1 AND vcode_count > 1 THEN
UPDATE sch2.jlb_pays_temp2 p
SET p.is_invalid = 7
WHERE p.phone = c1.phone;
END IF;
--если это юрлицо
IF pers IS NULL THEN
UPDATE sch2.jlb_pays_temp2 p
SET p.is_invalid = 1
WHERE p.phone = c1.phone;
END IF;
END LOOP; --end c1
commit;
end jlb_set_kr_by_phone;
* This source code was highlighted with Source Code Highlighter.
В вышеприведенном примере, если говорить коротко, в таблице выставляются соостветствующие телефонам коды районов.Триггеры
Иногда достаточно удобно использовать триггеры. Допустим, у нас есть таблица файлов платежей, у записей которой есть потомки - платежи, хранящиеся в таблице платежей. Необходимо, чтобы при удалении файла автоматически удалялись и все платежи, связанные с ним. Ниже представлен простой пример:
--таблица файлов
create table jlb_files(
file_id number(10) PRIMARY KEY USING INDEX,
bank_id number(10),
file_name varchar2(50),
file_date DATE,
upload_date DATE,
total_pays_cnt NUMERIC(9, 0),
total_pays_sum NUMERIC(10, 2)
);
--таблица оплат
create table jlb_pays(
pay_id number(10) PRIMARY KEY USING INDEX,
file_id number(10),
account varchar2(20),
pay_sum NUMERIC(9,2),
pay_date DATE,
);
--триггер
CREATE OR REPLACE TRIGGER jlb_files_before_delete
BEFORE DELETE
ON jlb_files
FOR EACH ROW
DECLARE
BEGIN
DELETE FROM jlb_pays p
WHERE :old.file_id = p.file_id;
END;
* This source code was highlighted with Source Code Highlighter.
Очевидно, что jlb_files - это таблица файлов, а jlb_pays - это таблица дочерних платежей. При удалении файла из jlb_files автоматически удаляются все платежи с соответствующим file_id. В теле триггера видно, что old представляет собой удаляемую строку. http://www.techonthenet.com/oracle/triggers/before_delete.php
Комментариев нет:
Отправить комментарий