|
|
|
Re: oracle pl/sql procedure [message #612108 is a reply to message #612088] |
Sat, 12 April 2014 02:42 |
John Watson
Messages: 8931 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
Please get into the habit posting exactly what you see, using copy/paste and code tags. Like this:orclz> conn hr/hr
Connected.
orclz> create or replace procedure upd_man(dep_id employees.department_id%type)
2 as
3 emp employees_employee_id%type;
4 begin
5 select employee_id into emp from employees
6 where department_id = dep_id
7 and
8 salary = (select max(salary) from employees where department_id = dep_id);
9 update departments set manager_id = emp where department_id = dep_id;
10 end;
11 /
Warning: Procedure created with compilation errors.
orclz> sho err
Errors for PROCEDURE UPD_MAN:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/5 PL/SQL: Item ignored
3/5 PLS-00201: identifier 'EMPLOYEES_EMPLOYEE_ID' must be declared
5/1 PL/SQL: SQL Statement ignored
5/25 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
5/29 PL/SQL: ORA-00904: : invalid identifier
9/1 PL/SQL: SQL Statement ignored
9/37 PL/SQL: ORA-00904: "EMP": invalid identifier
9/37 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
orclz> Fix your typo on line 3, and it compiles. Is this a college homework assignment? If so, I would write it a function, not procedure, and return the new manager employee_id. THat might get higher marks.
|
|
|
|
|
|
|
Re: oracle pl/sql procedure [message #612655 is a reply to message #612643] |
Wed, 23 April 2014 02:44 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
msol25 wrote on Wed, 23 April 2014 08:01hi Vamshi,
Please use COMMIT after update statement otherwise you can't see the updated result for departments table.
That's not good advice. Stored procedures should not contain commit. The top level program that calls the procedure should determine when a commit is issued. If a commit is present then the procedure can't form part of a larger transaction.
|
|
|
Re: oracle pl/sql procedure [message #612656 is a reply to message #612655] |
Wed, 23 April 2014 02:46 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
The procedure can be written as a single update statement, no need for a separate select.
But you need to consider what happens if two employees have the max salary.
|
|
|
|
|
|
|
|
|
|
|
Re: oracle pl/sql procedure [message #612682 is a reply to message #612681] |
Wed, 23 April 2014 05:16 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
There's two cases in which the select will throw that error:
1) The dept doesn't exist - in which case the update isn't going to update anything.
2) The dept doesn't have any employees - in which case the dept manager_id is going to get updated to null, which is arguably the correct action.
Moving the exception handler to end will have no effect in case 1 (ok it won't even try to run the update, but the resulting effect on data (none) will be the same). It'll make a difference to case 2.
Personally in case 1 I'd want it to throw an error back to say the dept doesn't exist. I'd ditch the exception handler as it doesn't allow you to distinguish between the two and do this instead:
BEGIN
UPDATE departments
SET manager_id = (SELECT employee_id
FROM employees
WHERE department_id = dep_id
AND salary = (SELECT MAX(salary)
FROM employees
WHERE department_id = dep_id
)
)
WHERE department_id = dep_id;
IF sql%rowcount = 0 THEN
raise_application_error(-20001, 'Dept '||dep_id||' does not exist.');
END IF;
END;
|
|
|
|
|
|
Re: oracle pl/sql procedure [message #612698 is a reply to message #612694] |
Wed, 23 April 2014 06:42 |
|
Michel Cadot
Messages: 68647 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
It is your specification, model and data that define where, when and how you need to handle exceptions.
I remember Steven Feuerstein's article containing something closed to this:
Llewellyn suggests that we group all exceptions into three categories: deliberate, unfortunate, and unexpected.
In deliberate exceptions, the code deliberately raises an exception as part of its normal behavior. UTL_FILE.GET_LINE, which raises NO_DATA_FOUND when you read past the end of file, is a perfect example of a program that raises a deliberate exception.
Unfortunate exceptions are those where an exception has been raised that may not constitute an error in your application logic. It might, for example, simply be a different data condition. NO_DATA_FOUND, raised by a SELECT INTO, is an unfortunate exception.
A "hard error" that was raised, that you did not expect, and that may indicate a serious problem in your application is an unexpected error. TOO_MANY_ROWS is a classic unexpected error; it indicates that you have duplicate values for a primary key or unique index.
Before you start building your next application, decide on a strategy for handling exceptions of these three types. Then, when you run into a particular exception, figure out which category it falls into and take the appropriate action. Here are the guidelines I follow for these three exception types:
Deliberate. Redesign your program so that you can avoid placing application logic in the exception section. The code you'll need to write to work around a deliberate exception will, of course, vary for each exception (and the circumstances that raise it).
Unexpected. The guideline for handling unexpected exceptions is straightforward. In general, you should log the error, along with any application-specific information that will help you understand what caused it. And then you should reraise the error to stop the outer block from continuing to execute. Avoid hard-coding INSERT statements into your log table, and instead rely on a single, reusable, and generic error management package that will take care of all the administrative details for you.
Unfortunate. Now let's discuss what to do about unfortunate exceptions such as NO_DATA_FOUND. As with the deliberate exception, the general rule is to avoid having to put application logic into the exception section. The way to do that with an unfortunate exception is to make it possible for the programmer to choose whether an exception should be raised.
I don't completely agree with all the points but this is a good guideline.
|
|
|
|
Re: oracle pl/sql procedure [message #612703 is a reply to message #612699] |
Wed, 23 April 2014 07:44 |
|
Michel Cadot
Messages: 68647 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
The type of exception does definitively not depend on us (the developer) but on the specification. The project manager/designer defines the type of the exception by defining/designing (or not) if and what should be done with that exception.
If the designer (who may be wrong and we can (have to) point/ask him about it) does not mention this exception then it is an unexpected error otherwise it is an unfortunate one. And maybe the designer chooses to not handle this exception here (and treat it as an unexpected one for this procedure) but to handle it in the caller procedure (and this is one of the reason why "commit" or "rollback" should not be part of the procedure without speaking about bigger transaction cookiemonster already mentioned).
|
|
|