极其离奇的问题,大家近来看看,解决了100分相送!!

waxle 2004-08-14 02:46:54
救命啊,触发器中是否可以使用循环结构??
这是我用循环结构写的触发器。
CREATE OR REPLACE TRIGGER UPDATERESULTD AFTER INSERT ON RESULTR
FOR EACH ROW
DECLARE
LOOP1 INTEGER;
SECNODE VARCHAR2(10);
RATIODR NUMBER(8,3);
BEGIN
SELECT COUNT(*) INTO LOOP1 FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE;
FOR I IN 1..LOOP1 LOOP
SELECT SECNODE INTO SECNODE FROM ((SELECT SECNODE FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE AND ROWNUM<(I+1)) MINUS (SELECT SECNODE FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE AND ROWNUM<I)) WHERE ROWNUM=1;
SELECT RATIODR INTO RATIODR FROM ((SELECT RATIODR FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE AND ROWNUM<(I+1)) MINUS (SELECT RATIODR FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE AND ROWNUM<I)) WHERE ROWNUM=1;
INSERT INTO RESULTD VALUES(:NEW.YR,SECNODE,:NEW.WATER_QR*RATIODR);
END LOOP;
END;
/

这是相关的三个表建表的语句
CREATE TABLE RESULTR(YR CHAR(10),FIRNODE CHAR(10),WATER_QR NUMBER(8,3));
CREATE TABLE RESULTD(YR CHAR(10),SECNODE CHAR(10),WATER_QD NUMBER(8,3));
CREATE TABLE RELATION_DR(FIRNODE CHAR(10),SECNODE CHAR(10),RATIODR NUMBER(5,2));

但是在使用的时候有些插入出错了,出错信息如下:
ERROR 位于第 1 行:
ORA-01403: 未找到数据
ORA-06512: 在"LRH.UPDATERESULTD", line 9
ORA-04088: 触发器 'LRH.UPDATERESULTD' 执行过程中出错

大虾们救命啊,是不是不能用循环结构,能不能提示一下或帮忙改一下,谢谢!!!


我的三个表格的数据吧。
第一个关系表:
SQL> select * from relation_dr;

FIRNODE SECNODE RATIODR
---------- ---------- ----------
HETIAN P01 .6
HETIAN P02 .3
HETIAN P03 .1
AKESHU P04 .5
AKESHU P05 .3
AKESHU P06 .05
AKESHU P07 .15
NONGYISHI P08 .25
NONGYISHI P09 .35
NONGYISHI P10 .15
NONGYISHI P11 .25

FIRNODE SECNODE RATIODR
---------- ---------- ----------
KUELE P12 1

然后我插入以下语句时出错,好像只有HETIAN和AKESHU可以插入2条或以上数据,其他都不可以了,似乎这两个值已经注册了一样,不知道什么原因。
SQL> INSERT INTO RESULTR VALUES(2002,'HETIAN',500);

已创建 1 行。

SQL> INSERT INTO RESULTR VALUES(2002,'AKESHU',550);

已创建 1 行。

SQL> INSERT INTO RESULTR VALUES(2002,'NONGYISHI',400);
INSERT INTO RESULTR VALUES(2002,'NONGYISHI',400)
*
ERROR 位于第 1 行:
ORA-01403: 未找到数据
ORA-06512: 在"LRH.UPDATERESULTD", line 9
ORA-04088: 触发器 'LRH.UPDATERESULTD' 执行过程中出错


SQL> INSERT INTO RESULTR VALUES(2002,'KUELE',400);

已创建 1 行。

但是如果把RELATION_DR中NONGYISHI的条数改成1条,即删除3条数据。
如下语句:
SQL> delete from relation_dr where secnode IN ('P09','P10','P11');

已删除3行。

SQL> INSERT INTO RESULTR VALUES(2002,'NONGYISHI',400);

已创建 1 行。
即插入了数值。好像要加入其他的FIRNODE也是一样的,在RELATION_D不能超过一条数据,否则出错。不知道具体什么原因,大虾们救命啊。

