创建存储过程时出现问题
Issue when creating a stored procedure
我正在尝试创建一个存储过程,如下所示:
CREATE OR REPLACE PROCEDURE storedprocedure(emp number) AS
BEGIN
DECLARE
-- create the cursor based on a query
cursor emp_cursor is
select e.employeeid, firstname, lastname, e.departmentid, e.title,
salary, d.departmentname, billrate
from employees e
full join departments d on e.departmentID = d.departmentID
full join employeeproject p on e.employeeID = p.employeeID where e.employeeID = emp;
BEGIN
open emp_cursor;
-- first display information about the employee
dbms_output.put_line('- -');
dbms_output.put_line('- -');
dbms_output.put_line('Employee#' || e.employeeid
|| ' Name:' || TRIM(e.firstname) || ' ' || TRIM(e.lastname)
|| ' Dept: ');
dbms_output.put_line('_________________________________________________________');
dbms_output.put_line('- -');
dbms_output.put_line('- - Title: ' || e.title
|| ' Salary: ' || to_char(e.salary,'9,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(billrate,'9,999.99'));
-- next call the stored procedure to show department information
END;
END;
/
但是编译出错。当我 show errors
它告诉我 e.employeeID
、e.title
和 billrate
必须全部声明,但它们是原始查询。我在这里做错了什么?我是否误解了宣布它们的含义?
这些是被查询表中存在的所有列,运行 查询 SQL 得到结果。
您正在打开游标,但您没有将它提取到任何东西中——无论是一系列标量变量还是记录类型——这通常会在循环中完成。然后,当您在循环中时,您指的是 variables/record,而不是游标查询中使用的 table - 这超出了游标声明之外的范围。
有一个稍微简单的隐式游标循环,在这种情况下您可能会发现它更容易一些:
CREATE OR REPLACE PROCEDURE storedprocedure(emp number) AS
BEGIN
FOR rec IN (
select e.employeeid, firstname, lastname, e.departmentid, e.title,
salary, d.departmentname, billrate
from employees e
full join departments d on e.departmentID = d.departmentID
full join employeeproject p on e.employeeID = p.employeeID where e.employeeID = emp
)
LOOP
-- first display information about the employee
dbms_output.put_line('- -');
dbms_output.put_line('- -');
dbms_output.put_line('Employee#' || rec.employeeid
|| ' Name:' || TRIM(rec.firstname) || ' ' || TRIM(rec.lastname)
|| ' Dept: ');
dbms_output.put_line('_________________________________________________________');
dbms_output.put_line('- -');
dbms_output.put_line('- - Title: ' || rec.title
|| ' Salary: ' || to_char(rec.salary,'9,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(rec.billrate,'9,999.99'));
-- next call the stored procedure to show department information
END LOOP;
END;
/
请注意,循环内对列的所有引用都是 rec.<field>
的形式 - 它们是从循环中这次的记录中获取的,而不是直接来自底层的 tables。
你还有一个嵌套块,它没有任何危害但没有用,所以我把它去掉了。
如果您特别想使用显式打开-获取-关闭游标处理,它看起来像这样:
CREATE OR REPLACE PROCEDURE storedprocedure(emp number) AS
-- create the cursor based on a query
cursor emp_cursor is
select e.employeeid, firstname, lastname, e.departmentid, e.title,
salary, d.departmentname, billrate
from employees e
full join departments d on e.departmentID = d.departmentID
full join employeeproject p on e.employeeID = p.employeeID where e.employeeID = emp;
-- record variable based on cursor definition
rec emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
LOOP
-- fetch the next row result from the cursor into the record vairable
FETCH emp_cursor INTO rec;
-- break out of the loop if there are no more results to fetch
EXIT WHEN emp_cursor%NOTFOUND;
-- first display information about the employee
dbms_output.put_line('- -');
dbms_output.put_line('- -');
dbms_output.put_line('Employee#' || rec.employeeid
|| ' Name:' || TRIM(rec.firstname) || ' ' || TRIM(rec.lastname)
|| ' Dept: ');
dbms_output.put_line('_________________________________________________________');
dbms_output.put_line('- -');
dbms_output.put_line('- - Title: ' || rec.title
|| ' Salary: ' || to_char(rec.salary,'9,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(rec.billrate,'9,999.99'));
-- next call the stored procedure to show department information
END LOOP;
CLOSE emp_cursor;
END;
/
我正在尝试创建一个存储过程,如下所示:
CREATE OR REPLACE PROCEDURE storedprocedure(emp number) AS
BEGIN
DECLARE
-- create the cursor based on a query
cursor emp_cursor is
select e.employeeid, firstname, lastname, e.departmentid, e.title,
salary, d.departmentname, billrate
from employees e
full join departments d on e.departmentID = d.departmentID
full join employeeproject p on e.employeeID = p.employeeID where e.employeeID = emp;
BEGIN
open emp_cursor;
-- first display information about the employee
dbms_output.put_line('- -');
dbms_output.put_line('- -');
dbms_output.put_line('Employee#' || e.employeeid
|| ' Name:' || TRIM(e.firstname) || ' ' || TRIM(e.lastname)
|| ' Dept: ');
dbms_output.put_line('_________________________________________________________');
dbms_output.put_line('- -');
dbms_output.put_line('- - Title: ' || e.title
|| ' Salary: ' || to_char(e.salary,'9,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(billrate,'9,999.99'));
-- next call the stored procedure to show department information
END;
END;
/
但是编译出错。当我 show errors
它告诉我 e.employeeID
、e.title
和 billrate
必须全部声明,但它们是原始查询。我在这里做错了什么?我是否误解了宣布它们的含义?
这些是被查询表中存在的所有列,运行 查询 SQL 得到结果。
您正在打开游标,但您没有将它提取到任何东西中——无论是一系列标量变量还是记录类型——这通常会在循环中完成。然后,当您在循环中时,您指的是 variables/record,而不是游标查询中使用的 table - 这超出了游标声明之外的范围。
有一个稍微简单的隐式游标循环,在这种情况下您可能会发现它更容易一些:
CREATE OR REPLACE PROCEDURE storedprocedure(emp number) AS
BEGIN
FOR rec IN (
select e.employeeid, firstname, lastname, e.departmentid, e.title,
salary, d.departmentname, billrate
from employees e
full join departments d on e.departmentID = d.departmentID
full join employeeproject p on e.employeeID = p.employeeID where e.employeeID = emp
)
LOOP
-- first display information about the employee
dbms_output.put_line('- -');
dbms_output.put_line('- -');
dbms_output.put_line('Employee#' || rec.employeeid
|| ' Name:' || TRIM(rec.firstname) || ' ' || TRIM(rec.lastname)
|| ' Dept: ');
dbms_output.put_line('_________________________________________________________');
dbms_output.put_line('- -');
dbms_output.put_line('- - Title: ' || rec.title
|| ' Salary: ' || to_char(rec.salary,'9,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(rec.billrate,'9,999.99'));
-- next call the stored procedure to show department information
END LOOP;
END;
/
请注意,循环内对列的所有引用都是 rec.<field>
的形式 - 它们是从循环中这次的记录中获取的,而不是直接来自底层的 tables。
你还有一个嵌套块,它没有任何危害但没有用,所以我把它去掉了。
如果您特别想使用显式打开-获取-关闭游标处理,它看起来像这样:
CREATE OR REPLACE PROCEDURE storedprocedure(emp number) AS
-- create the cursor based on a query
cursor emp_cursor is
select e.employeeid, firstname, lastname, e.departmentid, e.title,
salary, d.departmentname, billrate
from employees e
full join departments d on e.departmentID = d.departmentID
full join employeeproject p on e.employeeID = p.employeeID where e.employeeID = emp;
-- record variable based on cursor definition
rec emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
LOOP
-- fetch the next row result from the cursor into the record vairable
FETCH emp_cursor INTO rec;
-- break out of the loop if there are no more results to fetch
EXIT WHEN emp_cursor%NOTFOUND;
-- first display information about the employee
dbms_output.put_line('- -');
dbms_output.put_line('- -');
dbms_output.put_line('Employee#' || rec.employeeid
|| ' Name:' || TRIM(rec.firstname) || ' ' || TRIM(rec.lastname)
|| ' Dept: ');
dbms_output.put_line('_________________________________________________________');
dbms_output.put_line('- -');
dbms_output.put_line('- - Title: ' || rec.title
|| ' Salary: ' || to_char(rec.salary,'9,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(rec.billrate,'9,999.99'));
-- next call the stored procedure to show department information
END LOOP;
CLOSE emp_cursor;
END;
/