这是我的情景: 我有一个表Employees我只需要考虑一个属性(工资),所有其他属性都不需要进行练习。我必须创建另一个表(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;
答案 0 :(得分: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;
...