如何使用 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;
我有一个由员工 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;