目前我正在學習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