改成after
如果是在不行可以考虑使用临时表+表级触发器
如果是在不行可以考虑使用临时表+表级触发器
解决方案 »
- 多线程数据库加锁
- 用sql实现求两字符串的公共子串(有测试数据)
- 我怎样把一个表空间的里面的表导入到另外一个表空间里面?
- 我再问一下oracle数据导入到sqlserver中的方法.有想法的朋友进来看看,帮下忙.谢了.我分不多了.不好意思.
- 如何取得oracle的所有表的表结构,表名称,索引信息?(在不知道有那些表的情况下)
- oracle安装问题:系统未满足安装要求,系统要求Service Pack1或更高的版本
- oracle初始化问题
- oracle入门,这也有错,见鬼
- 还是关于ROWNUM的问题
- 三层数据库系统的解决方案?
- 触发器问题!
- 字库ZHS16CGB231280改成ZHS16GBK,导出时出现的问题。
错误信息如下:
---------------------------
Error
---------------------------
ORA-04091: 表 PROJECT.GC_PHASE 发生了变化,触发器/函数不能读
ORA-06512: 在"PROJECT.TRI_PROGRESS", line 15
ORA-04088: 触发器 'PROJECT.TRI_PROGRESS' 执行过程中出错
View program sources of error stack?
---------------------------
是(Y) 否(N)
---------------------------
出错语句:
select sum(downpercent*downworkload) into intitemprogress from gc_phase where itemcode='LS20040112030K';
不知leborety(那只螃蟹) 所说的owner问题是什么意思??
1.触发器不可以执行COMMIT、ROLLBACK或SAVEPOINT语句,而且不可以调用执行这些语句之一的函数或过程。
2.触发器不可以声明long或LONG RAW变量。
3.触发器不可以在定义它的表上执行DML操作。
create table gc_phase_temp as select * from gc_phase where 某字段名=随便一个现在没有的值
这就建了一个空的临时表了,和gc_phase一模一样的,就是没有相应的索引对表gc_phase做行级触发,目的是把新的值insert到gc_phase_temp,用insert into gc_phase_temp
valuse(:new.字段1,:new.字段2....)
t1用来将处理的数据行存到包中变量中,t2用来执行对表的操作:
eg:
select sum(downpercent*downworkload) into intitemprogress from gc_phase where itemcode='LS20040112030K';
http://community.csdn.net/Expert/topic/3420/3420871.xml?temp=.7411463
下边创建临时表的语句要写在触发器中吗?如果写在触发器中每次触发器被触发的时候都要建一次名为Tmp的临时表,这样会不会出问题呢?
11:04:36 SQL> CREATE GLOBAL TEMPORARY TABLE Tmp(
11:04:39 2 rid varchar2(20))ON COMMIT DELETE ROWS;
在sql*plus里面创建一次就可以了
当commit时自动晴空临时表中的数据。
TYPE t_Majors IS TABLE OF students.major%TYPE
INDEX BY BINARY_INTEGER;
TYPE t_IDS IS TABLE OF students.ID%TYPE
INDEX BY BINARY_INTEGER;V_studentsmajors t_majors;
V_studentsIDs t_Ids;
V_numEntries BINARY_INTEGER :=0;
END Studentdata;CREATE OR REPLACE TRIGGER RlimitMajors
BEFORE INSERT OR UPDATE OF major ON students FOR EACH ROW
BEGIN
Studentdata.v_numEntries := studentsdata.v_numEntries + 1;
Studentdata.v-studentMajors(studentdata.v_numEntries) := :new.major;
Studentdata.v_studentIDs (studentdata.v_numEntries) := :new.id;
END RlimitMajors;CREATE OR REPLACE TRIGGER SlimitMajors
BEFORE INSERT OR UPDATE OF major ON students
BEGIN
v_MaxStudents CONSTANT NUMBER := 5;
v_CurrentStudents NUMBER;v_studentID students.ID%TYPE;
v_Major student.major%TYPE;BEGIN
FOR v_loopindex IN 1 .. studentdata.V_numEntries loop
v_studentID := studentdata.v_stidentIDs(v_loopindex);
v_major := studentdata.v_studentmajors(v_loopindex);SELECT count(*) INTO v_currentstudents FROM students
WHERE major = v_major;IF v_currentstudents > v_maxstudents THEN
RAISE_APPLICATION_ERROR(-20000,'Too many students for major '||v_major||
'because of student '|| v_studentID);
END IF;
END LOOP;END SlimitMajors;
http://community.csdn.net/Expert/topic/3420/3420871.xml?temp=.7411463
该贴提供的方法应能够解决你的问题了,佩服,向高手学习
能汇总出满足条件的数据来!这样我不是还要读取A表,出现老问题了吗!!
这里的downpercent,downworkload的值是你更新前还是更新后的值,应,'LS20040112030K'有可能是你要更新的那一条记录的,
是吗?临时表的设计可以按你的需求要做,应可以的,
CREATE GLOBAL TEMPORARY TABLE gc_phase_temp
(
fvaritemcode varchar2(20)
)ON COMMIT DELETE ROWS;--创建行级触发器,目的是保存varitemcode,
CREATE OR REPLACE TRIGGER "TRI_PROGRESS" after
UPDATE
OR DELETE ON "GC_PHASE" FOR EACH ROW
declare begininsert into gc_phase_temp values (:old.itemcode);end;--创建语句表触发器,也称表级触发器,主要的逻辑在这里
CREATE OR REPLACE TRIGGER "TRI_PROGRESS2" after
UPDATE
OR DELETE ON "GC_PHASE"
declare
varitemcode varchar2(20);
introws number;
intitemprogress int;
varparentcode varchar(20);
beginselect fvaritemcode into varitemcode from gc_phase_temp;--varitemcode:=:old.itemcode;
--是否末级项目,如果有子项目,不计算
select count(*) into introws from gc_item_child where parentcode=varitemcode;
if(introws>0) then
return;
end if;
--计算本级项目的进度--select sum(downpercent*downworkload) into intitemprogress from gc_phase where itemcode=varitemcode;
select sum(downpercent*downworkload) into intitemprogress from gc_phase where itemcode='LS20040112030K';
procselect(intitemprogress);-- from gc_phase;
if(intitemprogress < 1) then
intitemprogress:=0.000;
end if;
update gc_item_date set progress=intitemprogress where itemcode=varitemcode;
select parentcode into varparentcode from gc_item_date where itemcode=varitemcode;
--计算上级项目的进度
gc_calProgress(varparentcode);
end;--如果你的gc_calprogress里没有用到:new,:old的值的话,这样应该就可以了.