而且非常奇怪的是当我重新建一个触发器,更换表名之后也是只有HETIAN和AKESHU这两项在RELATION_DR表能超过两行的数据,其他都不可以,好像出现触发器的系统记忆功能一样,不知道怎么回事啊,感觉非常离奇。敬请哪位大虾相告,多谢多谢!!
解决必定加分100。
...全文
207 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
EnjoyLift 2004-08-16
  • 打赏
  • 举报
回复
问题的关键在于你没有处理NO_DATA_FOUND异常(只要你的SELECT语句没有数据返回就会引起这个异常),至于是不是SELECT能不能查到数据很容易测试,由于你这个触发器是数据插入后执行的,所以可以在遇到异常后把你的这个触发器禁止,然后执行你的触发器里的SELECT语句看是不是有没有数据返回的SELECT语句,还有你的SQL语句的书写没有缩进,太难看了
EnjoyLift 2004-08-16
  • 打赏
  • 举报
回复
ORA-01403 no data found
Topics
What is this error?
How to fix it
1-August-2001
Author: Kavitha Soundararajan


--------------------------------------------------------------------------------

What causes this error?
This error occurs when a SQL statement, written within a PL/SQL block, does not fetch any data.


Back to top of file
--------------------------------------------------------------------------------

How to fix it
The easiest fix would be is to handle the error in the PL/SQL block

When a SQL statement is written within a PL/SQL block, enclose the SQL with a BEGIN and END statement. Handle the exception and raise a user-friendly message or handle the rest of the processing.

Eg:

CREATE OR REPLACE PROCEDURE test_proc (p_empno IN NUMBER) IS
l_empname VARCHAR2(50);
BEGIN

SELECT empname
INTO l_empname
FROM emp
WHERE empno = p_empno;

IF l_empname = 'Sarah Jones' THEN
INSERT INTO empresult values ('105', 'Found Sarah Jones');
END IF;
END;
/
The above procedure has not handled the error that would be raised if the select statement did not find the specified empno. See the following for the error raised:

SQL> exec test_proc (1)
begin test_proc (1); end;

*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at "TAROT.TEST_PROC", line 4
ORA-06512: at line 1

If you want to procedure to execute properly without errors on the screen, then you would have to handle the error.

The Exception needs to be controlled by adding an exception handler to the code. The above code has been modified to handle an exception NO_DATA_FOUND. This is the name of the exception that the error relates to.

CREATE OR REPLACE PROCEDURE test_proc (p_empno IN NUMBER) IS
l_empname VARCHAR2(50);
BEGIN

SELECT empname
INTO l_empname
FROM emp
WHERE empno = p_empno;

IF l_empname = 'Sarah Jones' THEN
INSERT INTO empresult values ('105', 'Found Sarah Jones');
END IF;

EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO empresult values(p_empno, 'Did not find Sarah Jones');
END;
/

If you execute the above procedure now, this is what you would see:

SQL> exec test_proc (1)

PL/SQL procedure successfully completed.

SQL> select *
2 from empresult;

EMPNO EMPNAME
--------- --------------------------------------------------
1 Did not find Sarah Jones

As the exception was handled, a row was inserted into the empresult table with the error message you specified.

When the exception is raised, the control jumps from the select statement to the exception handler routine. Any code after the Select will not get executed if an exception has been raised. But if you do have some code that needs to be executed after the select has been executed, irrespective of whether the select was successful or not, then you would need to nest the begin and end statements.

CREATE OR REPLACE PROCEDURE test_proc (p_empno IN NUMBER) IS
l_empname VARCHAR2(50);
l_count NUMBER;
BEGIN
BEGIN
SELECT empname
INTO l_empname
FROM emp
WHERE empno = p_empno;

IF l_empname = 'Sarah Jones' THEN
INSERT INTO empresult values ('105', 'Found Sarah Jones');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO empresult values(p_empno, 'Did not find Sarah Jones');
END;

l_count := 1;
-- More statements
-- And more
END;
/

The procedure has been changed to NEST the BEGIN and END statements. So, if the SELECT statement fails, the control will enter the exception handler and then proceed on to the next line which is l_count := 1 statement.

It is always best to have separate BEGIN and END statements for every SELECT written in your PL/SQL block, which enables you to raise SELECT-senstitive error messages.

Please do not use SQL%NOTFOUND to check for this error. When the NO_DATA_FOUND exception is raised, then the program will look for the Exception handler. If it does not find one, then the error message is thrown to the screen.

