如何使用 select 语句的 FOR 循环通过游标获取多个数据?

How to fetch multiple data through cursors using FOR loop for a select statement?

我有一个由员工 table 组成的老式 HR 架构。 table 有一列员工的工资。最低工资为 2100,最高工资为 24000。如果我要找到 table 的工资列中不存在的所有千工资(3000,4000,5000 ...)(在 2100 和 24000 之间),那么我该怎么办?

我想在游标的 select 语句上使用 FOR 循环,然后通过游标获取数据并显示它们。但它会引发错误。以下是我针对上述问题尝试过的方法:

declare
cursor c1 is
for i in 2000..25000
loop
select salary
from employees where salary<>i;
end loop;
sal number(10);
begin
for cur IN c1
loop
dbms_output.put_line(c1.sal);
end loop;
end;

以上代码抛出错误 "Expected instead of "

有人有治愈方法吗?

这可能是一个 pl/sql 解决方案,比您的尝试更简单;评论中的一些解释:

declare
    vNum number;
begin
    /* a loop for 2000 ... 25000 would give 2000, 2001, 2002, ... 25000 */
    for i in 2..25 loop
        /* check if the salary exists */
        select count(1)
        into vNum
        from employees
        where salary = i * 1000;
        --
        /* print the result */
        if vNum = 0 then
            dbms_output.put_line('Salary ' || i*1000 || ' does not exist');
        else        
            dbms_output.put_line('Salary ' || i*1000 || ' exists');
        end if;
    end loop;
end;    

请注意,这不是一个有效的解决方案,也不是我实现它的方式,但我希望它足够清楚,可以为您提供一些构建过程的提示。

这可能是一个 SQL 解决方案:

select sal
from ( 
        select (level +1) * 1000 as sal
        from dual
        connect by  (level +1) * 1000 <= 25000
     ) salaries
where salaries.sal not in ( select salary from employees) 

这里的 "tricky" 部分是内部查询,用于生成值列表 2000, 3000, ... 25000:

select (level +1) * 1000 as sal
from dual
connect by  (level +1) * 1000 <= 25000

这里我用了一个NOT IN,这可能不是完美的选择,但我希望它能很清楚;逻辑类似于“列出 2000 年的所有值,... 25000 不在 工资列表”。

这是一个纯粹的 SQL 解决方案,不需要您对最低和最高薪水进行硬编码,并使用 MINUS 而不是相关子查询:

SELECT min_salary + ( LEVEL - 1 ) * 1000 As salary
FROM   (
  SELECT MIN( CEIL( salary / 1000 ) * 1000 ) AS min_salary,
         MAX( FLOOR( salary / 1000 ) * 1000 ) AS max_salary
  FROM   employees
)
CONNECT BY min_salary + ( LEVEL - 1 ) * 1000 <= max_salary

MINUS

SELECT salary
FROM   employees;