想做一个触发器:发现表中的一个字段被改了,对应将另一个字段也改过来。如何实现?

sxbug 2005-01-07 09:51:06
这个问题和我前面提的问题是关联的,为了多给热心人分数,就新开了一贴:)

在这个表中,工程的编号是与工程属性有关系的,若用户改变了已输入的工程纪录的工程属性,触发器应将工程编号对应修改。修改的原则比较麻烦,假设有表:
工程编号 工程名称 工程属性
2005qx0001 123 1
2005qx0002 213 1
2005lx0001 312 2
2005lx0002 121 2
2005lx0003 212 2

若将倒数第二行的工程属性(2)改成(1),则表中的数据自动变成:

工程编号 工程名称 工程属性
2005qx0001 123 1
2005qx0002 213 1
2005lx0001 312 2
2005qx0003 121 1
2005lx0002 212 2
就是工程属性(2)的数据应该自动重新排序,被改动的纪录在工程属性(1)的序列中自动变成最后一条记录。


我写了一点,有问题。
CREATE OR REPLACE TRIGGER "JAMIS"."T_UPDATE_TASK_ATTR" AFTER
UPDATE OF "TASKATTRIBUTE"
ON "JAMIS"."TASK"
FOR EACH ROW
declare
myYear Varchar(10);
myTAALIAS Varchar(2);
newTaskID Varchar(10);
myYearCount NUMBER(10);

BEGIN
select (to_char(sysdate,'yyyy')||'%') into myYear from dual;
select TAALIAS into myTAALIAS from TASKATTRIB where TASKATTRIBUTEID=:new.TASKATTRIBUTE;
select to_char(sysdate,'yyyy')||myTAALIAS||lpad(to_char(myYearCount+1),4,'0') into newTaskID from dual;
:old.TASKID=newTaskID;
End;

望高人指点,谢谢
...全文
186 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
ORARichard 2005-01-08
  • 打赏
  • 举报
回复
before UPDATE 注意这是before
ORARichard 2005-01-08
  • 打赏
  • 举报
回复
CREATE OR REPLACE TRIGGER "JAMIS"."T_UPDATE_TASK_ATTR" before UPDATE OF "TASKATTRIBUTE"
ON "JAMIS"."TASK"
FOR EACH ROW
declare tmp varchar2(20);
BEGIN
if :new.TASKATTRIBUTE!=:old.TASKATTRIBUTE then
select max(TASKATTRIBUTEID) into tmp
from task
where TASKATTRIBUTE=:old.TASKATTRIBUTE;
select substr(tmp,1,6)||
substr(10000+substr(tmp,7,4)+1,2,4)
into :new.TASKATTRIBUTEID from dual;
end if;
End;
这样试试
sxbug 2005-01-08
  • 打赏
  • 举报
回复
to ORARichard(没钱的日子......)
错误提示:在此类触发器中,无法更新这个new值
ORARichard 2005-01-08
  • 打赏
  • 举报
回复
把exec去掉,exec是在SQLPLUS的命令,不是数据库的命令
sxbug 2005-01-08
  • 打赏
  • 举报
回复
to ORARichard(没钱的日子......)
我试一试.

顺便问一下,在触发器中怎样调用过程.这样可以吗?
CREATE OR REPLACE TRIGGER "JAMIS"."T_UPDATE_TASK_ATTR" AFTER
UPDATE OF "TASKATTRIBUTE"
ON "JAMIS"."TASK"
FOR EACH ROW
declare
myYear Varchar(10);
myTAALIAS Varchar(2);
newTaskID Varchar(10);
myYearCount NUMBER(10);

BEGIN
select (to_char(sysdate,'yyyy')||'%') into myYear from dual;
select TAALIAS into myTAALIAS from TASKATTRIB where TASKATTRIBUTEID=:new.TASKATTRIBUTE;
select to_char(sysdate,'yyyy')||myTAALIAS||lpad(to_char(myYearCount+1),4,'0') into newTaskID from dual;

exec pro_test1(newTaskID,:old.TaskID);--我写一个过程去修改工程编号,可以吗?

End;

谢谢
ORARichard 2005-01-08
  • 打赏
  • 举报
回复
--try

CREATE OR REPLACE TRIGGER "JAMIS"."T_UPDATE_TASK_ATTR" before UPDATE OF "TASKATTRIBUTE"
ON "JAMIS"."TASK"
FOR EACH ROW
BEGIN
if :new.TASKATTRIBUTE!=:old.TASKATTRIBUTE then
select max(TASKATTRIBUTEID) into :new.TASKATTRIBUTEID
from task
where TASKATTRIBUTE=:old.TASKATTRIBUTE;
select substr(:new.TASKATTRIBUTEID,1,6)||
substr(10000+substr(:new.TASKATTRIBUTEID,7,4)+1,2,4)
into :new.TASKATTRIBUTEID from dual;
end if;
End;
ORARichard 2005-01-08
  • 打赏
  • 举报
