Oracle存储过程报PLS-00049 bad bind variable错误如何解决
错误原因与修复方案
1 核心编译错误(PLS-00049)产生原因
:NEW是Oracle触发器特有的伪记录变量,仅在行级触发器中可以使用,用于指代即将插入/更新的新行数据,存储过程中不存在该变量,所以编译器会报绑定变量不存在的错误。
2 其他需要修复的逻辑问题
除了编译错误外,存储过程还存在多处逻辑错误:
- 余额查询语句
select saldo into v_saldo from konto没有加where条件,会返回所有账户的余额,运行时会抛出TOO_MANY_ROWS异常 - 账户余额更新语句
update konto set saldo = v_saldo - p_belopp没有加where条件,会修改所有账户的余额,造成批量数据错误 - 执行顺序错误:当前是先插入交易记录再校验权限,即便权限不足也已经生成了无效交易记录
- 入参
p_radnr的类型引用了不存在的表kontoägare,会导致类型识别错误 - 权限校验函数
get_behörighet当前的SQL是无关联的交叉连接,只要传入的pnr和knr各自存在就返回1,并没有校验该用户是否持有对应账户,建议补充账户持有人关联关系后修改函数逻辑。
3 修正后的存储过程代码
create or replace procedure do_uttag ( p_radnr uttag.radnr%TYPE, p_pnr bankkund.pnr%TYPE, p_knr konto.knr%TYPE, p_belopp uttag.belopp%TYPE) as v_saldo konto.saldo%type; begin -- 先校验权限 if get_behörighet(p_pnr,p_knr) = 0 then raise_application_error(-20101, 'Du har inte behörigheten!'); end if; -- 查询对应账户的余额 select saldo into v_saldo from konto where knr = p_knr; -- 插入交易记录 insert into uttag( radnr, pnr, knr, belopp, datum ) values ( p_radnr, p_pnr, p_knr, p_belopp, SYSDATE ); -- 更新对应账户的余额 update konto set saldo = v_saldo - p_belopp where knr = p_knr; dbms_output.put_line('Saldot är nu = ' ||(v_saldo - p_belopp)); end; /
内容的提问来源于stack exchange,提问作者S.J.
相关产品推荐
相关产品推荐

