Sql 创建存储过程时出现的问题
我正在尝试创建一个存储过程,如下所示:Sql 创建存储过程时出现的问题,sql,oracle,stored-procedures,cursor,declare,Sql,Oracle,Stored Procedures,Cursor,Declare,我正在尝试创建一个存储过程,如下所示: 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, salar
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,'$999,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(billrate,'$999,999.99'));
-- next call the stored procedure to show department information
END;
END;
/
但它编译时会出错。当我显示错误时,它告诉我必须声明e.employeeID
,e.title
和billrate
,但它们是原始查询。我做错了什么?我是否误解了申报它们意味着什么
这些都是被查询的表中存在的列,并在SQL获取结果时运行查询。您正在打开光标,但没有将其提取到任何内容中—一系列标量变量或记录类型—通常在循环中完成。然后,当您在循环中时,您引用的是变量/记录,而不是游标查询中使用的表-这超出了游标声明的范围 在本例中,有一个稍微简单的隐式光标循环,您可能会发现它更容易:
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,'$999,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(rec.billrate,'$999,999.99'));
-- next call the stored procedure to show department information
END LOOP;
END;
/
请注意,循环中对列的所有引用都是rec.
——它们是从循环中这一次的记录中获取的,而不是直接从基础表中获取的
您还有一个嵌套块,它不会造成任何伤害,但没有任何用处,所以我将其删除
如果您特别希望使用显式的open-fetch-close游标处理,它将如下所示:
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,'$999,999,999.99'));
dbms_output.put_line('- - Billing Rate: ' || to_char(rec.billrate,'$999,999.99'));
-- next call the stored procedure to show department information
END LOOP;
CLOSE emp_cursor;
END;
/
请标记您正在使用的特定SQL产品-SQL Server、Oracle、MySQL、PostgreSQL等。我正在使用Oracle。我现在将添加到标记中,格式有点难理解,但是您需要某种循环构造,并通过游标获取循环。请记住,在SQL数据库中,游标通常是最后的手段。通常最好使用基于集合的方法。