回复
--try

CREATE OR REPLACE TRIGGER "JAMIS"."T_UPDATE_TASK_ATTR" before UPDATE OF "TASKATTRIBUTE"
ON "JAMIS"."TASK"
FOR EACH ROW
BEGIN
if :new.TASKATTRIBUTE!=:old.TASKATTRIBUTE then
select max(TASKATTRIBUTEID) into :new.TASKATTRIBUTEID
from task
where TASKATTRIBUTE=:old.TASKATTRIBUTE;
end if;
select substr(:new.TASKATTRIBUTEID,1,6)||
substr(10000+substr(:new.TASKATTRIBUTEID,7,4)+1,2,4)
into :new.TASKATTRIBUTEID from dual;
select End;
baojianjun 2005-01-08
  • 打赏
  • 举报
回复
一個最苯的辦法:
--example:
--------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE PRO_TEST
AS
CURSOR CUR_TYPE IS
SELECT DISTINCT NAME FROM BAO_TEMP;
IS_TYPE VARCHAR2(20);
I NUMBER(10) ;
MIN_ID NUMBER(10) ;
MAX_ID NUMBER(10) ;
CURSOR CUR_ID IS
SELECT ID FROM BAO_TEMP
WHERE NAME = IS_TYPE
ORDER BY ID ;
IS_ID NUMBER(10) ;
BEGIN
OPEN CUR_TYPE;
LOOP
FETCH CUR_TYPE INTO IS_TYPE;
EXIT WHEN CUR_TYPE%NOTFOUND;

SELECT COUNT(*) INTO I
FROM BAO_TEMP
WHERE NAME = IS_TYPE ;
SELECT MIN(ID) INTO MIN_ID
FROM BAO_TEMP
WHERE NAME = IS_TYPE ;

OPEN CUR_ID;
LOOP
FETCH CUR_ID INTO IS_ID;
EXIT WHEN CUR_ID%NOTFOUND;

UPDATE BAO_TEMP
SET ID = MIN_ID +I-1
WHERE NAME = IS_TYPE
AND ID = IS_ID ;

I:=I+1 ;

END LOOP;
CLOSE CUR_ID;

END LOOP;
CLOSE CUR_TYPE;

COMMIT;
END;
/
---------------------------------------------------
SQL> SELECT * FROM BAO_TEMP
2 /

ID NAME
---------- --------------------
401 A
402 A
403 A
502 B
503 B
501 B

選取了 6 列

目前歷時: 00:00:00.15
SQL> UPDATE BAO_TEMP SET NAME = 'A' WHERE ID = 501
2 /

更新了 1 列

目前歷時: 00:00:00.00
SQL> COMMIT;

確認完成

目前歷時: 00:00:00.16
SQL> SELECT * FROM BAO_TEMP
2 /

ID NAME
---------- --------------------
401 A
402 A
403 A
502 B
503 B
501 A

選取了 6 列

目前歷時: 00:00:00.78
SQL> EXEC PRO_TEST

PL/SQL 程序順利完成

目前歷時: 00:00:00.32
SQL> SELECT * FROM BAO_TEMP
2 /

ID NAME
---------- --------------------
404 A
405 A
406 A
504 B
504 B
407 A

選取了 6 列

目前歷時: 00:00:00.78
baojianjun 2005-01-08
  • 打赏
  • 举报
回复
我覺得用過程來實現
用TRIGGER會產生問題的,就是不能在使用TRIGGER的時候
對本表進行修改

你的算法基本是自動搜索,自動增加和填充工程编号
sxbug 2005-01-08
  • 打赏
  • 举报
回复
to ORARichard(没钱的日子......)
工程编号 工程名称 工程属性
2005qx0001 123 1
2005qx0002 213 1
2005qx0004 312 1
2005qx0003 121 1
2005lx0001 212 2


to baojianjun(包子)
首先谢谢了.
我认为如何全部搜索修改,会不会很慢?
你设计的结果,好象和我的设想有区别.
如果简单一点:假如一条记录从属性(1)改成属性(2),属性(1)的序列就不管了,让用户自己手工改;记录改完后自动作为属性(2)的最后一条记录.


工程编号 工程名称 工程属性
2005qx0001 123 1
2005qx0002 213 1
2005lx0001 312 2
2005lx0002 121 2
2005lx0003 212 2

改为
工程编号 工程名称 工程属性
2005qx0001 123 1
2005qx0002 213 1
2005lx0001 312 2
2005qx0003 121 1
2005lx0003 212 2

这又如何实现?谢谢
ORARichard 2005-01-07
  • 打赏
  • 举报
回复
2005lx0001 312 2
如果是更新这条记录结果又是怎样呢

17,082

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