Raising no_data_found
Executing anonymous block (see below) does not report ORA-01403 to the host environment.
I am using NCOCI in Delphi, but I had the same problem with ADO.
declare
a varchar2 (100);
begin
select dummy
into a
from dual
where 1= 0;
end;
The following code works as expected:
declare
a varchar2 (100);
begin
select dummy
into a
from dual
where 1= 0;
exception
when no_data_found then
raise_application_error (-20000, SQLERRM);
end;
Thanks for any suggestion, Dab
An OCI_NO_DATA return is different than an OCI_ERROR. In fact there are several values that an OCI function can return and you should be prepared to handle them:
OCI_SUCCESS
The function completed successfully.
OCI_SUCCESS_WITH_INFO
The function completed successfully; a call to OCIErrorGet() returns additional diagnostic information. This may include warnings.
OCI_NO_DATA
The function completed, and there is no further data.
OCI_ERROR
The function failed; a call to OCIErrorGet() returns additional information.
OCI_INVALID_HANDLE
An invalid handle was passed as a parameter or a user callback is passed an invalid handle or invalid context. No further diagnostics are available.
OCI_NEED_DATA
The application must provide runtime data.
OCI_STILL_EXECUTING
The service context was established in nonblocking mode, and the current operation could not be completed immediately. The operation must be called again to complete. OCIErrorGet() returns ORA-03123 as the error code.
OCI_CONTINUE
This code is returned only from a callback function. It indicates that the callback function wants the OCI library to resume its normal processing.
Similar Messages
-
Win_Api_Shell.SendKeys() raised NO_DATA_FOUND
When I used the d2kwutil Win_Api_Shell.SendKeys() function to simultate a keybord,it always raised the error NO_DATA_FOUND,my code is as follows,
Begin
Go_item('CUXHR.IT_PASTE');
win_api_shell.sendkeys(get_window_property(FORMS_MDI_WINDOW,window_handle),'^V',TRUE);
END;
A strange thing is that,the result of " get_window_property(FORMS_MDI_WINDOW,window_handle) " is 0,which one can help me?Many thanks!Please read this:
http://blogs.oracle.com/shay/entry/10_commandments_for_the_otn_fo
Without details it will be very difficult to offer accurate feedback. Also, I will assume you are using an old and obsolete version. You might want to start considering a more modern and currently supported version. Keep in mind that if/when you do so, code like you are attempting to write will not work since modern Forms versions are web based and some functions such as the one you are attempting to use are not supported. -
How to continue the loop after getting the exception NO_DATA_FOUND
I am inserting 2000 employees attendance data into table through procedure by validating the shifts assigned some times if employee doesn't have shift it raising NO_DATA_FOUND exception, so now I am inserting the details of the employee into one table as a log.
my question is if 2000 transactions are inserting if exception raised at 1000 record as "NO_DATA_FOUND" is it remaining records will insert into the table? or it will exit from the procedure and stops remaining 1000 transactions?, please advice if any other way to continue the remaining transactions
oracle version: 11 G R2, OS: Windows 2008 R2Do your select statement in a seperate begin...end block, you can cath the excption in the block and do your logging there.
Something like this
--just an example from scott/tiger
Declare
CNT number := 7851 ;
vname varchar2(25);
ins_flag boolean ;
BEGIN
while cnt <= 7935 and cnt >=7850
LOOP
Begin
select ename into vname from emp where empno=cnt ;
ins_flag := true;
exception
when no_data_found then
-- dbms_output.put_line('no data');
ins_flag := false;
end;
if ins_flag then
--do insert here
dbms_output.put_line('do your insert here');
else
dbms_output.put_line('no insert');
end if;
cnt := cnt+1 ;
END LOOP;
end; -
Oracle ODBC driver: NO_DATA_FOUND blocked
Hello,
I found that NO_DATA_FOUND exceptions thrown inside stored_procedures are sometimes not propagated to ODBC errors. This happens with the Oracle ODBC driver, but not with the MS one (the MS one does propagate the exception/error).
Test-Procedure:
Create or Replace Procedure throws_exception(p1 in number)
IS
BEGIN
raise NO_DATA_FOUND;
END;
If I call this stored_procedure the ODBC call will return with no errors:
Begin THROWS_EXCEPTION(1); end;
Versions:
- oracle server: 10.02
- oracle driver: 10.02
- mirosoft driver: 2.575
Is this a known bug in the oracle ODBC driver, or is this a bad setup, etc?
If this is a bug, it is a very inconvenient one, because basically it means your stored_procedure can fail completely silentely. It implies that the use of the oracle driver is completely unreliable.
I have copied this text from another user, he got no answer to this :-(
Thanks
Joachim Paulus
Message was edited by:
user517727
Message was edited by:
user517727Any answers? Same problem on 10.2.0.2.0
-
Select and function with no_data_found
Hi,
I came across this today (I remembered reading about it somewhere).
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
SQL> create function rahul_f return varchar2 as
2 begin
3 raise no_data_found;
4 end rahul_f;
5 /
Function created.
SQL> select rahul_f from dual;
RAHUL_F
SQL> declare
2 i varchar2(1);
3 begin
4 i := rahul_f;
5 end;
6 /
declare
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at "XX.RAHUL_F", line 3
ORA-06512: at line 4
SQL>
So, I know this has something to do with 'no_data_found' mentioned here:
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/errors.htm#LNPLS00703
'Because this exception is used internally by some SQL functions to signal completion, you should not rely on this exception being propagated if you raise it within a function that is called as part of a query.'
Anybody have any link on explaining this part more? I looked around but, couldn't find any discussions on this.I had same experience few days back.
First I dont think you need the funtion to call the exception.
You can directly implement your code in the EXCEPTION block, if theres a no_data_found excpetion.
This is my code..
PROCEDURE modify_req_det(
detail_id_in IN req_details.detail_id%TYPE,
type_id_in IN req_details.req_type_id%TYPE,
value_in IN VARCHAR2,
parent_in IN req_details.parent%TYPE,
sortorder_in IN req_details.sort_order%TYPE,
groupid_in IN req_details.group_id%TYPE,
errormsg OUT NOCOPY VARCHAR2) AS
BEGIN
SELECT DISTINCT lookup, col_name
INTO v_lookup, v_colname
FROM req_type t, req_details d
WHERE parent = parent_in
AND t.req_type_id = d.req_type_id;
EXCEPTION
WHEN no_data_found THEN
UPDATE req_details SET
req_type_id = type_id_in,
value_id = v_valueId,
parent = parent_in,
sort_order = sortorder_in,
group_id = groupid_in
WHERE detail_id = detail_id_in;
END modify_req_det; -
PL/SQL Using SQL%NOTFOUND to raise a user defined exception in a function
I have written the following function for finding the number of items in stock in the item table.
CREATE OR REPLACE function getAmount (ItemID IN NUMBER)
RETURN NUMBER
AS
invalid_id EXCEPTION;
returnedQty number;
BEGIN
Select qty
Into returnedQty
From item
Where itemNo = ItemID;
RETURN (returnedQty);
IF SQL%NOTFOUND THEN
RAISE invalid_id;
END IF;
COMMIT;
Exception
WHEN invalid_id THEN
DBMS_OUTPUT.PUT_LINE('Invalid ID entered');
END getAmount;
The function compiles successfully, although there is a problem that Oracle is not handling my user-defined exception invalid_id
If I use the following for a valid itemID:
DECLARE
return_value number;
BEGIN
return_value := getAmount(1);
DBMS_OUTPUT.PUT_LINE (return_value);
END;
then the function returns the quantity of items in stock correctly.
However, if I enter an incorrect itemID, say 20
DECLARE
return_value number;
BEGIN
return_value := getAmount(20);
DBMS_OUTPUT.PUT_LINE (return_value);
END;
The invalid_id exception is not raised, and the Oracle errors says: no_data_found and the function has not returned a value. If I add a no_data_found exception, this works perfectly, but for this assignment I must write my own user-defined error.
Any help would be very much appreciated!
Thank you.What you're trying to do, is to use an implicit cursor. Implicit cursors will raise no_data_found and too_many_rows in case of an error. Explicit cursors will not.
Also, you have a small coding error ... a little rewrite and your code will do as you want to:
CREATE OR REPLACE function getAmount (ItemID IN NUMBER)
RETURN NUMBER
AS
invalid_id EXCEPTION;
returnedQty number;
cursor citem is
Select qty
From item
Where itemNo = ItemID;
fnd boolean;
BEGIN
open citem;
fetch citem Into returnedQty;
fnd := citem%found;
close citem;
if fnd then
RETURN (returnedQty);
else
RAISE invalid_id;
END IF;
/* Do not catch your own exception or the calling code will not receive it.
Exception
WHEN invalid_id THEN
DBMS_OUTPUT.PUT_LINE('Invalid ID entered');
END getAmount;
Your problem is, you're not using a package. This means, that the calling code has no way of catching this user-defined exeption. The correct way is to define a package, define the userdefined exception in the package and refer to it in your code:
create or replace package amt
is
invalid_id EXCEPTION;
function getAmount (ItemID IN NUMBER)
RETURN NUMBER;
end;
create or replace package body amt
is
function getAmount (ItemID IN NUMBER)
RETURN NUMBER
AS
returnedQty number;
cursor citem is
Select qty
From item
Where itemNo = ItemID;
fnd boolean;
BEGIN
open citem;
fetch citem Into returnedQty;
fnd := citem%found;
close citem;
if fnd then
RETURN (returnedQty);
else
RAISE invalid_id;
END IF;
end;
end; -- end package
To do a simple test, you'll do:
declare
a number;
begin
a := amt.getAmount(123);
dbms_output.put_line('The result is '||a);
exception
when amt.invalid_id then
dbms_output.put_line('ID not found');
end;
Other ways is to raise the exception in your no_data_found block.
But I'm REALLY puzzled if there's really someone out there who prefers a user-defined exception instead of the clearly defined NO_DATA_FOUND exception.
I can't be sure of course, but are you sure what they mean is they don't want ANY exception? That's a pretty common requirement.
In general - explicit cursors are a bit faster because Oracle does not have to do a second fetch to determine TOO_MANY_ROWS. And it's not too much additional writing. Explicit cursors will never raise exceptions - unless you use dynamic sql and your SQL is invalid.
Good luck -
I have some PL/SQL code that looks like this:
PROCEDURE my_proc(start_date DATE, end_date DATE)
AS
BEGIN
FOR rec IN (SELECT DISTINCT column1
FROM my_table
WHERE test_date_and_time BETWEEN start_date AND end_date;)
LOOP
END LOOP;
END; The procedure is called in the following way:
DECLARE
sdate DATE;
edate DATE;
BEGIN
sdate := to_date('1-jan-2003');
edate := to_date('10-jan-2003');
my_proc(sdate, edate);
END;I get an ORA-1403 exception (No Data Found) at the select statement in the my_proc procedure. But if I run the select statement directly with SQL, several records are found.
Does anybody know what I am missing.Hi,
DBelt wrote:
I have some PL/SQL code that looks like this:
PROCEDURE my_proc(start_date DATE, end_date DATE)
AS
BEGIN
FOR rec IN (SELECT DISTINCT column1
FROM my_table
WHERE test_date_and_time BETWEEN start_date AND end_date;)
LOOP
END LOOP;
END; The procedure is called in the following way:
DECLARE
sdate DATE;
edate DATE;
BEGIN
sdate := to_date('1-jan-2003');
edate := to_date('10-jan-2003');
my_proc(sdate, edate);
END;I get an ORA-1403 exception (No Data Found) at the select statement in the my_proc procedure. But if I run the select statement directly with SQL, several records are found.
Does anybody know what I am missing.Are you sure the code you posted is what you're actually running? The semicolon at the end of the query:
... WHERE test_date_and_time BETWEEN start_date AND end_date;)is a mistake, but it wouldn't cause ORA-01403.
Also,
FOR rec IN (query)
LOOP
END LOOP;doesn't raise NO_DATA_FOUND. If the query doesn't return any records, then the loop is simply not executed even once.
If you'd like help, then post your actual code, or a simplified version that gets the same error, along with whatever CREATE TABLE and INSERT statements are needed to run it. -
PL/SQL 101 : Exception Handling
Frequently I see questions and issues around the use of Exception/Error Handling in PL/SQL. More often than not the issue comes from the questioners misunderstanding about how PL/SQL is constructed and executed, so I thought I'd write a small article covering the key concepts to give a clear picture of how it all hangs together. (Note: the examples are just showing examples of the exception handling structure, and should not be taken as truly valid code for ways of handling things)
Exception Handling
Contents
1. Understanding Execution Blocks (part 1)
2. Execution of the Execution Block
3. Exceptions
4. Understanding Execution Blocks (part 2)
5. How to continue exection of statements after an exception
6. User defined exceptions
7. Line number of exception
8. Exceptions within code within the exception block
1. Understanding Execution Blocks (part 1)
The first thing that one needs to understand is almost taking us back to the basics of PL/SQL... how a PL/SQL execution block is constructed.
Essentially an execution block is made of 3 sections...
+---------------------------+
| Declaration Section |
+---------------------------+
| Statements Section |
+---------------------------+
| Exception Section |
+---------------------------+
The Declaration section is the part defined between the PROCEDURE/FUNCTION header or the DECLARE keyword (for anonymous blocks) and the BEGIN keyword. (Optional section)
The Statements section is where your code goes and lies between the BEGIN keyword and the EXCEPTION keyword (or END keyword if there is no EXCEPTION section). (Mandatory section)
The Exception section is where any exception handling goes and lies between the EXCEPTION keyword at the END keyword. (Optional section)
Example of an anonymous block...
DECLARE
.. declarative statements go here ..
BEGIN
.. code statements go here ..
EXCEPTION
.. exception handlers go here ..
END;
Example of a procedure/function block...
[CREATE OR REPLACE] (PROCEDURE|FUNCTION) <proc or fn name> [(<parameters>)] [RETURN <datatype>] (IS|AS)
.. declarative statements go here ..
BEGIN
.. code statements go here ..
EXCEPTION
.. exception handlers go here ..
END;
(Note: The same can also be done for packages, but let's keep it simple)
2. Execution of the Execution Block
This may seem a simple concept, but it's surprising how many people have issues showing they haven't grasped it. When an Execution block is entered, the declaration section is processed, creating a scope of variables, types , cursors, etc. to be visible to the execution block and then execution enters into the Statements section. Each statment in the statements section is executed in turn and when the execution completes the last statment the execution block is exited back to whatever called it.
3. Exceptions
Exceptions generally happen during the execution of statements in the Statements section. When an exception happens the execution of statements jumps immediately into the exception section. In this section we can specify what exceptions we wish to 'capture' or 'trap' and do one of the two following things...
(Note: The exception section still has access to all the declared items in the declaration section)
3.i) Handle the exception
We do this when we recognise what the exception is (most likely it's something we expect to happen) and we have a means of dealing with it so that our application can continue on.
Example...
(without the exception handler the exception is passed back to the calling code, in this case SQL*Plus)
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_name VARCHAR2(20);
3 begin
4 select ename
5 into v_name
6 from emp
7 where empno = &empno;
8 dbms_output.put_line(v_name);
9* end;
SQL> /
Enter value for empno: 123
old 7: where empno = &empno;
new 7: where empno = 123;
declare
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 4
(with an exception handler, we capture the exception, handle it how we want to, and the calling code is happy that there is no error for it to report)
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_name VARCHAR2(20);
3 begin
4 select ename
5 into v_name
6 from emp
7 where empno = &empno;
8 dbms_output.put_line(v_name);
9 exception
10 when no_data_found then
11 dbms_output.put_line('There is no employee with this employee number.');
12* end;
SQL> /
Enter value for empno: 123
old 7: where empno = &empno;
new 7: where empno = 123;
There is no employee with this employee number.
PL/SQL procedure successfully completed.
3.ii) Raise the exception
We do this when:-
a) we recognise the exception, handle it but still want to let the calling code know that it happened
b) we recognise the exception, wish to log it happened and then let the calling code deal with it
c) we don't recognise the exception and we want the calling code to deal with it
Example of b)
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_name VARCHAR2(20);
3 v_empno NUMBER := &empno;
4 begin
5 select ename
6 into v_name
7 from emp
8 where empno = v_empno;
9 dbms_output.put_line(v_name);
10 EXCEPTION
11 WHEN no_data_found THEN
12 INSERT INTO sql_errors (txt)
13 VALUES ('Search for '||v_empno||' failed.');
14 COMMIT;
15 RAISE;
16* end;
SQL> /
Enter value for empno: 123
old 3: v_empno NUMBER := &empno;
new 3: v_empno NUMBER := 123;
declare
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 15
SQL> select * from sql_errors;
TXT
Search for 123 failed.
SQL>
Example of c)
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_name VARCHAR2(20);
3 v_empno NUMBER := &empno;
4 begin
5 select ename
6 into v_name
7 from emp
8 where empno = v_empno;
9 dbms_output.put_line(v_name);
10 EXCEPTION
11 WHEN no_data_found THEN
12 INSERT INTO sql_errors (txt)
13 VALUES ('Search for '||v_empno||' failed.');
14 COMMIT;
15 RAISE;
16 WHEN others THEN
17 RAISE;
18* end;
SQL> /
Enter value for empno: 'ABC'
old 3: v_empno NUMBER := &empno;
new 3: v_empno NUMBER := 'ABC';
declare
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 3
SQL> select * from sql_errors;
TXT
Search for 123 failed.
SQL>
As you can see from the sql_errors log table, no log was written so the WHEN others exception was the exception that raised the error to the calling code (SQL*Plus)
4. Understanding Execution Blocks (part 2)
Ok, so now we understand the very basics of an execution block and what happens when an exception happens. Let's take it a step further...
Execution blocks are not just a single simple block in most cases. Often, during our statements section we have a need to call some reusable code and we do that by calling a procedure or function. Effectively this nests the procedure or function's code as another execution block within the current statement section so, in terms of execution, we end up with something like...
+---------------------------------+
| Declaration Section |
+---------------------------------+
| Statements Section |
| . |
| +---------------------------+ |
| | Declaration Section | |
| +---------------------------+ |
| | Statements Section | |
| +---------------------------+ |
| | Exception Section | |
| +---------------------------+ |
| . |
+---------------------------------+
| Exception Section |
+---------------------------------+
Example... (Note: log_trace just writes some text to a table for tracing)
SQL> create or replace procedure a as
2 v_dummy NUMBER := log_trace('Procedure A''s Declaration Section');
3 begin
4 v_dummy := log_trace('Procedure A''s Statement Section');
5 v_dummy := 1/0; -- cause an exception
6 exception
7 when others then
8 v_dummy := log_trace('Procedure A''s Exception Section');
9 raise;
10 end;
11 /
Procedure created.
SQL> create or replace procedure b as
2 v_dummy NUMBER := log_trace('Procedure B''s Declaration Section');
3 begin
4 v_dummy := log_trace('Procedure B''s Statement Section');
5 a; -- HERE the execution passes to the declare/statement/exception sections of A
6 exception
7 when others then
8 v_dummy := log_trace('Procedure B''s Exception Section');
9 raise;
10 end;
11 /
Procedure created.
SQL> exec b;
BEGIN b; END;
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.B", line 9
ORA-06512: at line 1
SQL> select * from code_trace;
TXT
Procedure B's Declaration Section
Procedure B's Statement Section
Procedure A's Declaration Section
Procedure A's Statement Section
Procedure A's Exception Section
Procedure B's Exception Section
6 rows selected.
SQL>
Likewise, execution blocks can be nested deeper and deeper.
5. How to continue exection of statements after an exception
One of the common questions asked is how to return execution to the statement after the one that created the exception and continue on.
Well, firstly, you can only do this for statements you expect to raise an exception, such as when you want to check if there is no data found in a query.
If you consider what's been shown above you could put any statement you expect to cause an exception inside it's own procedure or function with it's own exception section to handle the exception without raising it back to the calling code. However, the nature of procedures and functions is really to provide a means of re-using code, so if it's a statement you only use once it seems a little silly to go creating individual procedures for these.
Instead, you nest execution blocks directly, to give the same result as shown in the diagram at the start of part 4 of this article.
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure b (p_empno IN VARCHAR2) as
2 v_dummy NUMBER := log_trace('Procedure B''s Declaration Section');
3 begin
4 v_dummy := log_trace('Procedure B''s Statement Section');
5 -- Here we start another execution block nested in the first one...
6 declare
7 v_dummy NUMBER := log_trace('Nested Block Declaration Section');
8 begin
9 v_dummy := log_trace('Nested Block Statement Section');
10 select empno
11 into v_dummy
12 from emp
13 where empno = p_empno; -- Note: the parameters and variables from
parent execution block are available to use!
14 exception
15 when no_data_found then
16 -- This is an exception we can handle so we don't raise it
17 v_dummy := log_trace('No employee was found');
18 v_dummy := log_trace('Nested Block Exception Section - Exception Handled');
19 when others then
20 -- Other exceptions we can't handle so we raise them
21 v_dummy := log_trace('Nested Block Exception Section - Exception Raised');
22 raise;
23 end;
24 -- ...Here endeth the nested execution block
25 -- As the nested block handled it's exception we come back to here...
26 v_dummy := log_trace('Procedure B''s Statement Section Continued');
27 exception
28 when others then
29 -- We'll only get to here if an unhandled exception was raised
30 -- either in the nested block or in procedure b's statement section
31 v_dummy := log_trace('Procedure B''s Exception Section');
32 raise;
33* end;
SQL> /
Procedure created.
SQL> exec b(123);
PL/SQL procedure successfully completed.
SQL> select * from code_trace;
TXT
Procedure B's Declaration Section
Procedure B's Statement Section
Nested Block Declaration Section
Nested Block Statement Section
No employee was found
Nested Block Exception Section - Exception Handled
Procedure B's Statement Section Continued
7 rows selected.
SQL> truncate table code_trace;
Table truncated.
SQL> exec b('ABC');
BEGIN b('ABC'); END;
ERROR at line 1:
ORA-01722: invalid number
ORA-06512: at "SCOTT.B", line 32
ORA-06512: at line 1
SQL> select * from code_trace;
TXT
Procedure B's Declaration Section
Procedure B's Statement Section
Nested Block Declaration Section
Nested Block Statement Section
Nested Block Exception Section - Exception Raised
Procedure B's Exception Section
6 rows selected.
SQL>
You can see from this that, very simply, the code that we expected may have an exception was able to either handle the exception and return to the outer execution block to continue execution, or if an unexpected exception occurred then it was able to be raised up to the outer exception section.
6. User defined exceptions
There are three sorts of 'User Defined' exceptions. There are logical situations (e.g. business logic) where, for example, certain criteria are not met to complete a task, and there are existing Oracle errors that you wish to give a name to in order to capture them in the exception section. The third is raising your own exception messages with our own exception numbers. Let's look at the first one...
Let's say I have tables which detail stock availablility and reorder levels...
SQL> select * from reorder_level;
ITEM_ID STOCK_LEVEL
1 20
2 20
3 10
4 2
5 2
SQL> select * from stock;
ITEM_ID ITEM_DESC STOCK_LEVEL
1 Pencils 10
2 Pens 2
3 Notepads 25
4 Stapler 5
5 Hole Punch 3
SQL>
Now, our Business has told the administrative clerk to check stock levels and re-order anything that is below the re-order level, but not to hold stock of more than 4 times the re-order level for any particular item. As an IT department we've been asked to put together an application that will automatically produce the re-order documents upon the clerks request and, because our company is so tight-ar*ed about money, they don't want to waste any paper with incorrect printouts so we have to ensure the clerk can't order things they shouldn't.
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure re_order(p_item_id NUMBER, p_quantity NUMBER) is
2 cursor cur_stock_reorder is
3 select s.stock_level
4 ,r.stock_level as reorder_level
5 ,(r.stock_level*4) as reorder_limit
6 from stock s join reorder_level r on (s.item_id = r.item_id)
7 where s.item_id = p_item_id;
8 --
9 v_stock cur_stock_reorder%ROWTYPE;
10 begin
11 OPEN cur_stock_reorder;
12 FETCH cur_stock_reorder INTO v_stock;
13 IF cur_stock_reorder%NOTFOUND THEN
14 RAISE no_data_found;
15 END IF;
16 CLOSE cur_stock_reorder;
17 --
18 IF v_stock.stock_level >= v_stock.reorder_level THEN
19 -- Stock is not low enough to warrant an order
20 DBMS_OUTPUT.PUT_LINE('Stock has not reached re-order level yet!');
21 ELSE
22 IF v_stock.stock_level + p_quantity > v_stock.reorder_limit THEN
23 -- Required amount is over-ordering
24 DBMS_OUTPUT.PUT_LINE('Quantity specified is too much. Max for this item: '
||to_char(v_stock.reorder_limit-v_stock.stock_level));
25 ELSE
26 DBMS_OUTPUT.PUT_LINE('Order OK. Printing Order...');
27 -- Here goes our code to print the order
28 END IF;
29 END IF;
30 --
31 exception
32 WHEN no_data_found THEN
33 CLOSE cur_stock_reorder;
34 DBMS_OUTPUT.PUT_LINE('Invalid Item ID.');
35* end;
SQL> /
Procedure created.
SQL> exec re_order(10,100);
Invalid Item ID.
PL/SQL procedure successfully completed.
SQL> exec re_order(3,40);
Stock has not reached re-order level yet!
PL/SQL procedure successfully completed.
SQL> exec re_order(1,100);
Quantity specified is too much. Max for this item: 70
PL/SQL procedure successfully completed.
SQL> exec re_order(2,50);
Order OK. Printing Order...
PL/SQL procedure successfully completed.
SQL>
Ok, so that code works, but it's a bit messy with all those nested IF statements. Is there a cleaner way perhaps? Wouldn't it be nice if we could set up our own exceptions...
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure re_order(p_item_id NUMBER, p_quantity NUMBER) is
2 cursor cur_stock_reorder is
3 select s.stock_level
4 ,r.stock_level as reorder_level
5 ,(r.stock_level*4) as reorder_limit
6 from stock s join reorder_level r on (s.item_id = r.item_id)
7 where s.item_id = p_item_id;
8 --
9 v_stock cur_stock_reorder%ROWTYPE;
10 --
11 -- Let's declare our own exceptions for business logic...
12 exc_not_warranted EXCEPTION;
13 exc_too_much EXCEPTION;
14 begin
15 OPEN cur_stock_reorder;
16 FETCH cur_stock_reorder INTO v_stock;
17 IF cur_stock_reorder%NOTFOUND THEN
18 RAISE no_data_found;
19 END IF;
20 CLOSE cur_stock_reorder;
21 --
22 IF v_stock.stock_level >= v_stock.reorder_level THEN
23 -- Stock is not low enough to warrant an order
24 RAISE exc_not_warranted;
25 END IF;
26 --
27 IF v_stock.stock_level + p_quantity > v_stock.reorder_limit THEN
28 -- Required amount is over-ordering
29 RAISE exc_too_much;
30 END IF;
31 --
32 DBMS_OUTPUT.PUT_LINE('Order OK. Printing Order...');
33 -- Here goes our code to print the order
34 --
35 exception
36 WHEN no_data_found THEN
37 CLOSE cur_stock_reorder;
38 DBMS_OUTPUT.PUT_LINE('Invalid Item ID.');
39 WHEN exc_not_warranted THEN
40 DBMS_OUTPUT.PUT_LINE('Stock has not reached re-order level yet!');
41 WHEN exc_too_much THEN
42 DBMS_OUTPUT.PUT_LINE('Quantity specified is too much. Max for this item: '
||to_char(v_stock.reorder_limit-v_stock.stock_level));
43* end;
SQL> /
Procedure created.
SQL> exec re_order(10,100);
Invalid Item ID.
PL/SQL procedure successfully completed.
SQL> exec re_order(3,40);
Stock has not reached re-order level yet!
PL/SQL procedure successfully completed.
SQL> exec re_order(1,100);
Quantity specified is too much. Max for this item: 70
PL/SQL procedure successfully completed.
SQL> exec re_order(2,50);
Order OK. Printing Order...
PL/SQL procedure successfully completed.
SQL>
That's better. And now we don't have to use all those nested IF statements and worry about it accidently getting to code that will print the order out as, once one of our user defined exceptions is raised, execution goes from the Statements section into the Exception section and all handling of errors is done in one place.
Now for the second sort of user defined exception...
A new requirement has come in from the Finance department who want to have details shown on the order that show a re-order 'indicator' based on the formula ((maximum allowed stock - current stock)/re-order quantity), so this needs calculating and passing to the report...
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure re_order(p_item_id NUMBER, p_quantity NUMBER) is
2 cursor cur_stock_reorder is
3 select s.stock_level
4 ,r.stock_level as reorder_level
5 ,(r.stock_level*4) as reorder_limit
6 ,(((r.stock_level*4)-s.stock_level)/p_quantity) as finance_factor
7 from stock s join reorder_level r on (s.item_id = r.item_id)
8 where s.item_id = p_item_id;
9 --
10 v_stock cur_stock_reorder%ROWTYPE;
11 --
12 -- Let's declare our own exceptions for business logic...
13 exc_not_warranted EXCEPTION;
14 exc_too_much EXCEPTION;
15 begin
16 OPEN cur_stock_reorder;
17 FETCH cur_stock_reorder INTO v_stock;
18 IF cur_stock_reorder%NOTFOUND THEN
19 RAISE no_data_found;
20 END IF;
21 CLOSE cur_stock_reorder;
22 --
23 IF v_stock.stock_level >= v_stock.reorder_level THEN
24 -- Stock is not low enough to warrant an order
25 RAISE exc_not_warranted;
26 END IF;
27 --
28 IF v_stock.stock_level + p_quantity > v_stock.reorder_limit THEN
29 -- Required amount is over-ordering
30 RAISE exc_too_much;
31 END IF;
32 --
33 DBMS_OUTPUT.PUT_LINE('Order OK. Printing Order...');
34 -- Here goes our code to print the order, passing the finance_factor
35 --
36 exception
37 WHEN no_data_found THEN
38 CLOSE cur_stock_reorder;
39 DBMS_OUTPUT.PUT_LINE('Invalid Item ID.');
40 WHEN exc_not_warranted THEN
41 DBMS_OUTPUT.PUT_LINE('Stock has not reached re-order level yet!');
42 WHEN exc_too_much THEN
43 DBMS_OUTPUT.PUT_LINE('Quantity specified is too much. Max for this item: '
||to_char(v_stock.reorder_limit-v_stock.stock_level));
44* end;
SQL> /
Procedure created.
SQL> exec re_order(2,40);
Order OK. Printing Order...
PL/SQL procedure successfully completed.
SQL> exec re_order(2,0);
BEGIN re_order(2,0); END;
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.RE_ORDER", line 17
ORA-06512: at line 1
SQL>
Hmm, there's a problem if the person specifies a re-order quantity of zero. It raises an unhandled exception.
Well, we could put a condition/check into our code to make sure the parameter is not zero, but again we would be wrapping our code in an IF statement and not dealing with the exception in the exception handler.
We could do as we did before and just include a simple IF statement to check the value and raise our own user defined exception but, in this instance the error is standard Oracle error (ORA-01476) so we should be able to capture it inside the exception handler anyway... however...
EXCEPTION
WHEN ORA-01476 THEN
... is not valid. What we need is to give this Oracle error a name.
This is done by declaring a user defined exception as we did before and then associating that name with the error number using the PRAGMA EXCEPTION_INIT statement in the declaration section.
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure re_order(p_item_id NUMBER, p_quantity NUMBER) is
2 cursor cur_stock_reorder is
3 select s.stock_level
4 ,r.stock_level as reorder_level
5 ,(r.stock_level*4) as reorder_limit
6 ,(((r.stock_level*4)-s.stock_level)/p_quantity) as finance_factor
7 from stock s join reorder_level r on (s.item_id = r.item_id)
8 where s.item_id = p_item_id;
9 --
10 v_stock cur_stock_reorder%ROWTYPE;
11 --
12 -- Let's declare our own exceptions for business logic...
13 exc_not_warranted EXCEPTION;
14 exc_too_much EXCEPTION;
15 --
16 exc_zero_quantity EXCEPTION;
17 PRAGMA EXCEPTION_INIT(exc_zero_quantity, -1476);
18 begin
19 OPEN cur_stock_reorder;
20 FETCH cur_stock_reorder INTO v_stock;
21 IF cur_stock_reorder%NOTFOUND THEN
22 RAISE no_data_found;
23 END IF;
24 CLOSE cur_stock_reorder;
25 --
26 IF v_stock.stock_level >= v_stock.reorder_level THEN
27 -- Stock is not low enough to warrant an order
28 RAISE exc_not_warranted;
29 END IF;
30 --
31 IF v_stock.stock_level + p_quantity > v_stock.reorder_limit THEN
32 -- Required amount is over-ordering
33 RAISE exc_too_much;
34 END IF;
35 --
36 DBMS_OUTPUT.PUT_LINE('Order OK. Printing Order...');
37 -- Here goes our code to print the order, passing the finance_factor
38 --
39 exception
40 WHEN exc_zero_quantity THEN
41 DBMS_OUTPUT.PUT_LINE('Quantity of 0 (zero) is invalid.');
42 WHEN no_data_found THEN
43 CLOSE cur_stock_reorder;
44 DBMS_OUTPUT.PUT_LINE('Invalid Item ID.');
45 WHEN exc_not_warranted THEN
46 DBMS_OUTPUT.PUT_LINE('Stock has not reached re-order level yet!');
47 WHEN exc_too_much THEN
48 DBMS_OUTPUT.PUT_LINE('Quantity specified is too much. Max for this item: '
||to_char(v_stock.reorder_limit-v_stock.stock_level));
49* end;
SQL> /
Procedure created.
SQL> exec re_order(2,0);
Quantity of 0 (zero) is invalid.
PL/SQL procedure successfully completed.
SQL>
Lastly, let's look at raising our own exceptions with our own exception numbers...
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure re_order(p_item_id NUMBER, p_quantity NUMBER) is
2 cursor cur_stock_reorder is
3 select s.stock_level
4 ,r.stock_level as reorder_level
5 ,(r.stock_level*4) as reorder_limit
6 ,(((r.stock_level*4)-s.stock_level)/p_quantity) as finance_factor
7 from stock s join reorder_level r on (s.item_id = r.item_id)
8 where s.item_id = p_item_id;
9 --
10 v_stock cur_stock_reorder%ROWTYPE;
11 --
12 exc_zero_quantity EXCEPTION;
13 PRAGMA EXCEPTION_INIT(exc_zero_quantity, -1476);
14 begin
15 OPEN cur_stock_reorder;
16 FETCH cur_stock_reorder INTO v_stock;
17 IF cur_stock_reorder%NOTFOUND THEN
18 RAISE no_data_found;
19 END IF;
20 CLOSE cur_stock_reorder;
21 --
22 IF v_stock.stock_level >= v_stock.reorder_level THEN
23 -- Stock is not low enough to warrant an order
24 [b]RAISE_APPLICATION_ERROR(-20000, 'Stock has not reached re-order level yet!');[/b]
25 END IF;
26 --
27 IF v_stock.stock_level + p_quantity > v_stock.reorder_limit THEN
28 -- Required amount is over-ordering
29its nice article, have put up this one the blog
site,Nah, I don't have time to blog, but if one of the other Ace's/Experts wants to copy it to a blog with reference back to here (and all due credit given ;)) then that's fine by me.
I'd go for a book like "Selected articles by OTN members" or something. Does anybody have a list of links of all those mentioned articles?Just these ones I've bookmarked...
Introduction to regular expressions ... by CD
When your query takes too long ... by Rob van Wijk
How to pipeline a function with a dynamic number of columns? by ascheffer
PL/SQL 101 : Exception Handling by BluShadow -
Store all values from updateable report on clientside for later use
apex 4.2 , 11xe
hello,
it is possible to store all values from an updateable report to something like an cache BEFORE sent it to DB ?
Background:
i have an modified updateable report ,look the jpg
http://www10.pic-upload.de/25.06.13/3zq5wr23awwg.jpg
updateable report have ever 29 rows. as example i make time entrys for an employee. very often the next employee have the same timeentrys. now iam thinking about to make the entrys for the first employee, then click a button to store the values from ALL cells into somting like a javascript cache or jquery.data() . when i pull another employee from lov i have a fresh empty report( with 29 rows) and now i want to call the data back from cache to the cells (with another button). the cache shouldnt be destroyed when refresh the page,cause there is a page refresh when pull another employee from lov.
is it possible to store all cell values(empty or not) from report all in one?
what is the best and simplest way ?
good would be an example for the code or method i should use.
or is somthing inside apex i could use for that. i looked in apex.api but didnt found something.
my report based on a view with iof trigger and apex collection.
greets/christianthx for answer jarola and sorry for my bad english.
apex collection will not work.
let me explain why not and i think something like javascript/jquery is better for that.
there is a table MAZEIT and i have this updateable report. when i select an employee from lov, a collection will be created. the collection look in MAZEIT ,perhaps there are real timeentrys, in this case the collection will be modified and give me 29 rows,some are filled. or there are no real entrys and the collection give me 29 empty rows.
here my report sql:
select
"HID_SEQ_ID",
"DATUM",
"WOTAG",
"WOTAGNR",
"KNDABT_ID",
"ZEIT",
"BEGINN",
"ENDE",
"PAUSE",
"ZUSCHLAG",
"BEM",
"MELDUNG"
from "#OWNER#"."V_COLL_MAZEIT"
here the v_coll_mazeit (view) sql
CREATE OR REPLACE VIEW V_COLL_MAZEIT AS
SELECT seq_id HID_SEQ_ID -- APEX_COLLECTIONS.SEQ_ID
,C001 HID_MAZEIT_ID -- MAZEIT.ID
,C002 DATUM -- Datum DD.MM.YYYY
,C003 WOTAG -- Wochentag Mo/Di/...
,C004 WOTAGNR -- Wochentag 1/2/...
,C005 KNDABT_ID -- Abteilung
,C006 ZEIT -- Zeit in HH24:MI
,C007 BEGINN -- Beginn in HH24:MI
,C008 ENDE -- Ende in HH24:MI
,C009 PAUSE -- Pause in HH24:MI
,C010 ZUSCHLAG
,C011 BEM
,C040 HID_MANDANT_ID
,C041 HID_KND_ID
,C042 HID_MA_ID
,C043 HID_KW
,C048 HID_HASH4CHECK -- Hash für Check auf Änderungen MAZEIT
,C049 HID_SORTIER -- für ORDER BY hier Arbeitsbeginn
,C050 MELDUNG -- für FehlerMeldungen
FROM APEX_COLLECTIONS
WHERE COLLECTION_NAME='V_COLL_MAZEIT'
ORDER BY HID_SORTIER;
here the trigger (iof) from v_coll_mazeit
CREATE OR REPLACE TRIGGER "V_COLL_MAZEIT_IOF_U_TRG"
INSTEAD OF UPDATE ON V_COLL_MAZEIT
FOR EACH ROW
BEGIN
--RAISE_APPLICATION_ERROR(-20004,'NIX DA');
CM_MEAT.V_COLL_MAZEIT_IOF_U_TRG(
:NEW.HID_SEQ_ID
,:NEW.HID_MAZEIT_ID
,:NEW.DATUM
,:NEW.WOTAG
,:NEW.WOTAGNR
,:NEW.KNDABT_ID
,:NEW.ZEIT
,:NEW.BEGINN
,:NEW.ENDE
,:NEW.PAUSE
,:NEW.ZUSCHLAG
,:NEW.BEM
,:NEW.HID_HASH4CHECK
,:NEW.HID_SORTIER
,:NEW.MELDUNG
END V_COLL_MAZEIT_IOF_U_TRG;
and here a package procedure when i select an employee:
PROCEDURE V_COLL_MAZEIT_PROC(
iAction IN PLS_INTEGER,
iDatum IN DATE DEFAULT SYSDATE,
iMandantId IN MAZEIT.MANDANT_ID%TYPE,
iKndId IN MAZEIT.KND_ID%TYPE,
iMaId IN MAZEIT.MA_ID%TYPE,
oCollName OUT VARCHAR2)
IS
TK_FUNC_NAME CONSTANT USER_OBJECTS.OBJECT_NAME%TYPE := 'V_COLL_MAZEIT_PROC';
TK_COLL_NAME CONSTANT APEX_COLLECTIONS.COLLECTION_NAME%TYPE := 'V_COLL_MAZEIT';
TK_MD5 CONSTANT VARCHAR2(2) := 'NO';
TYPE t_Tage_TAB IS TABLE OF DATE INDEX BY BINARY_INTEGER;
TYPE t_TageVC_TAB IS TABLE OF VARCHAR2(8) INDEX BY BINARY_INTEGER;
TYPE t_TageI_TAB IS TABLE OF PLS_INTEGER INDEX BY BINARY_INTEGER;
tTage t_Tage_TAB;
tTageVC t_TageVC_TAB;
tTageI t_TageI_TAB;
vDatum DATE;
vDatumCh VARCHAR2(8);
vKW4Db MAZEIT.KW%TYPE;
vI PLS_INTEGER := 0;
vAnz PLS_INTEGER := 0;
BEGIN
FOR rec IN (SELECT * FROM NLS_SESSION_PARAMETERS)
LOOP
InsProto(rec.PARAMETER||'=['||rec.VALUE||']',
QK_PACK_NAME,TK_FUNC_NAME);
END LOOP;
CMT.InsProto('iAction='||iAction||', iDatum='||iDatum||', iMandantId='||iMandantId||', iKndId='||iKndId||', iMaId'||iMaId,
QK_PACK_NAME,TK_FUNC_NAME);
oCollName := TK_COLL_NAME;
IF iAction=0 THEN -- löschen
IF APEX_COLLECTION.COLLECTION_EXISTS(p_collection_name=>TK_COLL_NAME) THEN
APEX_COLLECTION.TRUNCATE_COLLECTION(TK_COLL_NAME);
APEX_COLLECTION.DELETE_COLLECTION(TK_COLL_NAME);
END IF;
|| Säubern und anlegen
ELSIF iAction=1 THEN
IF APEX_COLLECTION.COLLECTION_EXISTS(p_collection_name=>TK_COLL_NAME) THEN
APEX_COLLECTION.TRUNCATE_COLLECTION(p_collection_name=>TK_COLL_NAME);
ELSE
APEX_COLLECTION.CREATE_COLLECTION(p_collection_name=>TK_COLL_NAME);
END IF;
vDatum := NVL(iDATUM,SYSDATE);
vDatum := TO_DATE(TO_CHAR(vDatum,'YYYYMMDD')||'000000','YYYYMMDDHH24MISS');
vKW4Db := GetKW4Db(vDatum);
tTage(1) := CMT.GetMonday(vDATUM,0);
SELECT tTage(1) + 1DAY,tTage(1) + 2DAY,tTage(1) + 3DAY,tTage(1) + 4DAY,tTage(1) + 5DAY,tTage(1) + 6DAY
INTO tTage(2),tTage(3),tTage(4),tTage(5),tTage(6),tTage(7)
FROM DUAL;
FOR i IN 1..7 LOOP tTageI(i) := 0; tTageVC(i) := TO_CHAR(tTage(i),'YYYYMMDD'); END LOOP;
-- erste Zeile enthält Default-Werte
APEX_COLLECTION.add_member( p_COLLECTION_name=> TK_COLL_NAME,p_generate_md5=>TK_MD5
,P_C001 => 0 -- MAZEIT.ID
,P_C002 => '<b>Vorgabe</b>' -- Datum DD.MM.YYYY
,P_C003 => ' ' -- Wochentag Mo/Di/...
,P_C004 => ' ' -- Wochentag 1/2/...
,P_C005 => 0 -- MAZEIT.KNDABT_ID
,P_C006 => NULL -- Zeit in HH24:MI
,P_C007 => NULL -- Beginn in HH24:MI
,P_C008 => NULL -- Ende in HH24:MI
,P_C009 => NULL -- Pause in HH24:MI
,P_C010 => NULL -- Zuschlag
,P_C011 => NULL -- Bem
,P_C040 => iMandantId
,P_C041 => iKndId
,P_C042 => iMaId
,P_C043 => vKW4Db
,P_C048 => '-1' -- Hash für Check auf Änderungen MAZEIT
,P_C049 => ' ' -- für ORDER BY hier Arbeitsbeginn
,P_C050 => NULL
FOR rec IN (SELECT z.*,
TO_CHAR(DBMS_UTILITY.get_hash_value(
z.id||'|'||
z.mandant_id||'|'||
z.majob_id||'|'||
z.ma_id||'|'||
z.knd_id||'|'||
z.kndabt_id||'|'||
z.kw||'|'||
z.arb_beg||'|'||
z.arb_end||'|'||
z.zeit||'|'||
z.pause||'|'||
z.zuschlag||'|'||
z.stk_anz||'|'||
z.stk_kg||'|'||
z.stk_gemuur||'|'||
z.stk_bezahlt||'|'||
z.bem||'|'||
z.ART4RECH
,1,POWER(2,30))) AS HID_HASH4CHECK
FROM MAZEIT z
WHERE z.MANDANT_ID=iMandantId AND
z.KND_ID=iKndId AND
z.MA_ID=iMaId AND
z.KW = GetKW4Db(tTage(1)) AND
z.ART4RECH IN (CMT.GetTCVNum('MAZEIT_ART4RECH_STD'),CMT.GetTCVNum('MAZEIT_ART4RECH_STK'),CMT.GetTCVNum('MAZEIT_ART4RECH_KG'))
ORDER BY z.ARB_BEG)
LOOP
IF rec.ZUSCHLAG=0 THEN
rec.ZUSCHLAG := NULL;
END IF;
vI := 0;
vDatumCh := TO_CHAR(rec.ARB_BEG,'YYYYMMDD');
FOR i IN 1..7 LOOP
IF tTageVC(i)=vDatumCh THEN
tTageI(i) := tTageI(i) + 1;
vI := i;
EXIT;
END IF;
END LOOP;
-- Stücklohn kommt an den Anfang der Bemerkung gekennzeichnet mit QK_COLL_MAZEIT_STK_KZ ursprüngliche Bemekuung nach dem :
rec.BEM := RTRIM(rec.BEM);
IF rec.ART4RECH = CMT.GetTCVNum('MAZEIT_ART4RECH_STK') THEN
DECLARE
vBem MAZEIT.BEM%TYPE := QK_COLL_MAZEIT_STK_KZ;
BEGIN
IF rec.STK_BEZAHLT > 0. THEN
vBem := QK_COLL_MAZEIT_STK_KZ||TO_CHAR(rec.stk_bezahlt,'FM9999D00');
ELSIF rec.STK_ANZ > 0 THEN
vBem := QK_COLL_MAZEIT_STA_KZ||TO_CHAR(rec.stk_anz,'FM9999');
END IF;
IF rec.BEM IS NULL THEN
rec.BEM := vBem;
ELSE
rec.BEM := SUBSTR(vBem||':'||rec.BEM,1,CMT.GetColLen('MAZEIT','BEM'));
END IF;
END;
ELSIF rec.ART4RECH = CMT.GetTCVNum('MAZEIT_ART4RECH_KG') THEN
DECLARE
vBem MAZEIT.BEM%TYPE := QK_COLL_MAZEIT_KG_KZ;
BEGIN
IF rec.STK_KG > 0. THEN
vBem := QK_COLL_MAZEIT_KG_KZ||TO_CHAR(rec.stk_kg,'FM999999D000');
END IF;
IF rec.BEM IS NULL THEN
rec.BEM := vBem;
ELSE
rec.BEM := SUBSTR(vBem||':'||rec.BEM,1,CMT.GetColLen('MAZEIT','BEM'));
END IF;
END;
END IF;
IF vI>0 THEN
IF tTageI(vI)=1 THEN
APEX_COLLECTION.add_member( p_COLLECTION_name=> TK_COLL_NAME,p_generate_md5=>TK_MD5
,P_C001 => rec.id -- MAZEIT.ID
,P_C002 => TO_CHAR(rec.ARB_BEG,'DD.MM.YYYY') -- Datum DD.MM.YYYY
,P_C003 => CMT.WoTag(rec.ARB_BEG) -- Wochentag Mo/Di/...
,P_C004 => CMT.WoTagNr(rec.ARB_BEG) -- Wochentag 1/2/...
,P_C005 => rec.KNDABT_ID -- MAZEIT.KNDABT_ID
,P_C006 => CMT.Minuten2InduZeit(rec.ZEIT) -- Zeit als InduZeit in HH24,MI
,P_C007 => TO_CHAR(rec.ARB_BEG,'HH24:MI') -- Beginn in HH24:MI
,P_C008 => TO_CHAR(rec.ARB_END,'HH24:MI') -- Ende in HH24:MI
,P_C009 => CMT.Minuten2HHMI(rec.PAUSE,TRUE) -- Pause in HH24:MI
,P_C010 => rec.ZUSCHLAG
,P_C011 => rec.BEM
,P_C040 => iMandantId
,P_C041 => iKndId
,P_C042 => iMaId
,P_C043 => vKW4Db
,P_C048 => rec.HID_HASH4CHECK -- Hash für Check auf Änderungen MAZEIT
,P_C049 => TO_CHAR(rec.ARB_BEG,'YYYYMMDDHH24MI') -- für ORDER BY hier Arbeitsbeginn
,P_C050 => NULL -- für FehlerMeldungen
ELSE
APEX_COLLECTION.add_member( p_COLLECTION_name=> TK_COLL_NAME,p_generate_md5=>TK_MD5
,P_C001 => rec.id -- MAZEIT.ID
,P_C002 => NULL -- Datum DD.MM.YYYY
,P_C003 => NULL -- Wochentag Mo/Di/...
,P_C004 => NULL -- Wochentag 1/2/...
,P_C005 => rec.KNDABT_ID -- MAZEIT.KNDABT_ID
,P_C006 => CMT.Minuten2InduZeit(rec.ZEIT) -- Zeit als InduZeit in HH24,MI
,P_C007 => TO_CHAR(rec.ARB_BEG,'HH24:MI') -- Beginn in HH24:MI
,P_C008 => TO_CHAR(rec.ARB_END,'HH24:MI') -- Ende in HH24:MI
,P_C009 => CMT.Minuten2HHMI(rec.PAUSE,TRUE) -- Pause in HH24:MI
,P_C010 => rec.ZUSCHLAG
,P_C011 => rec.BEM
,P_C040 => iMandantId
,P_C041 => iKndId
,P_C042 => iMaId
,P_C043 => vKW4Db
,P_C048 => rec.HID_HASH4CHECK -- Hash für Check auf Änderungen MAZEIT
,P_C049 => TO_CHAR(rec.ARB_BEG,'YYYYMMDDHH24MI') -- für ORDER BY hier Arbeitsbeginn
,P_C050 => NULL -- für FehlerMeldungen
END IF;
vAnz := vAnz + 1;
END IF;
END LOOP;
FOR i IN 1..7 LOOP
IF tTageI(i)<4 THEN
FOR j IN tTageI(i)+1..4 LOOP
IF j=1 THEN
APEX_COLLECTION.add_member( p_COLLECTION_name=> TK_COLL_NAME,p_generate_md5=>TK_MD5
,P_C001 => -1 -- MAZEIT.ID
,P_C002 => TO_CHAR(tTage(i),'DD.MM.YYYY') -- Datum DD.MM.YYYY
,P_C003 => CMT.WoTag(tTage(i)) -- Wochentag Mo/Di/...
,P_C004 => CMT.WoTagNr(tTage(i)) -- Wochentag 1/2/...
,P_C005 => 0 -- MAZEIT.KNDABT_ID
--,P_C006 => Minuten2InduZeit(0) -- Zeit als InduZeit in HH24,MI
,P_C006 => NULL -- Zeit als InduZeit in HH24,MI
--,P_C007 => '06:30' -- Beginn in HH24:MI
,P_C007 => NULL -- Beginn in HH24:MI
,P_C008 => NULL -- Ende in HH24:MI
--,P_C009 => Minuten2HHMI(0) -- Pause in HH24:MI
,P_C009 => NULL -- Pause in HH24:MI
,P_C010 => NULL -- Zuschlag
,P_C011 => NULL -- Bem
,P_C040 => iMandantId
,P_C041 => iKndId
,P_C042 => iMaId
,P_C043 => vKW4Db
,P_C048 => '-1' -- Hash für Check auf Änderungen MAZEIT
,P_C049 => TO_CHAR(tTage(i),'YYYYMMDD')||'99'||TO_CHAR(j,'FM09') -- für ORDER BY hier Arbeitsbeginn
,P_C050 => NULL
ELSE -- auffüllen
APEX_COLLECTION.add_member( p_COLLECTION_name=> TK_COLL_NAME,p_generate_md5=>TK_MD5
,P_C001 => -1 -- MAZEIT.ID
,P_C002 => NULL -- Datum DD.MM.YYYY
,P_C003 => NULL -- Wochentag Mo/Di/...
,P_C004 => NULL -- Wochentag 1/2/...
,P_C005 => 0 -- MAZEIT.KNDABT_ID
--,P_C006 => Minuten2HHMI(0) -- Zeit in HH24:MI
,P_C006 => NULL -- Zeit in HH24:MI
--,P_C007 => '06:30' -- Beginn in HH24:MI
,P_C007 => NULL -- Beginn in HH24:MI
,P_C008 => NULL -- Ende in HH24:MI
--,P_C009 => Minuten2InduZeit(0) -- Pause als InduZeit in HH24,MI
,P_C009 => NULL -- Pause als InduZeit in HH24,MI
,P_C010 => NULL -- Zuschlag
,P_C011 => NULL -- Bem
,P_C040 => iMandantId
,P_C041 => iKndId
,P_C042 => iMaId
,P_C043 => vKW4Db
,P_C048 => '-1' -- Hash für Check auf Änderungen MAZEIT
,P_C049 => TO_CHAR(tTage(i),'YYYYMMDD')||'99'||TO_CHAR(j,'FM09') -- für ORDER BY hier Arbeitsbeginn
,P_C050 => NULL
END IF;
END LOOP;
END IF;
END LOOP;
vI := 0;
FOR rec IN (SELECT * FROM V_COLL_MAZEIT) LOOP
vI := vI + 1;
CMT.InsProto('i='||LPAD(TO_CHAR(vI),3,' ')||':'||
rec.hid_seq_id||'|'||
rec.hid_mazeit_id||'|'||
rec.datum||'|'||
rec.wotag||'|'||
rec.wotagnr||'|'||
rec.zeit||'|'||
rec.beginn||'|'||
rec.ende||'|'||
rec.pause||'|'||
rec.zuschlag||'|'||
rec.bem||'|'||
rec.hid_hash4check||'|'||
rec.hid_sortier||'|'||
rec.meldung
,QK_PACK_NAME,TK_FUNC_NAME);
END LOOP;
ELSE
raise_Application_ERROR(-20100,'kann ich doch nicht Action='||TO_CHAR(iAction));
END IF;
END V_COLL_MAZEIT_PROC;
and here the procedure (look for real entrys in table)
PROCEDURE V_COLL_MAZEIT_IOF_U_TRG(
iHID_SEQ_ID apex_collections.seq_id%TYPE
,iHID_MAZEIT_ID apex_collections.C001%TYPE
,iDATUM apex_collections.C002%TYPE
,iWOTAG apex_collections.C003%TYPE
,iWOTAGNR apex_collections.C004%TYPE
,iKNDABT_ID apex_collections.C005%TYPE
,iZEIT apex_collections.C006%TYPE
,iBEGINN apex_collections.C007%TYPE
,iENDE apex_collections.C008%TYPE
,iPAUSE apex_collections.C009%TYPE
,iZUSCHLAG apex_collections.C010%TYPE
,iBEM apex_collections.C011%TYPE
,iHID_HASH4CHECK apex_collections.C048%TYPE
,iHID_SORTIER apex_collections.C049%TYPE
,iMELDUNG apex_collections.C050%TYPE
IS
PRAGMA AUTONOMOUS_TRANSACTION;
TK_FUNC_NAME CONSTANT USER_OBJECTS.OBJECT_NAME%TYPE := 'V_COLL_MAZEIT_IOF_U_TRG';
TK_COLL_NAME CONSTANT APEX_COLLECTIONS.COLLECTION_NAME%TYPE := 'V_COLL_MAZEIT';
vRcString VARCHAR2(2000) := NULL;
rCollMaZeit0 V_COLL_MAZEIT%ROWTYPE;
rCollMaZeit V_COLL_MAZEIT%ROWTYPE;
rMaZeit MAZEIT%ROWTYPE;
vHash4Check PLS_INTEGER;
vURow ROWID;
BEGIN
CMT.InsProto(
ihid_seq_id||'|'||
ihid_mazeit_id||'|'||
idatum||'|'||
iwotag||'|'||
iwotagnr||'|'||
iKNDABT_ID||'|'||
izeit||'|'||
ibeginn||'|'||
iende||'|'||
ipause||'|'||
izuschlag||'|'||
ibem||'|'||
ihid_hash4check||'|'||
ihid_sortier||'|'||
imeldung
,QK_PACK_NAME,TK_FUNC_NAME);
-- VIEW-ZeitZeile lesen
SELECT t.* INTO rCollMaZeit
FROM V_COLL_MAZEIT t
WHERE t.HID_SEQ_ID = iHID_SEQ_ID;
IF iHID_MAZEIT_ID!=rCollMaZeit.HID_MAZEIT_ID OR
iHID_HASH4CHECK!=rCollMaZeit.HID_HASH4CHECK THEN
vRcString := 'Daten seit Anzeige verändert';
GOTO MARK_TRANSEND;
END IF;
-- VIEW-ZeitDefaultZeile setzen
IF rCollMaZeit.HID_MAZEIT_ID=0 THEN
--,P_C005 => 0 -- MAZEIT.KNDABT_ID
--,P_C006 => NULL -- Zeit in HH24,MI
--,P_C007 => NULL -- Beginn in HH24:MI
--,P_C008 => NULL -- Ende in HH24:MI
--,P_C009 => NULL -- Pause in HH24,MI
--,P_C010 => NULL -- Zuschlag
--,P_C011 => NULL -- Bem
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>5, p_attr_value=>iKNDABT_ID);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>6, p_attr_value=>iZEIT);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>7, p_attr_value=>iBEGINN);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>8, p_attr_value=>iENDE);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>9, p_attr_value=>iPAUSE);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>10, p_attr_value=>iZUSCHLAG);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>11, p_attr_value=>iBEM);
IF iBEM LIKE '#%' THEN -- Verteilen
-- VIEW-ZeitDefaultZeile lesen
SELECT t.* INTO rCollMaZeit0
FROM V_COLL_MAZEIT t
WHERE t.HID_MAZEIT_ID = 0;
rCollMaZeit0.BEM := SUBSTR(iBEM,2);
DECLARE
vAnz PLS_INTEGER := 0;
nVert MAZEIT.ZEIT%TYPE;
nZeitMinuten MAZEIT.ZEIT%TYPE;
nDiffMinuten MAZEIT.ZEIT%TYPE;
BEGIN
SELECT NVL(COUNT(*),0) INTO vAnz
FROM V_COLL_MAZEIT t
WHERE t.HID_MAZEIT_ID = -1 AND
t.DATUM IS NOT NULL AND
t.WOTAGNR IN ('1','2','3','4','5'); -- nur Mo-Fr
IF vAnz<=0 THEN
vRcString := 'Verteilen nicht möglich keine freien Tage gefunden';
ELSIF TRIM(iZEIT) IS NULL OR TRIM(iZEIT) IN ('00,00','0,00','0',',00',',0','0,','0,0') THEN
vRcString := 'Verteilen von Null Minuten nicht möglich';
ELSE
nDiffMinuten := 0;
nZeitMinuten := CMT.InduZeit2MinutenNum(TRIM(iZEIT));
IF nZeitMinuten>(vAnz*1440) THEN
vRcString := 'Zu verteilende Zeit zu groß';
ELSIF vAnz>1 THEN
nVert := FLOOR(nZeitMinuten/vAnz);
nDiffMinuten := nZeitMinuten - (nVert*vAnz);
nZeitMinuten := nVert;
END IF;
IF vRcString IS NULL THEN
FOR rec IN (SELECT t.* INTO rCollMaZeit
FROM V_COLL_MAZEIT t
WHERE t.HID_MAZEIT_ID = -1 AND
t.DATUM IS NOT NULL AND
t.WOTAGNR IN ('1','2','3','4','5')) -- nur Mo-Fr)
LOOP
rCollMaZeit := rec;
vRcString := qV_COLL_MAZEIT_Insert(iKNDABT_ID, iZEIT, nZeitMinuten+nDiffMinuten, iBEGINN, iENDE, iPAUSE, iZUSCHLAG, SUBSTR(iBEM,2),
rCollMaZeit0, rCollMaZeit, rMaZeit);
IF vRcString IS NOT NULL THEN
EXIT;
END IF;
nDiffMinuten := 0;
END LOOP;
END IF;
END IF;
END;
END IF;
-- MAZEIT-Vorhandener Eintrag
ELSIF rCollMaZeit.HID_MAZEIT_ID>0 THEN
SELECT z.ROWID, TO_CHAR(DBMS_UTILITY.get_hash_value(
z.id||'|'||
z.mandant_id||'|'||
z.majob_id||'|'||
z.ma_id||'|'||
z.knd_id||'|'||
z.kndabt_id||'|'||
z.kw||'|'||
z.arb_beg||'|'||
z.arb_end||'|'||
z.zeit||'|'||
z.pause||'|'||
z.zuschlag||'|'||
z.stk_anz||'|'||
z.stk_kg||'|'||
z.stk_gemuur||'|'||
z.stk_bezahlt||'|'||
z.bem||'|'||
z.ART4RECH
,1,POWER(2,30))) AS HID_HASH4CHECK
INTO vURow, vHash4Check
FROM MAZEIT z
WHERE z.ID=rCollMaZeit.HID_MAZEIT_ID
FOR UPDATE NOWAIT;
IF vHash4Check!=rCollMaZeit.HID_HASH4CHECK THEN
vRcString := 'Daten seit Anzeige verändert';
GOTO MARK_TRANSEND;
END IF;
SELECT z.* INTO rMaZeit
FROM MAZEIT z
WHERE ROWID=vURow;
rMaZeit.KNDABT_ID := TO_NUMBER(TRIM(iKNDABT_ID));
IF TRIM(iBEGINN) IS NULL THEN
rMaZeit.ARB_BEG := NULL;
ELSE
rMaZeit.ARB_BEG := TO_DATE(TO_CHAR(rMaZeit.ARB_BEG,'YYYYMMDD')||TRIM(SUBSTR(iBEGINN,1,5)),'YYYYMMDDHH24:MI');
END IF;
IF TRIM(iENDE) IS NULL THEN
rMaZeit.ARB_END := NULL;
ELSE
rMaZeit.ARB_END := TO_DATE(TO_CHAR(rMaZeit.ARB_BEG,'YYYYMMDD')||TRIM(SUBSTR(iENDE,1,5)),'YYYYMMDDHH24:MI');
END IF;
IF TRIM(iZEIT) IS NULL THEN
rMaZeit.ZEIT := NULL;
ELSE
rMaZeit.ZEIT := CMT.InduZeit2MinutenNum(TRIM(iZEIT));
END IF;
IF TRIM(iPAUSE) IS NULL THEN
rMaZeit.PAUSE := NULL;
ELSE
rMaZeit.PAUSE := CMT.HHMI2Minuten(TRIM(iPAUSE));
END IF;
IF iWOTAGNR IN (6,7) AND
rMaZeit.PAUSE IS NOT NULL AND rMaZeit.PAUSE<>0 THEN
vRcString := 'Eintrag Pause am Wochenende nicht erlaubt';
GOTO MARK_TRANSEND;
END IF;
IF TRIM(iZUSCHLAG) IS NULL THEN
rMaZeit.ZUSCHLAG := NULL;
ELSE
rMaZeit.ZUSCHLAG := TO_NUMBER(TRIM(iZUSCHLAG));
END IF;
IF RTRIM(iBEM) IS NULL THEN
rMaZeit.BEM := NULL;
ELSE
rMaZeit.BEM := RTRIM(iBEM);
END IF;
IF (rMaZeit.KNDABT_ID IS NOT NULL AND rMaZeit.KNDABT_ID>0) OR
rMaZeit.ARB_BEG IS NOT NULL OR rMaZeit.ARB_END IS NOT NULL OR
(rMaZeit.ZEIT IS NOT NULL AND rMaZeit.ZEIT!=0) OR rMaZeit.PAUSE IS NOT NULL OR
rMaZeit.ZUSCHLAG IS NOT NULL OR rMaZeit.BEM IS NOT NULL THEN
DECLARE
vBem MAZEIT.BEM%TYPE := rMaZeit.BEM;
BEGIN
rMaZeit.ZUSCHLAG := NVL(rMaZeit.ZUSCHLAG,0.0);
qV_COLL_MAZEIT_BEM_CHK(rMaZeit); -- Bem prüfen wg. ART4RECH Verschlüsselung mittels QK_COLL_MAZEIT_STK_KZ
UPDATE MAZEIT z
SET z.KNDABT_ID = rMaZeit.KNDABT_ID
,z.ARB_BEG = rMaZeit.ARB_BEG
,z.ARB_END = rMaZeit.ARB_END
,z.ZEIT = rMaZeit.ZEIT
,z.PAUSE = rMaZeit.PAUSE
,z.ZUSCHLAG = rMaZeit.ZUSCHLAG
,z.BEM = rMaZeit.BEM
,z.STK_BEZAHLT = rMaZeit.STK_BEZAHLT
,z.STK_ANZ = rMaZeit.STK_ANZ
,z.STK_KG = rMaZeit.STK_KG
,z.ART4RECH = rMaZeit.ART4RECH
WHERE ROWID=vURow;
IF SQL%ROWCOUNT=1 THEN
NULL;
ELSIF SQL%ROWCOUNT<1 THEN
RAISE NO_DATA_FOUND;
ELSE
RAISE TOO_MANY_ROWS;
END IF;
rMaZeit.BEM := vBem;
END;
ELSE
DELETE FROM MAZEIT z
WHERE ROWID=vURow;
IF SQL%ROWCOUNT=1 THEN
NULL;
ELSIF SQL%ROWCOUNT<1 THEN
RAISE NO_DATA_FOUND;
ELSE
RAISE TOO_MANY_ROWS;
END IF;
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>1, p_attr_value=>-1);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>48, p_attr_value=>'-1');
END IF;
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>5, p_attr_value=>rMaZeit.KNDABT_ID);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>6, p_attr_value=>CMT.Minuten2InduZeit(rMaZeit.ZEIT));
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>7, p_attr_value=>TO_CHAR(rMaZeit.ARB_BEG,'HH24:MI'));
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>8, p_attr_value=>TO_CHAR(rMaZeit.ARB_END,'HH24:MI'));
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>9, p_attr_value=>CMT.Minuten2InduZeit(rMaZeit.PAUSE,TRUE) );
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>10, p_attr_value=>rMaZeit.ZUSCHLAG);
APEX_COLLECTION.update_member_attribute( p_COLLECTION_name=> TK_COLL_NAME, p_seq=>rCollMaZeit.HID_SEQ_ID
,p_attr_number=>11, p_attr_value=>RTRIM(rMaZeit.BEM));
-- MAZEIT neuer Eintrag
ELSIF rCollMaZeit.HID_MAZEIT_ID=-1 THEN
-- VIEW-ZeitDefaultZeile lesen
SELECT t.* INTO rCollMaZeit0
FROM V_COLL_MAZEIT t
WHERE t.HID_MAZEIT_ID = 0;
vRcString := qV_COLL_MAZEIT_Insert(iKNDABT_ID, iZEIT, NULL, iBEGINN, iENDE, iPAUSE, iZUSCHLAG, iBEM,
rCollMaZeit0, rCollMaZeit, rMaZeit);
ELSE
vRcString := 'Ungültige HID_MAZEIT_ID '||TO_CHAR(rCollMaZeit.HID_MAZEIT_ID);
END IF;
<<MARK_TRANSEND>>
IF vRcString IS NULL THEN
COMMIT;
ELSE
ROLLBACK;
RAISE_APPLICATION_ERROR(-20100,vRcString);
END IF;
END V_COLL_MAZEIT_IOF_U_TRG;
and in end there are 3 other procedures, all for table MAZEIT, the collection and and the report.
in princip its a good idea,to create another collection, but difficult to bind it to the report TOO,cause my "cell-fill- functionality" is to complicated.
my idea is another: to look with javascript/jquery whatever on clientside the cell-values. and only the editable cells. not the hidden cells.there would be ca. 180 editable cells. i want store the values from this cells all in one in a cache (clientside! ).
then select next employee (collection will be created with view ect.) and give me this 29 rows. in this moment i have cells with ID f02_0001 as example and can use the cache values with that. the ID's ever the same,cause i have ever 29 rows.
greets/christian -
Delete Statement Exception Handling
Hi guys,
I have a problem in my procedure. There are 3 parameters that I am passing into the procedure. I am matching these parameters to those in the table to delete one record at a time.
For example if I would like to delete the record with the values ('900682',3,'29-JUL-2008') as parameters, it deletes the record from the table but then again when I execute it with the same parameters it should show me an error message but it again says 'Deleted the Transcript Request.....' Can you please help me with this?
PROCEDURE p_delete_szptpsr_1 (p_shttran_id IN saturn.shttran.shttran_id%TYPE,
p_shttran_seq_no IN saturn.shttran.shttran_seq_no%TYPE,
p_shttran_request_date IN saturn.shttran.shttran_request_date%TYPE) IS
BEGIN
DELETE FROM saturn.shttran
WHERE shttran.shttran_id = p_shttran_id
and shttran.shttran_seq_no = p_shttran_seq_no
and trunc(shttran_request_date) = trunc(p_shttran_request_date);
DBMS_OUTPUT.PUT_LINE('Deleted the Transcript Request Seq No (' || p_shttran_seq_no || ') of the Student (' || p_shttran_id ||') for the requested date of (' || p_shttran_request_date ||')');
COMMIT;
EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Error: The supplied Notre Dame Student ID = (' || p_shttran_id ||
'), Transcript Request No = (' || p_shttran_seq_no || '), Request Date = (' || p_shttran_request_date || ') was not found.');
END p_delete_szptpsr_1;
Should I have a SELECT statement to use NO_DATA_FOUND ???A DELETE statement that deletes no rows (just like an UPDATE statement that updates no rows) is not an error to Oracle. Oracle won't throw any exception.
If you want your code to throw an exception, you'll need to write that logic. You could throw a NO_DATA_FOUND exception yourself, i.e.
IF( SQL%ROWCOUNT = 0 )
THEN
RAISE no_data_found;
END IF;If you are just going to catch the exception, though, you could just embed whatever code you would use to handle the exception in your IF statement, i.e.
IF( SQL%ROWCOUNT = 0 )
THEN
<<do something about the exception>>
END IF;In your original code, your exception handler is just a DBMS_OUTPUT statement. That is incredibly dangerous in real production code. You are relying on the fact that the client has enabled output, that the client has allocated a large enough buffer, that the user is going to see the message, and that the procedure will never be called from any piece of code that would ever care if it succeeded or failed. There are vanishingly few situations where those are safe things to rely on.
Justin -
hello.
I hope someone can help. My script below takes record(s) from a temporary table and loads them into ORACLE Financials via several APIs but on initial testing (using 1 NEW Record) it fails with the error message:
Employee No: 00020206
ORACLE error occurred processing record.. ORA-20001: PAY_7599_SYS_SUP_DT_OUTDATE
Ive tried to google the error message but nothing - can someone either suggest what this may be or shsow me another way of getting a more precise reason for the problem?
/* Formatted on 2009/04/29 11:52 (Formatter Plus v4.8.7) */
SET serveroutput ON SIZE 1000000 FORMAT WRAPPED
SET verify OFF
SET feedback OFF
DECLARE
-- Debugging/error handling
-- Work variables
l_employ_start_date DATE:= TO_DATE ('01-APR-1999', 'DD-MON-YYYY');
v_ora_loc_code number := 0;
p_emp_number VARCHAR2 (14);
v_rec_cnt NUMBER := 0;
insert_flag VARCHAR2 (8);
err_num NUMBER;
err_msg VARCHAR2 (150);
err_line VARCHAR2 (350);
err_seq NUMBER := 0;
l_validate BOOLEAN DEFAULT FALSE;
l_std_business_group_id NUMBER := '0';
l_default_code_comb_id NUMBER := '218048';
l_organization_id NUMBER := '0';
l_set_of_books_id NUMBER := '1';
l_job_id NUMBER := '10';
l_obj NUMBER;
l_datetrack_update_mode VARCHAR2 (30) := 'CORRECTION';
l_assignment_sequence NUMBER;
l_name_combination_warning BOOLEAN := FALSE;
l_assign_payroll_warning BOOLEAN := FALSE;
l_org_now_no_manager_warning BOOLEAN;
l_other_manager_warning BOOLEAN;
l_spp_delete_warning BOOLEAN;
l_entries_changed_warning VARCHAR2 (30);
l_tax_district_changed_warning BOOLEAN;
l_person_id NUMBER;
l_assignment_id NUMBER;
l_assignment_id2 NUMBER; -- := '28262';
l_special_ceiling_step_id NUMBER;
l_per_effective_end_date DATE:= TO_DATE ('11-Jul-2049', 'DD-MON-YYYY');
l_people_group_id NUMBER;
l_group_name VARCHAR2 (30);
l_assignment_number VARCHAR2 (35);
l_effective_end_date DATE := TO_DATE ('11-Jul-2049', 'DD-MON-YYYY');
l_date DATE := SYSDATE;
ip_p_address_id per_addresses.address_id%TYPE;
ip_p_object_version_number NUMBER;
ip_p_party_id per_addresses.party_id%TYPE;
l_per_object_version_number NUMBER;
l_asg_object_version_number NUMBER;
l_full_name VARCHAR2 (240);
l_per_comment_id NUMBER;
l_per_effective_start_date DATE;
l_concatenated_segments VARCHAR2 (240);
l_soft_coding_keyflex_id NUMBER;
l_comment_id NUMBER;
l_no_managers_warning BOOLEAN;
-- Get employee details info from work table
CURSOR get_employee_details
IS
SELECT std_hire_date, std_last_name, std_sex, std_date_of_birth,
std_email_address, std_emp_status,
LPAD (std_employee_number, 8, '0') std_employee_number,
std_first_name, std_marital_status, std_middle_names,
std_nationality, std_title, std_national_identifier,
std_address_line1, std_address_line2, std_address_line3,
std_address_line4, std_post_code, std_telephone_1, std_country,
std_region, std_location_id, std_organization_id,
std_supervisor_id, std_person_id, std_position_id
FROM SU_TEMPLOYEE_DETAILS;
-- Get EXISTING employee details info from ORACLE tables
CURSOR get_existing_employee_details
IS
SELECT per.person_id, per.business_group_id, per.last_name,
per.start_date, per.date_of_birth, per.email_address,
per.employee_number, per.first_name, per.marital_status,
per.middle_names, per.nationality, per.national_identifier,
per.sex, per.title, padd.address_id, padd.primary_flag,
padd.address_line1, padd.address_line2, padd.address_line3,
padd.town_or_city, padd.postal_code, padd.telephone_number_1, paas.assignment_id,
paas.assignment_number, paas.object_version_number, paas.EFFECTIVE_START_DATE,
paas.job_id, paas.position_id, paas.location_id, paas.organization_id, paas.assignment_type, paas.supervisor_id,
paas.default_code_comb_id, paas.set_of_books_id, paas.period_of_service_id
FROM per_all_people_f per,
per_all_assignments_f paas,
per_addresses padd
WHERE
per.person_id = padd.person_id
-- AND paas.person_id(+) = per.person_id;
AND paas.person_id(+) = per.person_id;
-- checks employee details info from PER_ALL_PEOPLE_F table
CURSOR c_check_employee (p_emp_number VARCHAR2)
IS
SELECT per.person_id, per.business_group_id, per.last_name,
per.start_date, per.date_of_birth, per.email_address,
per.employee_number, per.first_name, per.marital_status,
per.middle_names, per.nationality, per.national_identifier,
per.sex, per.title, padd.address_id, padd.primary_flag,
padd.address_line1, padd.address_line2, padd.address_line3,
padd.town_or_city, padd.postal_code, padd.telephone_number_1, paas.assignment_id,
paas.assignment_number, paas.object_version_number, paas.EFFECTIVE_START_DATE,
paas.job_id, paas.position_id, paas.location_id, paas.organization_id, paas.assignment_type, paas.supervisor_id,
paas.default_code_comb_id, paas.set_of_books_id, paas.period_of_service_id
FROM per_all_people_f per,
per_all_assignments_f paas,
per_addresses padd
WHERE per.employee_number = p_emp_number
AND per.person_id = padd.person_id
AND paas.person_id(+) = per.person_id;
emp_rec c_check_employee%ROWTYPE;
-- Cursor retrieves latest Object Version Number from per_assignments_f table..
CURSOR csr_ovn (cp_person_id IN per_all_people_f.person_id%TYPE)
IS
SELECT MAX (paas.object_version_number)
FROM per_assignments_f paas, per_all_people_f per
WHERE paas.person_id = per.person_id
AND per.employee_number = paas.assignment_number
AND per.person_id = cp_person_id;
-- Cursor to get Oracle_Loc_Code from SU CHRIS vs ORACLE Locations Table into a variable..
CURSOR csr_ora_loc_code (cp_location_id IN SU_TEMPLOYEE_DETAILS.std_location_id%TYPE)
IS
SELECT sil.ORACLE_LOC_CODE
FROM SU_TEMPLOYEE_DETAILS std, SU_IEXP_LOCATIONS sil
WHERE std.STD_LOCATION_ID = sil.CHRIS_LOC_code
AND std.STD_LOCATION_ID = cp_location_id;
BEGIN
-- Process each record in the work table
FOR v_emp IN get_employee_details
LOOP
-- determine whether customer already exists
OPEN c_check_employee (v_emp.std_employee_number);
FETCH c_check_employee
INTO emp_rec;
l_assignment_id2 := emp_rec.assignment_id;
IF v_emp.std_emp_status = 'N' and c_check_employee%NOTFOUND
THEN
insert_flag := 'I';
DBMS_OUTPUT.PUT_LINE ('Employee No: ' || v_emp.std_employee_number);
ELSIF v_emp.std_emp_status = 'C'
THEN
-- if c_check_employee%NOTFOUND then raise no_data_found;
-- elsif l_assignment_id2 is null then
if l_assignment_id2 is null then
raise_application_error (-20010, 'Employee No: ' || v_emp.std_employee_number || ' exists but has no assignment id!');
end if;
DBMS_OUTPUT.PUT_LINE ('Employee No: ' || v_emp.std_employee_number || ' already exists, making changes.. ' );
insert_flag := 'C';
-- RAISE_APPLICATION_ERROR (-20001, 'Employee No: ' || v_emp.std_employee_number || ' already exists ' );
END IF;
CLOSE c_check_employee;
-- Obtain the most recent Object Version Number..
OPEN csr_ovn (v_emp.std_person_id);
FETCH csr_ovn
INTO l_obj;
-- IF csr_ovn%NOTFOUND THEN RAISE NO_DATA_FOUND; END IF;
CLOSE csr_ovn;
-- Open Oracle Location Code cursor
OPEN csr_ora_loc_code(v_emp.std_location_id);
FETCH csr_ora_loc_code
INTO v_ora_loc_code;
CLOSE csr_ora_loc_code;
-- Create new PER_ALL_PEOPLE_F and PER_ADDRESSES record from
-- info in table record
IF insert_flag = 'I'
THEN
-- -- Importing Employee Procedure --
Hr_Employee_Api.create_gb_employee
(p_validate => l_validate,
p_hire_date => l_employ_start_date,
p_business_group_id => l_std_business_group_id,
p_date_of_birth => v_emp.std_date_of_birth,
p_email_address => v_emp.std_email_address,
p_first_name => v_emp.std_first_name,
p_middle_names => v_emp.std_middle_names,
p_last_name => v_emp.std_last_name,
p_sex => v_emp.std_sex,
p_ni_number => v_emp.std_national_identifier,
p_employee_number => v_emp.std_employee_number,
p_person_id => l_person_id,
p_title => v_emp.std_title,
p_assignment_id => l_assignment_id,
p_per_object_version_number => l_per_object_version_number,
p_asg_object_version_number => l_asg_object_version_number,
p_per_effective_start_date => l_per_effective_start_date,
p_per_effective_end_date => l_per_effective_end_date,
p_full_name => l_full_name,
p_per_comment_id => l_per_comment_id,
p_assignment_sequence => l_assignment_sequence,
p_assignment_number => l_assignment_number,
p_name_combination_warning => l_name_combination_warning,
p_assign_payroll_warning => l_assign_payroll_warning
Hr_Person_Address_Api.create_person_address
(p_validate => l_validate,
-- p_effective_date => v_emp.std_hire_date,
p_effective_date => l_employ_start_date,
p_pradd_ovlapval_override => NULL,
p_validate_county => NULL,
p_person_id => l_person_id,
p_primary_flag => 'Y',
p_style => 'GB_GLB',
p_date_from => SYSDATE,
p_date_to => NULL,
p_address_type => NULL,
p_comments => NULL,
p_address_line1 => v_emp.std_address_line1,
p_address_line2 => v_emp.std_address_line2,
p_address_line3 => v_emp.std_address_line3,
p_town_or_city => v_emp.std_address_line4,
p_region_1 => NULL,
p_region_2 => NULL,
p_region_3 => NULL,
p_postal_code => v_emp.std_post_code,
p_country => v_emp.std_nationality,
p_telephone_number_1 => NULL,
p_telephone_number_2 => NULL,
p_telephone_number_3 => NULL,
p_party_id => ip_p_party_id,
p_address_id => ip_p_address_id,
p_object_version_number => l_obj
Hr_Assignment_Api.update_emp_asg
(p_validate => l_validate,
p_effective_date => SYSDATE, -- l_date,
p_datetrack_update_mode => l_datetrack_update_mode,
p_assignment_id => l_assignment_id,
p_object_version_number => l_obj,
p_supervisor_id => v_emp.std_supervisor_id,
p_default_code_comb_id => l_default_code_comb_id,
p_set_of_books_id => l_set_of_books_id,
p_concatenated_segments => l_concatenated_segments,
--IN/OUT
p_soft_coding_keyflex_id => l_soft_coding_keyflex_id,
--IN/OUT
p_comment_id => l_comment_id,
--IN/OUT
p_effective_start_date => l_date, --IN/OUT
p_effective_end_date => l_effective_end_date,
--IN/OUT
p_no_managers_warning => l_no_managers_warning,
--IN/OUT
p_other_manager_warning => l_other_manager_warning
--IN/OUT
Hr_Assignment_Api.update_emp_asg_criteria
(p_validate => l_validate,
p_effective_date => SYSDATE, -- l_date,
p_datetrack_update_mode => l_datetrack_update_mode,
p_assignment_id => l_assignment_id,
p_object_version_number => l_obj,
p_organization_id => l_organization_id,
p_location_id => v_ora_loc_code,
p_job_id => l_job_id,
p_position_id => v_emp.std_position_id,
p_special_ceiling_step_id => l_special_ceiling_step_id,
p_effective_start_date => l_date,
--per_effective_start_date,
p_effective_end_date => l_effective_end_date,
--IN/OUT
p_people_group_id => l_people_group_id,
--IN/OUT
p_group_name => l_group_name, --IN/OUT
p_org_now_no_manager_warning => l_org_now_no_manager_warning,
--IN/OUT
p_other_manager_warning => l_other_manager_warning,
--IN/OUT
p_spp_delete_warning => l_spp_delete_warning,
--IN/OUT
p_entries_changed_warning => l_entries_changed_warning,
--IN/OUT
p_tax_district_changed_warning => l_tax_district_changed_warning
--IN/OUT
v_rec_cnt := v_rec_cnt + 1;
DBMS_OUTPUT.PUT (CHR (10));
DBMS_OUTPUT.PUT_LINE ( 'There were '
|| v_rec_cnt
|| ' records read in..'
-- Updating PER_ALL_PEOPLE_F and PER_ADDRESSES record from
-- info in table record
ELSE IF insert_flag = 'C'
THEN
-- ===================================================
-- these next 6 lines is for the initial mass update of existing employee records only
-- ===================================================
/*IF emp_rec.default_code_comb_id is NULL THEN
l_default_code_comb_id = 218048;
END IF;
IF emp_rec.job_id is NULL THEN
l_job_id = 10;
END IF; */
-- =========
-- Section end
-- =========
Hr_Assignment_Api.update_emp_asg
(p_validate => l_validate,
p_effective_date => emp_rec.EFFECTIVE_START_DATE,
p_datetrack_update_mode => l_datetrack_update_mode,
p_assignment_id => l_assignment_id2,
p_object_version_number => l_obj,
p_supervisor_id => v_emp.std_supervisor_id,
p_default_code_comb_id => emp_rec.default_code_comb_id,
p_set_of_books_id => emp_rec.set_of_books_id,
p_concatenated_segments => l_concatenated_segments,
--IN/OUT
p_soft_coding_keyflex_id => l_soft_coding_keyflex_id,
--IN/OUT
p_comment_id => l_comment_id,
--IN/OUT
p_effective_start_date => l_date, --IN/OUT
p_effective_end_date => l_effective_end_date,
--IN/OUT
p_no_managers_warning => l_no_managers_warning,
--IN/OUT
p_other_manager_warning => l_other_manager_warning
--IN/OUT
Hr_Assignment_Api.update_emp_asg_criteria
(p_validate => l_validate,
p_effective_date => emp_rec.EFFECTIVE_START_DATE,
p_datetrack_update_mode => l_datetrack_update_mode,
p_assignment_id => l_assignment_id2,
p_object_version_number => l_obj,
p_organization_id => emp_rec.organization_id,
p_location_id => v_ora_loc_code,
p_job_id => emp_rec.job_id,
p_position_id => emp_rec.position_id,
p_special_ceiling_step_id => l_special_ceiling_step_id,
p_effective_start_date => emp_rec.EFFECTIVE_START_DATE,
p_effective_end_date => l_effective_end_date,
--IN/OUT
p_people_group_id => l_people_group_id,
--IN/OUT
p_group_name => l_group_name, --IN/OUT
p_org_now_no_manager_warning => l_org_now_no_manager_warning,
--IN/OUT
p_other_manager_warning => l_other_manager_warning,
--IN/OUT
p_spp_delete_warning => l_spp_delete_warning,
--IN/OUT
p_entries_changed_warning => l_entries_changed_warning,
--IN/OUT
p_tax_district_changed_warning => l_tax_district_changed_warning
--IN/OUT
v_rec_cnt := v_rec_cnt + 1;
DBMS_OUTPUT.PUT (CHR (10));
DBMS_OUTPUT.PUT_LINE ( 'There were '
|| v_rec_cnt
|| ' records read in..'
DBMS_OUTPUT.PUT (CHR (10));
-- End of customer related details
END IF;
END IF;
END LOOP;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
ROLLBACK;
err_num := TO_CHAR (SQLCODE);
err_msg := SUBSTR (SQLERRM, 1, 150);
err_line := 'ORACLE error occurred processing record.. ' || err_msg;
DBMS_OUTPUT.PUT_LINE (err_line);
INSERT INTO SU_ERROR_LOG VALUES (err_msg, 'TEMPLOYEE_DTLS.sql', SYSTIMESTAMP);
WHEN OTHERS
THEN
ROLLBACK;
err_num := TO_CHAR (SQLCODE);
err_msg := SUBSTR (SQLERRM, 1, 150);
err_line := 'ORACLE error occurred processing record.. ' || err_msg;
DBMS_OUTPUT.PUT_LINE (err_line);
INSERT INTO SU_ERROR_LOG VALUES (err_msg, 'TEMPLOYEE_DTLS.sql', SYSTIMESTAMP);
END;
EXIT;Many thanks
StevenIt looks like the Supervisor employee is not active for the duration of the Employee Record.
Using the correct Supervisor record should resolve the issue. -
My script says Obj Vers Number is blank - but it can't be!
hello.
And help.
I have below a script that includes several APIs to insert and update employees' details in ORACLE
Financials. It has been working fine until I've recently added the ' Hr_Person_Api.update_gb_person API'
After this, it throws up a ''ORACLE error occurred processing record.. ORA-20001: The mandatory
argument object_version_number value cannot be null..' message.
There is an entry in per_all_people_f the employee Im wanting to update which is collected by the CURSOR csr_ovn2. This is then opened (v_emp.std_employee_number) and FETCH'd INTO l_obj2 which is then put into the APIs. So why is it saying its blank?
Can someone please please read through the script and possibly offer a suggestion?
Many many thanks..
PLease find bellow relevant sections of my script..
p_emp_number VARCHAR2 (30);
l_obj2 NUMBER;
-- Cursor retrieves latest Object Version Number from per_all_people_f table..
CURSOR csr_ovn2 (p_person_emp_no IN per_all_people_f.employee_number%TYPE)
IS
SELECT MAX (per.object_version_number)
FROM per_all_people_f per
WHERE per.employee_number = p_person_emp_no;
-- Process each record in the work table
FOR v_emp IN get_employee_details
LOOP
-- Obtain the most recent EMPLOYEE's Object Version Number..
OPEN csr_ovn2 (v_emp.std_employee_number);
FETCH csr_ovn2
INTO l_obj2;
IF csr_ovn2%NOTFOUND
THEN
RAISE NO_DATA_FOUND;
END IF;
CLOSE csr_ovn2;
Hr_Person_Api.update_gb_person
(p_validate => l_validate,
p_effective_date => SYSDATE,
p_datetrack_update_mode => l_datetrack_update_mode,
p_person_id => emp_rec.person_id,
p_object_version_number => l_obj2,
p_last_name => v_emp.std_last_name..Try this
Change the cursor definition of csr_ovn2 to
CURSOR csr_ovn2 (p_person_id NUMBER,p_date DATE)
IS
SELECT per.object_version_number
FROM per_all_people_f per
WHERE per.person_id = p_person_id
AND p_date BETWEEN per.effective_start_date and per.effective_end_date
and call the cursor using
OPEN csr_ovn2(emp_rec.person_id,SYSDATE); -
'alias required in SELECT..' - Why can't I see this?
Please help I'm going mad here!
The error message is:
ERROR at line 1:
ORA-06550: line 113, column 37:
PLS-00402: alias required in SELECT list of cursor to avoid duplicate column
names
ORA-06550: line 113, column 37:
PL/SQL: Item ignored
ORA-06550: line 137, column 13:
PLS-00320: the declaration of the type of this expression is incomplete or
malformed
ORA-06550: line 136, column 7:
PL/SQL: SQL Statement ignored
..Yet I disagree.. I cant see any 2 fields called the same.
(FYI the cursor it speaks of is called 'c_check_employee').
And the code.
/* Formatted on 2009/02/27 15:35 (Formatter Plus v4.8.7) */
SET serveroutput ON SIZE 1000000 FORMAT WRAPPED
SET verify OFF
SET feedback OFF
DECLARE
-- Debugging/error handling
-- Work variables
p_emp_number VARCHAR2 (14);
v_rec_cnt NUMBER := 0;
insert_flag VARCHAR2 (8);
l_validate BOOLEAN DEFAULT FALSE;
l_obj NUMBER;
l_datetrack_update_mode VARCHAR2 (30) := 'CORRECTION';
l_assignment_sequence NUMBER;
l_name_combination_warning BOOLEAN := FALSE;
l_assign_payroll_warning BOOLEAN := FALSE;
l_org_now_no_manager_warning BOOLEAN;
l_other_manager_warning BOOLEAN;
l_spp_delete_warning BOOLEAN;
l_entries_changed_warning VARCHAR2 (30);
l_tax_district_changed_warning BOOLEAN;
l_person_id NUMBER;
l_assignment_id NUMBER;
l_special_ceiling_step_id NUMBER;
l_per_effective_end_date DATE
:= TO_DATE ('11-Jul-2049', 'DD-MON-YYYY');
l_people_group_id NUMBER;
l_group_name VARCHAR2 (30);
l_assignment_number VARCHAR2 (35);
l_effective_end_date DATE
:= TO_DATE ('11-Jul-2049', 'DD-MON-YYYY');
l_date DATE := SYSDATE;
ip_p_address_id per_addresses.address_id%TYPE;
ip_p_object_version_number NUMBER;
ip_p_party_id per_addresses.party_id%TYPE;
l_per_object_version_number NUMBER;
l_asg_object_version_number NUMBER;
l_full_name VARCHAR2 (240);
l_per_comment_id NUMBER;
l_per_effective_start_date DATE;
l_concatenated_segments VARCHAR2 (12);
l_soft_coding_keyflex_id NUMBER;
l_comment_id NUMBER;
l_no_managers_warning BOOLEAN;
-- Get employee details info from work table
CURSOR get_employee_details
IS
SELECT std_validate, std_person_id, std_assignment_id, std_hire_date,
std_business_group_id, std_last_name, std_sex,
std_date_of_birth, std_email_address, std_employee_number,
std_first_name, std_marital_status, std_middle_names,
std_nationality, std_title, std_national_identifier,
std_address_line1, std_address_line2, std_address_line3,
std_address_line4, std_post_code, std_telephone_1,
std_position_id, std_job_id, std_location_id,
std_organization_id, std_supervisor_id,
std_default_code_comb_id, std_set_of_books_id, std_payroll_id,
std_grade_id, std_pay_basis_id, std_assn_ovn
FROM SU_TEMPLOYEE_DETAILS;
-- checks employee details info from PER_ALL_PEOPLE_F table
CURSOR c_check_employee (p_emp_number VARCHAR2)
IS
SELECT paas.assignment_id, per.person_id, per.business_group_id,
per.last_name, per.start_date, per.date_of_birth, per.email_address,
per.employee_number, per.first_name, per.marital_status, per.middle_names,
per.nationality, per.national_identifier, per.sex, per.title, padd.address_id,
padd.primary_flag,padd.address_line1, padd.address_line2, padd.address_line3,
padd.town_or_city, padd.postal_code, padd.telephone_number_1, padd.telephone_number_2,
padd.telephone_number_3,paas.job_id, paas.location_id,paas.organization_id, paas.assignment_type, paas.primary_flag, paas.supervisor_id,paas.default_code_comb_id,
paas.set_of_books_id,paas.assignment_number, paas.period_of_service_id,paas.object_version_number
FROM per_all_people_f per,
per_all_assignments_f paas,
per_addresses padd
WHERE per.employee_number = p_emp_number
AND per.person_id = padd.person_id
AND paas.person_id(+) = per.person_id;
emp_rec c_check_employee%ROWTYPE;
-- Cursor retrieves latest Object Version Number from per_assignments_f table..
CURSOR csr_ovn (cp_person_id IN per_all_people_f.person_id%TYPE)
IS
SELECT MAX (paas.object_version_number)
FROM per_assignments_f paas, per_all_people_f per
WHERE paas.person_id = per.person_id
AND per.employee_number = paas.assignment_number
AND per.person_id = cp_person_id;
BEGIN
-- Process each record in the work table
FOR v_emp IN get_employee_details
LOOP
-- determine whether customer already exists
OPEN c_check_employee (v_emp.std_employee_number);
FETCH c_check_employee
INTO emp_rec;
IF c_check_employee%NOTFOUND
THEN
insert_flag := 'I';
ELSE
insert_flag := 'X';
END IF;
CLOSE c_check_employee;
-- Obtain the most recent Object Version Number..
OPEN csr_ovn (v_emp.std_person_id);
FETCH csr_ovn
INTO l_obj;
-- IF csr_ovn%NOTFOUND THEN RAISE NO_DATA_FOUND; END IF;
CLOSE csr_ovn;
-- Create new PER_ALL_PEOPLE_F and PER_ADDRESSES record from
-- info in table record
IF insert_flag = 'I'
THEN
BEGIN -- Importing Employee Procedure --
-- DBMS_OUTPUT.PUT (CHR (10));
-- DBMS_OUTPUT.PUT_LINE ('Importing employees.... ');
BEGIN
Hr_Employee_Api.create_gb_employee
(p_validate => l_validate,
p_hire_date => v_emp.std_hire_date,
p_business_group_id => v_emp.std_business_group_id,
p_date_of_birth => v_emp.std_date_of_birth,
p_email_address => v_emp.std_email_address,
p_first_name => v_emp.std_first_name,
p_middle_names => v_emp.std_middle_names,
p_last_name => v_emp.std_last_name,
p_sex => v_emp.std_sex,
p_ni_number => v_emp.std_national_identifier,
p_employee_number => v_emp.std_employee_number,
p_person_id => l_person_id,
p_title => v_emp.std_title,
p_assignment_id => l_assignment_id,
p_per_object_version_number => l_per_object_version_number,
p_asg_object_version_number => l_asg_object_version_number,
p_per_effective_start_date => l_per_effective_start_date,
p_per_effective_end_date => l_per_effective_end_date,
p_full_name => l_full_name,
p_per_comment_id => l_per_comment_id,
p_assignment_sequence => l_assignment_sequence,
p_assignment_number => l_assignment_number,
p_name_combination_warning => l_name_combination_warning,
p_assign_payroll_warning => l_assign_payroll_warning
Hr_Person_Address_Api.create_person_address
(p_validate => l_validate,
p_effective_date => v_emp.std_hire_date,
p_pradd_ovlapval_override => NULL,
p_validate_county => NULL,
p_person_id => l_person_id,
p_primary_flag => 'Y',
p_style => 'GB_GLB',
-- p_date_from => v_emp.std_hire_date,
p_date_from => SYSDATE,
p_date_to => NULL,
p_address_line1 => v_emp.std_address_line1,
p_address_line2 => v_emp.std_address_line2,
p_address_line3 => v_emp.std_address_line3,
p_town_or_city => v_emp.std_address_line4,
p_postal_code => v_emp.std_post_code,
p_country => v_emp.std_nationality,
p_telephone_number_1 => v_emp.std_telephone_1,
p_party_id => ip_p_party_id,
p_address_id => ip_p_address_id,
p_object_version_number => l_obj
--ip_p_object_version_number
Hr_Assignment_Api.update_emp_asg_criteria
(p_validate => l_validate,
p_effective_date => l_date, -- SYSDATE
p_datetrack_update_mode => l_datetrack_update_mode,
p_assignment_id => l_assignment_id,
p_object_version_number => l_obj,
p_organization_id => v_emp.std_organization_id,
p_location_id => v_emp.std_location_id,
p_job_id => v_emp.std_job_id,
p_position_id => v_emp.std_position_id,
p_special_ceiling_step_id => l_special_ceiling_step_id,
p_effective_start_date => l_date,
p_effective_end_date => l_effective_end_date, --IN/OUT
p_people_group_id => l_people_group_id, --IN/OUT
p_group_name => l_group_name, --IN/OUT
p_org_now_no_manager_warning => l_org_now_no_manager_warning, --IN/OUT
p_other_manager_warning => l_other_manager_warning, --IN/OUT
p_spp_delete_warning => l_spp_delete_warning, --IN/OUT
p_entries_changed_warning => l_entries_changed_warning, --IN/OUT
p_tax_district_changed_warning => l_tax_district_changed_warning --IN/OUT
Hr_Assignment_Api.update_emp_asg
(p_validate => l_validate, -- in
p_effective_date => l_date,
p_datetrack_update_mode => 'CORRECTION',
p_assignment_id => l_assignment_id,
p_object_version_number => l_obj,
p_supervisor_id => v_emp.std_supervisor_id,
p_default_code_comb_id => v_emp.std_default_code_comb_id,
p_set_of_books_id => v_emp.std_set_of_books_id,
p_concatenated_segments => l_concatenated_segments, -- out
p_soft_coding_keyflex_id => l_soft_coding_keyflex_id, -- out
p_comment_id => l_comment_id, -- out
p_effective_start_date => l_date, -- out
p_effective_end_date => l_effective_end_date,
p_no_managers_warning => l_no_managers_warning,
p_other_manager_warning => l_other_manager_warning
-- DBMS_OUTPUT.PUT_LINE ('Employee No:'|| v_emp.std_employee_number|| ' imported successfully..' );
EXCEPTION
WHEN OTHERS
THEN
RAISE NO_DATA_FOUND;
-- DBMS_OUTPUT.PUT (CHR (10));
DBMS_OUTPUT.PUT_LINE ( 'Ah, Employee:'
|| v_emp.std_employee_number
|| ' failed to load.. '
|| SQLERRM
-- DBMS_OUTPUT.PUT (CHR (10));
END;
END;
-- DBMS_OUTPUT.PUT (CHR (10));
v_rec_cnt := v_rec_cnt + 1;
-- DBMS_OUTPUT.PUT_LINE ( 'There were '|| v_rec_cnt|| ' records read in..');
-- End of customer related details
END IF;
END LOOP;
COMMIT;
END;
EXIT;
many thanks..Check primary_flag .... ;)
Regards.
Satyaki De.
Alex is Winner.... ;)
Edited by: Satyaki_De on Mar 2, 2009 5:33 PM -
Question on Logic of seperation in OOAbap-Selection screen
Hello guys
I like to ask you one question i found and get your ideas.
If you look at the codes for creating an ALV
it always recommends you to seperate logic and business layer etc..
this is the new way of creating an ALV
So you have a model view and a controller
I implemented that following useful resources.
So that there s class called view
and the selection screen gets called from there inside the method
like
call SELECTION-SCREEN 100.
IF sy-subrc EQ 0.
ENDIF.
But one issue when you execute the report and press GO BACK standard button it doesnot come back to your selection screen but way to your code.
Is there a get around to that?
here is the code below:
Header 1
*& Report ZZ_SOLEN_FIRST
REPORT ZZ_SOLEN_FIRST.
DATA: gv_vbeln type vbap-Vbeln.
***Screen
SELECTION-SCREEN: BEGIN OF SCREEN 100 TITLE t-004.
SELECTION-SCREEN: BEGIN OF block aa WITH FRAME TITLE t-001.
SELECT-OPTIONS: s_vbeln FOR gv_vbeln.
SELECTion-SCREEN: END OF block aa.
SELECTion-SCREEN: END OF SCREEN 100.
*****DATA Layer
class lcl_data DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ty_out,
vbeln type vbap-vbeln,
posnr type vbap-posnr,
matnr type vbap-matnr,
vkorg type vbak-vkorg,
END OF ty_out
TYPES: tt_out TYPE STANDARD TABLE OF ty_out.
TYPES: gr_vbeln TYPE RANGE OF vbap-vbeln.
DATA: gt_output TYPE tt_out.
methods: constructor,
select_data IMPORTING VALUE(rs_vbeln) TYPE gr_vbeln.
ENDclass.
class lcl_data IMPLEMENTATION.
method constructor.
clear GT_OUTPUT.
ENDMETHOD.
method select_data.
DATA: lt_vbak type SORTED TABLE OF vbak WITH UNIQUE KEY vbeln.
FIELD-SYMBOLS: <lfs_output> like LINE OF gt_output,
<lfs_vbak> like LINE OF lt_vbak
select vbeln posnr matnr from vbap
INto TABLE
GT_OUTPUT
where vbeln in S_VBELN
IF sy-SUBRC EQ 0.
select * from vbak
INTO TABLE lt_vbak
FOR ALL ENTRIES IN GT_OUTPUT
where vbeln = GT_OUTPUT-vbeln
LOOP AT gt_output ASSIGNING <lfs_output>.
READ TABLE lt_vbak ASSIGNING <lfs_vbak>
with TABLE KEY vbeln = <lfs_output>-vbeln.
IF sy-Subrc eq 0.
<lfs_output>-vkorg = <lfs_vbak>-VKORG.
ENDIF.
ENDLOOP.
ENDIF.
ENDMETHOD.
ENDCLASS.
****Display
class lcl_view DEFINITION.
PUBLIC SECTION.
methods: start RETURNING VALUE(rv_true) type abap_bool.
METHODS: display CHANGING it_data TYPE STANDARD TABLE.
ENDCLASS.
class lcl_view IMPLEMENTATION.
METHOD start.
call SELECTION-SCREEN 100.
IF sy-subrc EQ 0.
rv_true = abap_true.
ENDIF.
endmethod.
method display.
DATA: lo_salv_table type REF TO CL_SALV_TABLE,
lt_columns TYPE SALV_T_COLUMN_REF.
FIELD-SYMBOLS: <lfs_columns> like LINE OF lt_columns.
CL_SALV_TABLE=>FACTORY(
* exporting
* LIST_DISPLAY = IF_SALV_C_BOOL_SAP=>FALSE " ALV Displayed in List Mode
* R_CONTAINER = " Abstract Container for GUI Controls
* CONTAINER_NAME =
importing
R_SALV_TABLE = lo_salv_table " Basis Class Simple ALV Tables
changing
T_TABLE = it_data
* catch CX_SALV_MSG. " ALV: General Error Class with Message
lt_columns = lo_salv_table->GET_COLUMNS( )->GET( ).
* LOOP AT lt_columns ASSIGNING <lfs_columns>.
* break developer.
* ENDLOOP.
lo_salv_table->DISPLAY( ).
ENDMETHOD.
ENDCLASS.
class lcl_controller DEFINITION.
PUBLIC SECTION.
methods: main.
ENDCLASS.
class lcl_controller IMPLEMENTATION.
method main.
DATA: lo_view type REF TO lcl_view,
lo_data TYPE REF TO LCL_DATA .
CREATE OBJECT: lo_data, lo_view.
break developer.
IF lo_view->START( ) Eq abap_true.
**get the data
lo_data->SELECT_DATA( s_vbeln[] ).
lo_view->DISPLAY(
changing
IT_DATA = lo_data->GT_OUTPUT
ENDIF.
ENDMETHOD.
ENDCLASS.
INITIALIZATION.
START-OF-SELECTION.
break developer.
DATA: lo_controller type REF TO lcl_controller.
CREATE OBJECT lo_controller.
lo_controller->MAIN( ).Here is the complete code that works fine!!!
Thanks to your ideas:
OO ALV
*& Report ZZ_SOLEN_FIRST
REPORT ZZ_SOLEN_FIRST.
DATA: gv_vbeln type vbap-Vbeln.
***Screen
SELECTION-SCREEN: BEGIN OF SCREEN 100 TITLE t-004.
SELECTION-SCREEN: BEGIN OF block aa WITH FRAME TITLE t-001.
SELECT-OPTIONS: s_vbeln FOR gv_vbeln.
SELECTion-SCREEN: END OF block aa.
SELECTion-SCREEN: END OF SCREEN 100.
*****DATA Layer
class lcl_data DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ty_out,
vbeln type vbap-vbeln,
posnr type vbap-posnr,
matnr type vbap-matnr,
vkorg type vbak-vkorg,
END OF ty_out
TYPES: tt_out TYPE STANDARD TABLE OF ty_out.
TYPES: gr_vbeln TYPE RANGE OF vbap-vbeln.
DATA: gt_output TYPE tt_out.
methods: constructor,
select_data IMPORTING VALUE(rs_vbeln) TYPE gr_vbeln.
ENDclass.
class lcl_data IMPLEMENTATION.
method constructor.
clear GT_OUTPUT.
ENDMETHOD.
method select_data.
DATA: lt_vbak type SORTED TABLE OF vbak WITH UNIQUE KEY vbeln.
FIELD-SYMBOLS: <lfs_output> like LINE OF gt_output,
<lfs_vbak> like LINE OF lt_vbak
select vbeln posnr matnr from vbap
INto TABLE
GT_OUTPUT
where vbeln in S_VBELN
IF sy-SUBRC EQ 0.
select * from vbak
INTO TABLE lt_vbak
FOR ALL ENTRIES IN GT_OUTPUT
where vbeln = GT_OUTPUT-vbeln
LOOP AT gt_output ASSIGNING <lfs_output>.
READ TABLE lt_vbak ASSIGNING <lfs_vbak>
with TABLE KEY vbeln = <lfs_output>-vbeln.
IF sy-Subrc eq 0.
<lfs_output>-vkorg = <lfs_vbak>-VKORG.
ENDIF.
ENDLOOP.
ENDIF.
ENDMETHOD.
ENDCLASS.
****Display
class lcl_view DEFINITION.
PUBLIC SECTION.
methods: start RETURNING VALUE(rv_return_flag) type abap_bool.
METHODS: display CHANGING it_data TYPE STANDARD TABLE.
ENDCLASS.
class lcl_view IMPLEMENTATION.
METHOD start.
call SELECTION-SCREEN 100.
IF sy-subrc EQ 0.
rv_return_flag = abap_true.
ENDIF.
endmethod.
method display.
DATA: lo_salv_table type REF TO CL_SALV_TABLE,
lt_columns TYPE SALV_T_COLUMN_REF.
FIELD-SYMBOLS: <lfs_columns> like LINE OF lt_columns.
CL_SALV_TABLE=>FACTORY(
* exporting
* LIST_DISPLAY = IF_SALV_C_BOOL_SAP=>FALSE " ALV Displayed in List Mode
* R_CONTAINER = " Abstract Container for GUI Controls
* CONTAINER_NAME =
importing
R_SALV_TABLE = lo_salv_table " Basis Class Simple ALV Tables
changing
T_TABLE = it_data
* catch CX_SALV_MSG. " ALV: General Error Class with Message
lt_columns = lo_salv_table->GET_COLUMNS( )->GET( ).
* LOOP AT lt_columns ASSIGNING <lfs_columns>.
* break developer.
* ENDLOOP.
lo_salv_table->DISPLAY( ).
ENDMETHOD.
ENDCLASS.
class lcl_controller DEFINITION.
PUBLIC SECTION.
methods: main.
ENDCLASS.
class lcl_controller IMPLEMENTATION.
method main.
DATA: lo_view type REF TO lcl_view,
lo_data TYPE REF TO LCL_DATA .
CREATE OBJECT: lo_data, lo_view.
break developer.
* while lo_view->START( ) eq abap_true.
***get the data
* lo_data->SELECT_DATA( s_vbeln[] ).
* lo_view->DISPLAY(
* changing
* IT_DATA = lo_data->GT_OUTPUT
* ENDWHILE.
do.
if lo_view->START( ) eq abap_true.
***get the data
lo_data->SELECT_DATA( s_vbeln[] ).
lo_view->DISPLAY(
changing
IT_DATA = lo_data->GT_OUTPUT
else.
return.
ENDIF.
ENDDO.
ENDMETHOD.
ENDCLASS.
class lcl_test_submit DEFINITION.
PUBLIC SECTION.
TYPES: tr_vbeln TYPE RANGE OF vbap-vbeln.
data: lt_list type table_abaplist.
methods: test_submit IMPORTING VALUE(ir_vbeln) type tr_vbeln
EXCEPTIONS submit_failed
no_data_found
ENDCLASS.
class lcl_test_submit IMPLEMENTATION.
method test_submit.
submit ZZ_SOLEN_FIRST
with s_vbeln in ir_vbeln
exporting list to memory and return
***Get the list from the memory
call function 'LIST_FROM_MEMORY'
tables
listobject = lt_list
exceptions
not_found = 1
others = 2.
if sy-subrc <> 0.
raise submit_failed.
endif.
if lt_list is initial.
raise no_data_found.
endif.
ENDMETHOD.
ENDCLASS.
INITIALIZATION.
START-OF-SELECTION.
break developer.
DATA: lo_controller type REF TO lcl_controller.
****Testing the Main
CREATE OBJECT lo_controller.
lo_controller->MAIN( ). -
Dbms_scheduler job finihed succesfull when underlying procedure fails
I have a job created with dbms_scheduler which finishes succesfully even when the underlying plsql procedure raises a oracle error.
Is there any way to stop the running job with a failure when the plsql procedure fails and show the oracle error in the all_scheduler_job_run_details.error# column?
Example:
procedure test is
begin raise no_data_found;
end;
dbms_scheduler.create_job(job_name =>'MY_JOB', 'test');
dbms_scheduler.run_job;
when querying all_scheduler_job_run_details I want to see the no_data_found error which occurs in procedure.user4260036 wrote:
I have a job created with dbms_scheduler which finishes succesfully even when the underlying plsql procedure raises a oracle error.
Is there any way to stop the running job with a failure when the plsql procedure fails and show the oracle error in the all_scheduler_job_run_details.error# column?
what exactly does "stop the running job" mean?
when querying all_scheduler_job_run_details I want to see the no_data_found error which occurs in procedure.in which column do you expect/desire this information to reside?
SQL> desc all_scheduler_job_run_details
Name Null? Type
LOG_ID NUMBER
LOG_DATE TIMESTAMP(6) WITH TIME ZONE
OWNER VARCHAR2(30)
JOB_NAME VARCHAR2(65)
JOB_SUBNAME VARCHAR2(65)
STATUS VARCHAR2(30)
ERROR# NUMBER
REQ_START_DATE TIMESTAMP(6) WITH TIME ZONE
ACTUAL_START_DATE TIMESTAMP(6) WITH TIME ZONE
RUN_DURATION INTERVAL DAY(3) TO SECOND(0)
INSTANCE_ID NUMBER
SESSION_ID VARCHAR2(30)
SLAVE_PID VARCHAR2(30)
CPU_USED INTERVAL DAY(3) TO SECOND(2)
CREDENTIAL_OWNER VARCHAR2(65)
CREDENTIAL_NAME VARCHAR2(65)
DESTINATION_OWNER VARCHAR2(128)
DESTINATION VARCHAR2(128)
ADDITIONAL_INFO VARCHAR2(4000)
Maybe you are looking for
-
Does the third generation iPod Nano have allot of problems with it?
I was wondering if you think that there is an unusual ammount of defective iPod nanos, or iPod nanos with problems. I know that forums are mainly a support page, so I'm only going to see posts about PROBLEMS with the iPod, but i wanted some opinions.
-
Java.lang.NullPointerException returned from webservice
Hi I have an axis client which sends an image attachment to an axis webservice, however I am returned with a null pointer exception, this is my client, package chapter5; import java.net.URL; import org.apache.axis.client.Service; import org.apache.ax
-
Outbound Dialer records to cache. how does it work?????
Im confused, on the campaign manager one of the settings for the campaigns is Records to cache. The Outbound guide says that this is "the minimum number of dialing numbers that each dialer caches for each of your outbound option skill groups. Defau
-
"Missing initial moveto in path definition" displayed on console
Hello - I have an AreaChart using all default styles...nothing is being done from my end to it as far as css/styles. I see this message on the console "Missing initial moveto in path definition. Path: Path@fe315d[styleClass=chart-series-area-fill ser
-
Minimum Payment Value Setting at Vendor level?
Hi SAP Payments Gurus, I know that you can set a minimum outgoing payment level in FBZP config at the compnay code and payment method level....but is it possible to place a minimum payment level on a specific vendor? We have vendors accounts who have