我正在使用 Oracle Database 11g Express Edition 在 Oracle SQL Developer 3.2.2中使用 PL / SQL 。
到目前为止,我已经创建了一些表格:人口和部门。
CREATE TABLE sectores (
codS NUMBER(2),
nombreS VARCHAR2(20),
porcentS NUMBER(5,2),
ingresosS NUMBER(9,2),
num_pob NUMBER(3),
PRIMARY KEY (codS)
);
CREATE TABLE poblacion (
dni VARCHAR2(9),
nombre VARCHAR(12),
apellido1 VARCHAR2(12),
apellido2 VARCHAR2(12),
fechanac DATE,
direccion VARCHAR2(20),
cp VARCHAR2(5),
sexo VARCHAR2(1),
ingresos NUMBER(7,2),
gastosFijos NUMBER(7,2),
gastosAlim NUMBER(7,2),
gastosRopa NUMBER(7,2),
sector NUMBER(2),
PRIMARY KEY (dni),
FOREIGN KEY (sector) REFERENCES sectores (codS) ON DELETE SET NULL
);
因此,“人口”中的人们将以某种方式链接到部门。 我的意图是在同一部门中有3个以上的人时随时进行判断。
每当我在“人口”中插入一个新人时,我都会将Sectors中的num_pob增加1。我使用此TRIGGER进行此操作:
CREATE OR REPLACE TRIGGER ingresosS1
AFTER INSERT ON poblacion
REFERENCING NEW AS NUEVA
FOR EACH ROW
WHEN (NUEVA.sector IS NOT NULL)
BEGIN
UPDATE sectores
SET ingresosS = ingresosS + :NUEVA.ingresos
WHERE codS = :NUEVA.sector;
UPDATE sectores
SET num_pob = 1 + (SELECT num_pob FROM sectores WHERE codS = :NUEVA.sector)
WHERE codS = :NUEVA.sector;
UPDATE sectores
SET porcentS = 100 * ingresosS / (SELECT SUM(ingresosS) FROM sectores);
END;
/
我检查了这一点,到目前为止,一切正常。 现在,我声明此触发器:
CREATE OR REPLACE TRIGGER muchaGente
AFTER INSERT OR UPDATE ON sectores
FOR EACH ROW
WHEN (NEW.codS IS NOT NULL)
DECLARE
counter INTEGER;
numPOB INTEGER;
BEGIN
counter := :OLD.num_pob;
numPOB := counter - 1;
IF 3 < counter
THEN
DBMS_OUTPUT.ENABLE;
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('Trigger muchaGente: Hay más de 3 personas en el sector:' || :NEW.codS );
DBMS_OUTPUT.PUT_LINE('Trigger muchaGente: Antes había:' || numPOB ||', ahora:' || :OLD.num_pob );
DBMS_OUTPUT.PUT_LINE('');
END IF;
END;
/
每次我超过3个人标记时,这应该可以帮助我在屏幕上书写。当我在同一扇区中插入4个人时,它可以完美工作。这是插入4个人后的日志:
触发更多信息:部门中的3个角色:1
触发uchaGente:Anteshabía:3,ahora:4
但是,问题来了……删除表并再次创建它们后,当我插入5个人时,我在日志中得到了这个信息:
触发更多信息:部门中的3个角色:1
触发uchaGente:Anteshabía:3,ahora:4
触发更多信息:部门中的3个角色:1
触发uchaGente:Anteshabía:3,ahora:4
触发更多信息:部门中的3个角色:1
触发uchaGente:Anteshabía:3,ahora:4
触发更多信息:部门中的3个角色:1
触发uchaGente:Anteshabía:4,ahora:5
这有0个意义。我猜触发器以某种方式足够快地弄乱了我屏幕上的日志,你们知道反正可以解决这个问题吗?也许最后一个TRIGGER出现错误,但是我没有看到任何...
答案 0 :(得分:3)
DBMS_OUTPUT.PUT_LINE将字符串放在缓冲区中。这些仅在控制权返回给客户端时显示。在缓冲输出的PL / SQL程序单元返回其调用方之前,无法检索输出。
当您的条件(每扇区num_pob> 3)满足时,您应该考虑引发异常。
重写触发器。
Trigger1
CREATE OR REPLACE TRIGGER ingresosS1
AFTER INSERT ON poblacion
REFERENCING NEW AS NUEVA
FOR EACH ROW
WHEN (NUEVA.sector IS NOT NULL)
BEGIN
UPDATE sectores
SET ingresosS = ingresosS + :NUEVA.ingresos
WHERE codS = :NUEVA.sector;
UPDATE sectores
SET num_pob = COALESCE(num_pob,0) + 1
WHERE codS = :NUEVA.sector;
UPDATE sectores
SET porcentS = COALESCE(100 * ingresosS / (SELECT SUM(ingresosS) FROM sectores),0);
END;
/
Trigger2
CREATE OR REPLACE TRIGGER muchaGente
AFTER INSERT OR UPDATE ON sectores
FOR EACH ROW
WHEN (NEW.codS IS NOT NULL)
DECLARE
counter INTEGER;
numPOB INTEGER;
BEGIN
counter := :OLD.num_pob;
numPOB := counter - 1;
IF counter > 3
THEN
RAISE_APPLICATION_ERROR( -20001,
'There are more than 3 persons in the same Sector' );
END IF;
END;
/
因此,当条件满足时,它将引发异常
ORA-20001:同一部门有3个人以上