目前我正在学习PLSQL,使用Oracle。我正在尝试获取比另一个表中的参数日期更早的数据。我希望程序获取所有数据,检查一些记录是否比param_value中的参数早(recv_date),并且如果是,则要启动我的警报程序。我在声明一个CURSOR和ln_pallets_container时遇到了问题。我知道我可以以某种方式进入ln_pallets数据只有在recv_date我已经过滤,但在这里,我不知道如何正确地做到这一点。也许我应该在过程之前声明光标,而不是在它之内?PLSQL Oracle游标程序
procedure CHECK_STOCK_DATE(warehouse_id_in IN warehouse.warehouse_id%TYPE)
IS
ln_pallet_count NUMBER;
ln_days_till_expiration param_value.param_value%TYPE;
CURSOR ln_pallets IS
SELECT container_id, recv_date
FROM wms_stock ws
ln_pallets_container%ROWTYPE;
BEGIN
OPEN ln_pallets;
LOOP
FETCH ln_pallets INTO ln_pallets_container;
EXIT WHEN ln_pallets%NOTFOUND;
SELECT param_value.param_value
INTO ln_days_till_expiration
FROM param_value
WHERE param_value.parameter_id = 266;
IF(ln_pallets_container.recv_date >= trunc(sysdate - ln_days_till_expiration)
ALARM.ALARM(WAREHOUSE_ID =>MY_COMMONS.GET_WHRS_ID,
SOURCE_TEXT => ln_pallets_container.container_id,
MESSAGE_CODE => 'Cannot find this container on warehouse. Check container code.');
END IF;
END LOOP;
CLOSE ln_pallets;
END;
看起来方式更好!正如你所说容易维护,但我有几个问题。 我不需要在这里声明任何东西?你只是使用了一些var ln_pallets_rec。稍后在LOOP中,source_text是我们想要使用的ln_pallets_rec.container_id,我不应该告诉哪种类型是ln_pallets_rec? –
[cursor-for-loop](https://docs.oracle.com/cloud/latest/db112/LNPLS/cursor_for_loop_statement.htm#LNPLS1155)的美妙之处在于Oracle会处理记录声明(有点像是什么时候你在1..10循环中做'我...'你不必声明i变量)加上光标处理。我更新了我的答案,以引用循环内正确的记录名称。值得注意的是,你可以显式声明游标,然后在for中引用游标名称,如下所示:'declare cursor my_cur as ...;在my_cur循环中开始my_rec ...,如果你想的话。 – Boneist
此外,隐式定义在cursor-for-loop中的记录范围纯粹是循环的,因此如果需要在循环外部引用它(例如,出于错误日志记录目的),则需要将其存储到变量中你有预先定义的,例如'声明my_var数字;开始for my_rec in(select ....)循环my_var:= my_rec.num_col; .... end loop;当其他人异常log_error(my_var);' – Boneist