我想知道我是否正确地走这条路。
编译器给出的主要问题是这一行
IF SELECT 1 FROM works WHERE an_employee.employee_name IN works.manager_name THEN
错误(17,8):PLS-00103:当遇到以下情况之一时遇到符号“SELECT”:( - + case mod new not null继续avg计数当前存在max min before sql stddev sum variance execute forall merge时间戳间隔日期管道
我想要做的是使用一个光标来检测第一个条件,如果它们在该城市的公司中工作。在我的表中的这个例子中,它将给出2个公司,大约7或8个雇员。然后我把它放到我的变量an_employee中。我想要做的是然后使用该员工来查看他们是否是来自我的管理表的管理员,其中有多行/元组。不是每个人都是经理。如何查看我的employee_name
是否在manager_name
列表中?
我是否为管理器声明了另一个游标,然后执行嵌套循环?
我可以使用现有游标并执行选择查询以从表manages.manager_name
获取管理器列表吗?如果我这样做,我怎么能在IF语句中使用它作为我的条件?
-- Give all employees that work in a company located in city X
-- a Y percent raise if they are managers and
-- a Z percent raise if they are not a manager
-- X, Y, and Z will be the three parameters for the stored procedure.
-- Build / compile a stored procedure
CREATE OR REPLACE PROCEDURE give_raises(X company.city%TYPE, Y NUMBER, Z NUMBER) IS
an_employee works.employee_name%TYPE;
-- cursor declaration
cursor Cursor1 IS
select works.employee_name
from works
where works.company_name IN (select company_name from company where city = 'London');
BEGIN
SELECT manager_name INTO managers FROM manages;
OPEN Cursor1;
LOOP
FETCH Cursor1 INTO an_employee;
EXIT WHEN Cursor1%NOTFOUND;
-- is a manager give Y percent raise
IF SELECT 1 FROM works WHERE an_employee.employee_name IN works.manager_name THEN
update works
set works.salary = works.salary + (works.salary * Y)
where works.employee_name = an_employee.employee_name;
ELSE -- is not a manager give Z percent raise
update works
set works.salary = works.salary + (works.salary * Z)
where works.employee_name = an_employee.employee_name;
END IF;
END LOOP;
CLOSE Cursor1;
END;
你也应该知道。我使用的是Oracle,Oracle Sql Developer和IDE。
答案 0 :(得分:2)
如果在逻辑条件下工作并且不支持条件中的Select语句。
你需要像这样重做你的代码
SELECT count(*)
INTO v_value
FROM works
WHERE an_employee.employee_name = works.manager_name;
IF v_value = 1 THEN
--do some stuff
ELSE
--do some other stuff
END IF;
答案 1 :(得分:1)
如果我正确地理解了您的问题,那么您正在尝试确定员工是否是经理,而不是根据该工资进行计算。希望在片段下方有所帮助。
CREATE OR REPLACE PROCEDURE give_raises(
X company.city%TYPE,
Y NUMBER,
Z NUMBER)
AS
managers PLS_INTEGER;
BEGIN
FOR an_employee IN
(SELECT works.employee_name
FROM works
WHERE works.company_name IN
(SELECT company_name FROM company WHERE city = 'London'
)
)
LOOP
SELECT COUNT(1)
INTO managers
FROM manages m
WHERE m.manager_name = an_employee.employee_name;
-- is a manager give Y percent raise
IF managers <> 0 THEN
UPDATE works
SET works.salary = works.salary + (works.salary * Y)
WHERE works.employee_name = an_employee.employee_name;
ELSE -- is not a manager give Z percent raise
UPDATE works
SET works.salary = works.salary + (works.salary * Z)
WHERE works.employee_name = an_employee.employee_name;
END IF;
END LOOP;
END;
答案 2 :(得分:0)
你的问题基本上与例如在昨天发布的a question中。 PL / SQL if
statement期望布尔表达式不是query result set。
一个好的做法是将查询封装到返回合适值的函数中。
示例:强>
SQL> !cat so53.sql
declare
function is_foo_1(p_foo in varchar2) return boolean is
v_exists number;
begin
select count(*)
into v_exists
from dual
where dummy = p_foo
and rownum = 1
;
return
case v_exists
when 1 then true
else false
end;
end;
function is_foo_2(p_foo in varchar2) return number is
v_exists number;
begin
select count(*)
into v_exists
from dual
where dummy = p_foo
and rownum = 1
;
return v_exists;
end;
begin
-- is_foo_1 returns a boolean value than is a valid boolean expression
if is_foo_1('X')
then
dbms_output.put_line('1:X');
end if;
if not is_foo_1('Y')
then
dbms_output.put_line('1:not Y');
end if;
-- is_foo_2 returns a number that is not a valid boolean expression (PL/SQL
-- doesn't have implicit type conversions) so one have to use an operator
-- (in this example `=`-operator) to construct an explicit boolean
-- expression
if is_foo_2('X') = 1
then
dbms_output.put_line('2:X');
end if;
if is_foo_2('Y') = 0
then
dbms_output.put_line('2:not Y');
end if;
end;
/
示例运行:
SQL> @so53.sql
1:X
1:not Y
2:X
2:not Y
PL/SQL procedure successfully completed.
SQL>