Usually I have to insert some data in a DB and it can't be inserted because the table has constraints preventing me from doing that. With the app I'm developing, some business rules (like "there are not two persons with the same id type and number" or "the XXXX product is already registered") are enforced with UNIQUE or composite keys and other mechanisms. Although I know that DBMS throws an error message (like ORA-6346 or ) I do not know how to catch those errors in .net 4.0 and translate them to an error that can be meaningful for the business layer.
As an example: I've seen an insertion mechanism that asks the DB if the register already exists and then it proceeds to insert data if it isn't the case. I want to do this only using a query and catching the database constraint violation error because the first way seems to me as very inefficient (DB can alert you about duplication with an error).
How can I implement something like that?
Note: I think that it is possible to catch the exception from the database and use its ORA-xxxx code to try to figure out what has happened. I do not remember with precision if the error message shows which constraint (the name of...) has been broken, but business layer code can contain constants with the constraint names and, from them, know what has happened.
What you should do here depends really on the architecture of your system, and your attitude towards the placement of business logic.
Many systems architects prefer to use a database as a dumb data store, and implement the type of error handling and integrity checking you're talking about in the middle/application layer. This is a perfectly valid approach, and is particularly suited to systems requiring regular smaller releases, where the business logic is subject to regular change (its much easier to redistribute an executable midweek than to co-ordinate a database release), and where the data model is fairly simple.
The other approach is to put some well-defined semi-permanent business logic into the database layer. This is particularly powerful when the data model is more complex, and you have a good DBA! ;)
My personal opinion is, an enterprise database should be responsible for its own integrity, and so I prefer to have logic in the database layer to ensure this - removing any vulnerability to bugs being introduced in non-database code releases. So in your specific example, I would definitely catch the error and report it meaningfully to your application layer.
Oracle supports catching various types of error using names exceptions, allowing you to raise these exceptions to your applications in a meaningful way. For example:
PROCEDURE test() AS
b VARCHAR2;
BEGIN
-- if the following row exists, then DUP_VAL_ON_INDEX will be thrown
-- (assuming there is a primary key constraint)
INSERT INTO table(a,b,c)
VALUES(1,2,3);
-- if there is no matching record, NO_DATA_FOUND will be thrown
SELECT a
INTO b
FROM TABLE
WHERE c = 'blah';
EXCEPTION -- both types of exception can be caught and embellished
WHEN DUP_VAL_ON_INDEX THEN
raise_application_error(-20570, 'Attempted to insert a duplicate value', TRUE);
WHEN NO_DATA_FOUND THEN
raise_application_error(-20571, 'No matching row in table for value:' || 'blah', TRUE);
WHEN OTHERS THEN
rollback
END test;
You can find more information here: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/errors.htm
Hope this helps..
There's a couple of approaches, here's broadly what I would do:
I agree with Mellamokb that error handling can be done within the stored proc but that doesn't exactly fit with your scenario as you specifically want to provide something that the business layer understands - which by definition the data layer should never know.
For #2, the MS Enterprise Libraries have an error handling block which (I think) allows you to that sort of thing through config; or if not it might get you close.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With