以下提到的程序旨在:
但是,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;
答案 0 :(得分:1)
使用单个SQL更新语句无法实现相同的效果吗?
UPDATE cptemplateworkcard tmpcard
SET tmpcard.budget_hour = (SELECT budget_hour
FROM cp_work_card cp
WHERE cp.job_id = tmpcard.jobid
AND rownum < 2)
WHERE EXISTS
(SELECT 1
FROM cp_work_card cp
WHERE cp.job_id = tmpcard.jobid);
我没有测试过这个,但原理是一样的......
编辑:鉴于你的约束,如果你必须使用一个程序,那么你可以不:
DECLARE
CURSOR c1
IS
SELECT DISTINCT
cp.job_id,
cp.budget_hour
FROM cp_work_card cp
INNER JOIN cptemplateworkcard temp
ON (cp.job_id = temp.jobid)
WHERE rownum < 2;
BEGIN
DBMS_OUTPUT.put_line( 'job_id : budget_hour' );
FOR c_rec IN c1
LOOP
UPDATE cptemplateworkcard tmpcard
SET tmpcard.budget_hour = c_rec.budget_hour
WHERE tmpcard.jobid = c_rec.job_id;
DBMS_OUTPUT.put_line( c_rec.job_id || ' : ' || c_rec.budget_hour );
END LOOP;
END;
编辑:
仅供参考,您当前的程序无效,因为您已将包含作业ID的变量命名为jobId
,这也恰好是表cptemplateworkcard
中列的名称。因此,当您执行更新时,它默认认为您的WHERE
子句正在将表列与自身进行比较,从而使用bHours
的值更新每一行。当程序结束时,显然是bHours
的最后一个值,即从光标返回的最终值是什么,因此您看到表中的所有值都设置为此最终值。
如果您将jobId
变量重命名为v_jobid
,那么它应该可以解决问题。
希望它有所帮助...
如果唯一的限制是它必须在PL / SQL过程块中,那么这将是最有效的过程:
BEGIN
UPDATE cptemplateworkcard tmpcard
SET tmpcard.budget_hour = (SELECT budget_hour
FROM cp_work_card cp
WHERE cp.job_id = tmpcard.jobid
AND rownum < 2)
WHERE EXISTS
(SELECT 1
FROM cp_work_card cp
WHERE cp.job_id = tmpcard.jobid);
DBMS_OUTPUT.put_line(SQL%rowcount||' record(s) updated');
END;
答案 1 :(得分:0)
如果您的陈述/条件都正确,那么执行以下语句而不是存储过程应该完全符合您的要求:
UPDATE cptemplateworkcard tc
SET tc.BUDGET_HOUR=(SELECT cpw.BUDGET_HOUR FROM cp_work_card cpw where cpw.job_id=tc.JOBID AND rownum<2)
WHERE tc.JOBID IN (select cp.job_id from cp_work_card cp);