1

这是我的场景:我有一张员工表,我只需要考虑一个属性(薪水)就可以进行练习,所有其他属性都不需要。我必须创建另一个表(least_earners)并在该表中插入来自员工的最后 n 个(从用户输入)收入者。

我已经这样做了,但我想知道是否可以或者我是否犯了错误(我正在使用 Oracle DB 和 PL/SQL)。可以在不创建对象之前创建表吗?它是否像使用 SQL 进行正常创建一样工作?

DECLARE
 bottom_n_salaries 
   NUMBER := &bottom_salaries;
 CURSOR emp_cursor IS
   SELECT DISTINCT salary 
   FROM employees
   ORDER BY salary ASC;
 CREATE TYPE least_earners_obj 
   AS OBJECT (salary NUMBER(8));
 CREATE TYPE least_earners 
   AS TABLE OF least_earners_obj;
BEGIN
 OPEN emp_cursor;
   LOOP
     INSERT INTO least_earners 
     VALUE(FETCH emp_cursor);
   EXIT WHEN emp_cursor%ROWCOUNT >bottom_n_salaries
   OR emp_cursor%NOTFOUND;
   END LOOP;
 CLOSE emp_cursor;
END;
4

1 回答 1

0

尽管您可以使用它,但您不需要 PL/SQL 来执行此操作。您可以使用CREATE table AS ...

CREATE TABLE least_earners AS
  SELECT sal FROM (
    SELECT sal
    FROM employees
    ORDER BY sal)
  WHERE ROWNUM <= &bottom_salaries

或者,如果表已经存在,您可以使用INSERT INTO table SELECT ...

INSERT INTO least_earners (sal)
  SELECT sal FROM (
    SELECT sal
    FROM employees
    ORDER BY sal)
  WHERE ROWNUM <= &bottom_salaries

如果您的作业需要 PL/SQL,则上面的代码中存在一些错误(附录:我基于 INSERT ... FETCH,但我可能是错的),另外它对于手头的任务来说太复杂了,除非您是需要使用对象。


带有游标的附录PL/SQL 是必需的,因此相应地调整了答案...

首先有几点:

  • 我不认为INSERT INTO least_earners VALUE(FETCH emp_cursor)是有效的语法,但我不在可以测试它的地方。下面的例子没有使用它。

  • 您正在插入另一个表并%NOTFOUND 随后检查。你需要先做。

总的来说,应该这样做,但正如我上面提到的,我不在一个可以测试它的地方。可能需要调整:

DECLARE
 bottom_n_salaries NUMBER := &bottom_salaries;
 thisSalary NUMBER;
 CURSOR emp_cursor IS
   SELECT DISTINCT salary 
   FROM employees
   ORDER BY salary ASC;
BEGIN
 OPEN emp_cursor;
   LOOP
     FETCH emp_cursor INTO thisSalary;
     EXIT WHEN emp_cursor%ROWCOUNT > bottom_n_salaries
            OR emp_cursor%NOTFOUND;
     INSERT INTO least_earners VALUES (thisSalary);
   END LOOP;
 CLOSE emp_cursor;
END;

如果把EXIT WHEN你的“最低工资”逻辑弄乱了,你可以EXIT尝试两次:

     ...
     EXIT WHEN emp_cursor%NOTFOUND;
     INSERT INTO least_earners VALUES (thisSalary);
     EXIT WHEN emp_cursor%ROWCOUNT > bottom_n_salaries;
     ...
于 2013-05-10T17:29:07.457 回答