waxle 2004-08-14
  • 打赏
  • 举报
回复
怎么没有人回啊,自己顶一个!!!
waxle 2004-08-14
  • 打赏
  • 举报
回复
但是那个RELATION_DR中的数值你也看到了,有NONGYISHI的值啊,不可能会没有值啊,数据结构都是一样的啊,为什么NONGYISHI就不可以呢??我的流程是这样的。
当插入数值到RESULTR时,根据插入RESULT_DR中的FIRNODE看看有几个SECNODE,有几个SECNODE就循环几次(loop1次),然后根据插入到RESULT_DR中的FIRNODE查询对应的SECNODE和RATIODR,然后写入到RESULTD中,即写入YR,SECNODE,以及根据比例(RATIODR)得到的WATER_DR。
当插入NONGYISHI是,按照流程应该时。
察看RELATION_DR表,然后可以得到loop1=4 因为有4条记录。
然后i=1根据我的记录则可以找到第一条记录。怎么可能没有记录呢??
大虾麻烦帮忙仔细看看请指教。而且我更换用户结果还是一样的。
dinya2003 2004-08-14
  • 打赏
  • 举报
回复
CREATE OR REPLACE TRIGGER UPDATERESULTD
AFTER INSERT ON RESULTR
FOR EACH ROW
DECLARE
LOOP1 INTEGER;
SECNODE VARCHAR2(10);
RATIODR NUMBER(8,3);
BEGIN
SELECT COUNT(*) INTO LOOP1 FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE;
FOR I IN 1..LOOP1 LOOP
SELECT SECNODE INTO SECNODE FROM ((SELECT SECNODE FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE AND ROWNUM<(I+1)) MINUS (SELECT SECNODE FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE AND ROWNUM<I)) WHERE ROWNUM=1;
SELECT RATIODR INTO RATIODR FROM ((SELECT RATIODR FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE AND ROWNUM<(I+1)) MINUS (SELECT RATIODR FROM RELATION_DR WHERE FIRNODE=:NEW.FIRNODE AND ROWNUM<I)) WHERE ROWNUM=1;

--增加以下部分判断是否有值,有可能select中没有值;
IF SECNODE IS NULL THEN
SECNODE:='没有值'||:NEW.YR;
END IF;
IF RATIODR IS NULL THEN
RATIODR:=0;
END IF;
-------------------------------------
INSERT INTO RESULTD VALUES(:NEW.YR,SECNODE,:NEW.WATER_QR*RATIODR);
END LOOP;
END;
内容概要:本文围绕基于三重移相控制(TPS)的双有源桥(DAB)高频隔离DC-DC变换器开展系统性研究,重点构建了其在Simulink环境下的高精度仿真模型。研究全面涵盖SPS单相移相、DPS双重重移相与TPS三重移相等多种控制策略的建模、实现与性能对比,深入分析不同模式下变换器的功率传输特性、软开关实现条件及功率回流问题,旨在提升DAB在交直流混合微电网、能量路由器、多端口柔性互联装置等场景中的转换效率与动态响应能力。通过对ZVS(零电压切换)条件的精确控制与移相角参数的优化,有效降低了开关损耗,增强了系统整体能效与运行稳定性。该仿真模型具有良好的可扩展性,适用于复杂电能转换系统的科研验证与工程开发。; 适合人群:电力电子、电气工程及其自动化等相关专业的硕士研究生、博士生、科研人员以及从事新能源变换器、柔性输配电系统设计的工程技术人员。; 使用场景及目标:①掌握双有源桥DAB变换器的基本工作原理及其在高频隔离场合的核心优势;②深入理解三重移相控制策略的设计机理、控制自由度分配及其在效率优化中的关键作用;③构建并调试可用于科研论文撰写、项目申报或实际系统验证的高保真Simulink仿真模型,支撑理论分析与实验对比。; 阅读建议:建议结合MATLAB/Simulink平台进行动手实践,重点关注主电路拓扑搭建、移相控制模块设计、驱动信号时序配置及ZVS实现条件的仿真观测,推荐通过对比SPS、DPS与TPS三种模式的稳态与动态响应曲线,深入掌握各控制策略的适用边界与优化方向。
【重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!

17,134

社区成员

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

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