用于更新的Oracle PL / SQL存储过程游标

时间:2017-11-13 20:03:49

标签: oracle stored-procedures plsql cursor

我试图通过增加“inc”值来更新汽车的'damage_amt',但仅限于年份发生的事故。

CREATE or REPLACE PROCEDURE updateDMG(xyear VARCHAR2, inc NUMBER) AS
    CURSOR cur1 IS
        select a.DAMAGE_AMT
        from participated a join accident b
        on a.report_nr = b.report_nr
        for update;        
    p_dmg PARTICPATED.damage_amt%TYPE;
    p_year NUMBER;
    inc_dmg NUMBER;
BEGIN
    p_year:=xyear;
    inc_dmg:=inc;
    OPEN cur1;
    LOOP
        FETCH cur1 bulk collect INTO p_dmg;
        EXIT WHEN cur1%NOTFOUND;           
        UPDATE PARTICIPATED
        SET damage_amt = damage_amt * inc_dmg
        WHERE p_dmg like xyear;
    END LOOP;    
    CLOSE cur1;    
END updateDMG;
/
EXEC updateDMG('08', 0.10);

但是我收到了错误:

PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: begin function pragma procedure subtype <an identifier> <a double-quoted delimited-identifier> current cursor delete exists prior

显然,我对这类答案的语法缺乏了解。任何人都能指出我的错误吗?我似乎无法从搜索中找到任何东西。

编辑:错过了/在END之后。现在它实际上并没有更新行。

最终编辑:想出来。我认为我的一些变量是不必要的,但我可能是错的。

CREATE or REPLACE PROCEDURE updateDMG(xyear NUMBER, inc DECIMAL) AS
CURSOR cur1 IS
    select a.DAMAGE_AMT, extract(year from b.ACCIDENT_DATE)
    from participated a join accident b
    on a.report_nr = b.report_nr
    for update;

p_dmg PARTICIPATED.damage_amt%TYPE;
p_year NUMBER;
input_year NUMBER;
inc_dmg DECIMAL;

BEGIN
input_year:=xyear;
inc_dmg:=inc;
OPEN cur1;

    FETCH cur1 INTO p_dmg, p_year;


    MERGE INTO PARTICIPATED x
    USING ACCIDENT y
    ON (x.report_nr = y.report_nr)
    WHEN MATCHED THEN
    UPDATE SET x.damage_amt = x.damage_amt * (1 + inc_dmg/100)
    WHERE extract(year from y.accident_date) = input_year;



CLOSE cur1;



END updateDMG;
/
EXEC updateDMG(2008, 10);

1 个答案:

答案 0 :(得分:0)

我现在没有数据库来全面检查语法,但我会建议这样的事情:

CREATE OR REPLACE PROCEDURE updatedmg (p_year NUMBER, p_inc DECIMAL)
AS
   l_next_year   NUMBER;
   l_from_date   DATE;
   l_to_date     DATE;
BEGIN
   l_next_year := p_year + 1;
   l_from_date := TO_DATE (p_year || '-01-01', 'RRRR-MM-DD');
   l_to_date := TO_DATE (l_next_year || '-01-01', 'RRRR-MM-DD');

   UPDATE participated pt
      SET pt.damage_amt = pt.damage_amt * (1 + p_inc / 100)
    WHERE pd.report_nr IN (SELECT ad.report_nr
                             FROM accident ad
                            WHERE ad.accident_date >= l_from_date
                                  AND ad.accident_date < l_to_date);
END updatedmg;

它很简单,你可以更好地利用表上的索引。

我希望它有所帮助。

祝你好运!