我的 Oracle SQL 代码正在编译我的代码块,该代码块将游标用于来自两个表的循环,但 dbms 输出行未显示结果

Posted

技术标签:

【中文标题】我的 Oracle SQL 代码正在编译我的代码块,该代码块将游标用于来自两个表的循环,但 dbms 输出行未显示结果【英文标题】:My Oracle SQL Code is compiling my block of code that uses a cursor for a loop from two tables but the dbms output line is not showing the results 【发布时间】:2021-12-23 16:19:55 【问题描述】:

我正在尝试编写一段 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 输出框中不会显示任何内容。错误是什么?

【问题讨论】:

如果你运行这个查询 "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' 和 date_assigned 【参考方案1】:

row_two 是一个已声明的局部变量,但从未为其分配任何值。因此,记录中的每个字段始终为null。当您将值row_one.date_assignednull 进行比较时,比较结果将始终为false。因此,您的 if 语句始终为 false,并且不会打印任何内容。

我对您发布的代码能够编译感到有些惊讶。 row_one 被声明为 jaherna42.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;

我通常还建议在您的查询中使用有意义的别名。将表别名为ab 就像使用单个字符变量名——不太可能帮助阅读代码的人理解它在做什么。使用一些一致的命名约定几乎肯定会更有用,例如,employee_ci 始终别名为 empci_inventory 始终别名为 inv

【讨论】:

以上是关于我的 Oracle SQL 代码正在编译我的代码块,该代码块将游标用于来自两个表的循环,但 dbms 输出行未显示结果的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 存储过程

赵强老师Oracle存储过程中的out参数

赵强老师Oracle存储过程中的out参数

oracle存储过程

wininet.h 不使用带有代码块的 GNU GCC 编译器进行编译

使用 Oracle 的 PL/SQL 函数中出现“无效指令”错误