sql raise_salary 程序
sql raise_salary procedure
我正在尝试制作一个 pl/sql 程序,它将经理的薪水从 table 提高,如果薪水大于 3000,我必须将其设置为 3000,但是我似乎无法做到这一点。我必须使用 o 过程,然后从匿名块中调用它。
我认为基本的update
是:
UPDATE emp
SET sal = (case when curr_sal + amount > 3000 then 3000
else curr_sal + amount
end)
WHERE job = 'MANAGER' ;
我不确定这如何适合您的程序,这似乎过于复杂。
在匿名块中,您正在为每个经理调用该过程。在此过程中,您将每位经理的工资提高 500。到区块退出时,您的经理将获得相当可观的加薪!
第一步是决定是否要在块中或过程中执行每个管理器循环。第二步是如果你想在经理的收入 > 3000 时引发异常,那么你必须检查经理的收入是否 > 3000。你检查 NULL,仅此而已。不,异常处理程序中的检查不算数。工资必须为 NULL 才能到达那里。
在这个例子中,我选择了执行程序中的所有循环。它只需要知道哪种工作类型获得加薪以及加薪金额。
CREATE OR REPLACE PROCEDURE Raise_Sal( Target_Job emp.JOB%TYPE, Amount NUMBER ) AS
Max_Sal Constant Number := 3000; -- Could also be passed in
Sal_Null Exception;
Sal_Too_Big Exception;
pragma exception_init( Sal_Null, -20101 );
pragma exception_init( Sal_Too_Big, -20102 );
CURSOR C1 IS
SELECT ID, Sal
FROM Emp
WHERE JOB = Target_Job
FOR UPDATE OF Sal; -- NOWAIT is redundant for cursors
BEGIN
FOR Emp IN C1 Loop BEGIN
IF Emp.Sal IS NULL THEN
Raise_Application_Error( -20101, 'Salary is missing' );
Elsif Emp.Sal > Max_Sal THEN
Raise Sal_Too_High;
Else
UPDATE Emp SET Sal = Curr_Sal + Amount WHERE CURRENT OF C1;
End If;
END;
Exception
WHEN Sal_Too_Big THEN
UPDATE Emp SET Sal = Max_Sal WHERE CURRENT OF C1;
WHEN Others THEN
Raise;
END loop;
END Raise_Sal;
/
DECLARE
V_Amount Constant Number := 500;
BEGIN
raise_sal( 'MANAGER', V_Amount );
end;
/
这不是生产质量代码。一方面,我将传递最高薪水金额,以便该过程可用于 "SalesClerk" 或 "VicePresident" 或 "SQLDeveloper" 或您有什么。我确定每个都有不同的最大值。不过你好像只对学技术感兴趣,就举个例子吧。
此外,Gordon 的回答指出了一个您可能仍然遗漏的问题。在 提高薪水之前,您正在检查薪水是否大于最大值。如果更新后它最终大于最大值怎么办?
我正在尝试制作一个 pl/sql 程序,它将经理的薪水从 table 提高,如果薪水大于 3000,我必须将其设置为 3000,但是我似乎无法做到这一点。我必须使用 o 过程,然后从匿名块中调用它。
我认为基本的update
是:
UPDATE emp
SET sal = (case when curr_sal + amount > 3000 then 3000
else curr_sal + amount
end)
WHERE job = 'MANAGER' ;
我不确定这如何适合您的程序,这似乎过于复杂。
在匿名块中,您正在为每个经理调用该过程。在此过程中,您将每位经理的工资提高 500。到区块退出时,您的经理将获得相当可观的加薪!
第一步是决定是否要在块中或过程中执行每个管理器循环。第二步是如果你想在经理的收入 > 3000 时引发异常,那么你必须检查经理的收入是否 > 3000。你检查 NULL,仅此而已。不,异常处理程序中的检查不算数。工资必须为 NULL 才能到达那里。
在这个例子中,我选择了执行程序中的所有循环。它只需要知道哪种工作类型获得加薪以及加薪金额。
CREATE OR REPLACE PROCEDURE Raise_Sal( Target_Job emp.JOB%TYPE, Amount NUMBER ) AS
Max_Sal Constant Number := 3000; -- Could also be passed in
Sal_Null Exception;
Sal_Too_Big Exception;
pragma exception_init( Sal_Null, -20101 );
pragma exception_init( Sal_Too_Big, -20102 );
CURSOR C1 IS
SELECT ID, Sal
FROM Emp
WHERE JOB = Target_Job
FOR UPDATE OF Sal; -- NOWAIT is redundant for cursors
BEGIN
FOR Emp IN C1 Loop BEGIN
IF Emp.Sal IS NULL THEN
Raise_Application_Error( -20101, 'Salary is missing' );
Elsif Emp.Sal > Max_Sal THEN
Raise Sal_Too_High;
Else
UPDATE Emp SET Sal = Curr_Sal + Amount WHERE CURRENT OF C1;
End If;
END;
Exception
WHEN Sal_Too_Big THEN
UPDATE Emp SET Sal = Max_Sal WHERE CURRENT OF C1;
WHEN Others THEN
Raise;
END loop;
END Raise_Sal;
/
DECLARE
V_Amount Constant Number := 500;
BEGIN
raise_sal( 'MANAGER', V_Amount );
end;
/
这不是生产质量代码。一方面,我将传递最高薪水金额,以便该过程可用于 "SalesClerk" 或 "VicePresident" 或 "SQLDeveloper" 或您有什么。我确定每个都有不同的最大值。不过你好像只对学技术感兴趣,就举个例子吧。
此外,Gordon 的回答指出了一个您可能仍然遗漏的问题。在 提高薪水之前,您正在检查薪水是否大于最大值。如果更新后它最终大于最大值怎么办?