CREATE OR REPLACE procedure verify_employee IS
Emp_name trkemployee.name#%TYPE,
Emp_ID trkemployee.E#%TYPE,
CURSOR c1;
IS
select e.e#, e.name from trkemployee e where e# IN (select e# from trkdriver intersect select e# from trkmechanic);
IN
(select e# from trkdriver intersect select e# from trkmechanic);
BEGIN
OPEN c1();
LOOP
END LOOP;
close c1;
END;
/
以上是我的PL / SQL代码..我想要实现的是列出所有以司机身份工作的员工。机械师同时..
我在终端单独执行sql语句,输出如下:
SQL> select e.e#, e.name from trkemployee e where e# IN (select e# from trkdriver intersect select e# from trkmechanic);
E# NAME
---------- --------------------------------------------------
14 Andrew R. Smith
但我想在PL / SQL中执行此操作并执行DMBS_OUTPUT.PUT(结果);
我知道检查多条记录,我需要使用光标。假设将来会有超过1行返回,我应该如何更改我的pl / sql,当我加载程序时,终端说有编译错误。
以下是我的3张桌子..
SQL> desc trkdriver;
Name Null? Type
----------------------------------------- -------- ----------------------------
E# NOT NULL NUMBER(12)
L# NOT NULL NUMBER(8)
STATUS NOT NULL VARCHAR2(10)
SQL> desc trkmechanic;
Name Null? Type
----------------------------------------- -------- ----------------------------
E# NOT NULL NUMBER(12)
L# NOT NULL NUMBER(8)
STATUS NOT NULL VARCHAR2(10)
EXPERIENCE NOT NULL VARCHAR2(10)
SQL> desc trkemployee;
Name Null? Type
----------------------------------------- -------- ----------------------------
E# NOT NULL NUMBER(12)
NAME NOT NULL VARCHAR2(50)
DOB DATE
ADDRESS NOT NULL VARCHAR2(300)
HIREDATE NOT NULL DATE
答案 0 :(得分:2)
您的代码中有两次IN (select ....
部分。我认为这就是编译错误的意义所在。
我还认为2 in
会更快,因为Oracle可能会更好地使用这些索引:
select
e.e#,
e.name
from
trkemployee e
where
e# IN (select e# from trkdriver)
and e# in (select e# from trkmechanic);
提示:如果使用这样的游标,则需要添加大量异常处理,以防止游标在出现错误时保持打开状态。 for
循环使游标循环更容易,更安全:
for r in C loop
DBMS_OUTPUT.PUT_LINE(r.e#);
end loop;
另外,我可以想象e#
是一个可能导致PL / SQL出现问题的字段名称。我不确定,但如果你遇到编译错误,可能就是这种情况。我宁愿选择像'EmployeeNr`这样更常见的名字。
[编辑]
您的代码有几个错误。首先,;
之后的cursor C1
不应该存在。此外,循环中没有代码,这在PL / SQL中是不允许的。如果您需要对其进行测试,但尚未编写代码,则可以键入null;
作为“无效的代码”。像:
loop
null;
end loop;
您的整个代码可能如下所示。这个实际上是编译的,应该让你用你可能需要的其他东西完成它。
CREATE OR REPLACE PROCEDURE verify_employee IS
CURSOR C1 IS
SELECT
E.E#,
E.name
FROM
trkemployee E
WHERE
E# IN (SELECT E# FROM trkdriver)
AND E# IN (SELECT E# FROM trkmechanic);
BEGIN
-- R becomes an alias for each row. You can access the fields
-- of the rows inside the loop
FOR R IN C1 LOOP
-- Output each Emplyee number.
DBMS_OUTPUT.PUT_LINE(R.E# || ', ' || r.name);
END LOOP;
END;