Oracle 过程中的更新查询更新为错误值
下面提到的过程旨在:
- 从 cpTemplateWorkCard 中存在的 cp_work_card 中获取 jobid
- 从 cp_work_card 中获取该 jobid 的第一条 bhours 记录
- 将其更新到 cpTemplateworkCard
但是,cpTemplateworkCard 的所有行都将更新为最后找到的 bHours 值排。但是,变量中的值在执行时被正确存储
DECLARE
jobId VARCHAR2(30);
bHours float;
idx NUMBER(4,0);
CURSOR c1
IS
select distinct
cp.job_id
from cp_work_card cp,
cptemplateworkcard temp
where cp.job_id = temp.JOBID;
BEGIN
idx:=1;
DBMS_OUTPUT.PUT_LINE('id : jobId : bHours');
OPEN c1;
LOOP
FETCH c1 INTO jobId;
EXIT WHEN C1%NOTFOUND;
select cpw.BUDGET_HOUR
into bHours
from cp_work_card cpw
where cpw.job_id=jobId
AND rownum<2;
/*DBMS_OUTPUT.PUT_LINE('Budget Hours: '||bHours);
UPDATE TO CPTEMPLATE*/
UPDATE cptemplateworkcard tmpCard
SET tmpCard.BUDGET_HOUR=bHours
where tmpCard.JOBID=jobId;
DBMS_OUTPUT.PUT_LINE(idx || ' : ' || jobId || ' : ' || bHours);
idx:= idx+1;
END LOOP;
CLOSE c1;
END;
The below mentioned procedure is intended to:
- fetch jobids from cp_work_card which exist in cpTemplateWorkCard
- Fetch the first record of bhours for the jobid from the cp_work_card
- update the same to cpTemplateworkCard
Hwoever, all the rows of cpTemplateworkCard are updated with the value of bHours found in last row. But, the values in the variable are stored correctly while execution
DECLARE
jobId VARCHAR2(30);
bHours float;
idx NUMBER(4,0);
CURSOR c1
IS
select distinct
cp.job_id
from cp_work_card cp,
cptemplateworkcard temp
where cp.job_id = temp.JOBID;
BEGIN
idx:=1;
DBMS_OUTPUT.PUT_LINE('id : jobId : bHours');
OPEN c1;
LOOP
FETCH c1 INTO jobId;
EXIT WHEN C1%NOTFOUND;
select cpw.BUDGET_HOUR
into bHours
from cp_work_card cpw
where cpw.job_id=jobId
AND rownum<2;
/*DBMS_OUTPUT.PUT_LINE('Budget Hours: '||bHours);
UPDATE TO CPTEMPLATE*/
UPDATE cptemplateworkcard tmpCard
SET tmpCard.BUDGET_HOUR=bHours
where tmpCard.JOBID=jobId;
DBMS_OUTPUT.PUT_LINE(idx || ' : ' || jobId || ' : ' || bHours);
idx:= idx+1;
END LOOP;
CLOSE c1;
END;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您的语句/条件全部正确,则执行以下语句而不是存储过程应该完全符合您的要求:
IF your statements/conditions are all correct then executing the following statement instead of your stored procedure should do exactly what you want:
难道不能用一条 SQL 更新语句来实现同样的效果吗?
我还没有测试过这个,但原理是相同的......
编辑:考虑到你的限制,如果你必须使用一个过程,那么你不能:
编辑:
仅供参考,您当前的过程不起作用,因为您已将保存作业 ID 的变量命名为
jobId
,这也恰好是表cptemplateworkcard
中的列名称代码>.因此,当您执行更新时,它默认认为您的WHERE
子句正在将表列与其自身进行比较,从而使用bHours
的值更新每一行。当该过程完成时,显然bHours
的最后一个值是从光标返回的最终值,因此您会看到表中的所有值都设置为该最终值。如果您重命名将
jobId
变量更改为v_jobid
之类的值,那么它应该可以解决问题。希望它有所帮助...
如果唯一的约束是它必须位于 PL/SQL 过程块中,那么这将是最有效的过程:
Couldn't you achieve the same with a single SQL update statement?
I haven't tested this but the principle is the same...
EDIT: Given your constraints and if you must use a procedure then could you not:
EDIT:
FYI, your current procedure isn't working because you have named your variable holding the job ID as
jobId
which also happens to be the name of a column in the tablecptemplateworkcard
. Therefore when you perform your update it defaults to thinking yourWHERE
clause is comparing the table column with itself thereby updating every row with whatever the value ofbHours
is. When the procedure has finished, obviously the last value ofbHours
what the final value returned from the cursor hence you are seeing all the values in the table set to this final value.If you rename your
jobId
variable to something likev_jobid
then it should solve the problem.Hope it helps...
If the only constraint is that it must be in a PL/SQL procedureal block then this will be the most efficient procedure: