在嵌入式SQL语句中,Oracle数据库会首先把不规范的标识符当作表中的列名来解释,如果不能找到匹配的列,Oracle才尝试把它当作当前作用范围内的PL/SQL变量来解释。所以当过程参数或定义的变量与表中列名相同时,会导致SQL语句限定条件的失效。
示例:
删除订单表中指定订单号的记录
procedure Del_Order(order_id in number, p_Message out varchar2) is
begin
delete orders where ordr_id = order_id;
exceptions when others then
return sqlerrm;
end Del_Order;
这段代码的执行结果是删除orders表中的一切内容。原因就是:SQL的名称 解析首先使用的是列名而不是PL/SQL标识符。这个where子句的的条件永远为真。
修正方法:
1.通过包或过程名来限定
delete orders where ordr_id = Del_Order.order_id
2.通过参数名加前缀,避免参数或变量与表中列名相同
procedure Del_Order(p_order_id in number, p_Message out varchar2) is
begin
delete orders where ordr_id = p_order_id;
end Del_Order;