我正在嘗試撰寫一段 SQL 代碼來比較兩個表中的兩個日期。一個表格顯示了獲得物品的時間(ci_acquired_date)。另一個表顯示了專案何時分配給員工 (date_acquired)。我的目標是使用一個回圈遍歷庫存并比較日期,看看分配給員工的任何日期是否小于獲得物品的日期(因為不可能為員工分配一個從未有過的物品)購買)并使用 DBMS 向我顯示它是哪個專案 ID 以及它的獲取和分配日期。
這是我的代碼:
declare
cursor task_five is
select a.date_assigned, a.ci_inv_id, b.ci_acquired_date
from jaherna42.employee_ci a
join jaherna42.ci_inventory b
on a.ci_inv_id = b.ci_inv_id
where a.user_or_support = 'USER';
row_one jaherna42.employee_ci%rowtype;
row_two jaherna42.ci_inventory%rowtype;
begin
for row_one in task_five
loop
if(row_one.date_assigned < row_two.ci_acquired_date)
then
dbms_output.put_line('The error is: ' || row_one.ci_inv_id);
dbms_output.put_line('The date assigned is: ' || row_one.date_assigned);
dbms_output.put_line('The date acquired is: ' || row_two.ci_acquired_date);
end if;
end loop;
end;
當我運行它時,腳本輸出框會顯示
PL/SQL procedure successfully completed.
但是我的 dbms 輸出框中不會顯示任何內容。錯誤是什么?
uj5u.com熱心網友回復:
row_two是一個區域變數,已宣告但從未為其分配任何值。因此,記錄中的每個欄位始終為null。當您將一個值row_one.date_assigned與 anull進行比較時,比較結果將始終為false。因此,您的if宣告始終存在,false并且不會列印任何內容。
我對您發布的代碼編譯感到有些驚訝。 row_one被宣告為 ajaherna42.employee_ci%rowtype但您定義的查詢似乎沒有從employee_ci. 也許您很幸運,您的表中列的順序和型別與查詢中的順序和型別相匹配,即使該查詢從多個表中提取資料。但這是一個幸運的意外。
如果您想將游標保留在宣告部分,您幾乎肯定希望針對游標 %rowtype而不是表來宣告您的區域變數。所以像這樣的事情可能是你真正想要的。
declare
cursor task_five
is
select a.date_assigned, a.ci_inv_id, b.ci_acquired_date
from jaherna42.employee_ci a
join jaherna42.ci_inventory b
on a.ci_inv_id = b.ci_inv_id
where a.user_or_support = 'USER';
row task_five%rowtype;
begin
for row in task_five
loop
if(row.date_assigned < row.ci_acquired_date)
then
dbms_output.put_line('The error is: ' || row.ci_inv_id);
dbms_output.put_line('The date assigned is: ' || row.date_assigned);
dbms_output.put_line('The date acquired is: ' || row.ci_acquired_date);
end if;
end loop;
end;
但是,除非這是您的分配要求,否則完全避免宣告并僅在代碼中使用隱式游標可能是有意義的。并在 SQL 而不是 PL/SQL 中進行比較
begin
for row in (select a.date_assigned, a.ci_inv_id, b.ci_acquired_date
from jaherna42.employee_ci a
join jaherna42.ci_inventory b
on a.ci_inv_id = b.ci_inv_id
where a.user_or_support = 'USER'
and a.date_assigned < b.ci_acquired_date)
loop
dbms_output.put_line('The error is: ' || row.ci_inv_id);
dbms_output.put_line('The date assigned is: ' || row.date_assigned);
dbms_output.put_line('The date acquired is: ' || row.ci_acquired_date);
end loop;
end;
我通常還建議在您的查詢中使用有意義的別名。將表別名為a和b就像使用單字符變數名一樣——不太可能幫助閱讀代碼的人理解它在做什么。使用一些一致的命名約定幾乎肯定會更有用,例如,employee_ci始終別名為emp并且ci_inventory始終別名為inv。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/365546.html
標籤:循环 加入 oracle-sqldeveloper 数据库游标 dbms-输出
上一篇:LEFT加入具有特定條件的子查詢
