Can not catch error in merge statement - vb.net

Hi I have problem to catch the error in merge statement.
The merge statement will get the following error when run in SQL Plus:
ORA-00932: inconsistent datatypes: expected DATE got NUMBER
When I execute the statement with ExecuteNonQuery in Vb.net will not get any exception.
Is there any way to catch that error in Vb.net without using log errors in merge statement?
EDIT:
Try
Dim count as Interger=0
Dim cmd As New OleDb.OleDbCommand(strSQL)
count = cmd .ExecuteNonQuery()
Catch ex as Exception
... Respond ...
End Try
Sample Merge Statement with error:
MERGE INTO TABLE_A a USING
(
SELECT ID,SUM(AMOUNT) AMOUNT
FROM TABLE_B b
GROUP BY ID
) b
ON ( b.ID=a.ID )
WHEN MATCHED THEN
UPDATE SET a.AMOUNT=a.AMOUNT+b.AMOUNT
WHEN NOT MATCHED THEN
INSERT (ID, DT, AMOUNT) VALUES (b.ID, 0, b.AMOUNT);
The SQL Plus will get error at the insert but Vb.net can not catch.
The data type for field DT is DATE.

EDIT 3:
My bad - in that case, I think you'll have to subscribe to oleDbConnection.InfoMessage event and check for applicable SQL-00932 messages after the MERGE command. I don't see any equivalent property to FireInfoMessageEventOnUserErrors in OLE-DB (which, again, seems totally backwards...).
EDIT 2:
It appears there's a default threshold that will cause vb.net to ignore certain SQL exceptions (can't fathom the rationale behind such a decision). Regardless, I think if you do the following, you should see the exception raised.
cmd.FireInfoMessageEventOnUserErrors = true;
End EDIT2
EDIT: I just read the problem a bit closer. If the vb.net execution is not throwing any exception at all, that would indicate that you're not running the exact same statement in both. My initial guess is that you're passing a date parameter that is passing SQL Plus string variable incorrectly as 01/01/2015 (which is 1 divided by 1 divided by 2015) and vb.net variable correctly as '01/01/2015' (that is, as a string with quotation marks).
End EDIT
I have no idea what you mean by "using log errors in merge statement", but it sounds like you just need the syntax for using the vb.net try-catch syntax to catch and act on Oracle errors.
From here: http://www.tek-tips.com/viewthread.cfm?qid=467119
Pertinent code snippet:
Try
... Sql here ...
Catch ex as OleDbException
... Respond to error here ...
End Try

Related

make SQL query fail on condition

For XYZ reason I need a query to explicitly fail (return error code to connection) if some condition is met (on Snowflake).
Can someone recommend an approach?
Some illustration in pseudo-code:
IF 0= ( SELECT COUNT(*) FROM XYZ) THEN FAIL
I like Simeon's approach, but you may want a custom error message if this is running in a long script. Throwing an error in a JavaScript UDF will allow custom (if untidy) error messages:
create or replace function RAISE_ERROR(MESSAGE string)
returns string
language javascript
as
$$
throw "-->" + MESSAGE + "<--";
$$;
select
case (select count(*) from XYZ)
when 0 then raise_error('My custom error.')
else 'There are rows in the table'
end
;
If there are no rows in XYZ, it will generate an error message that reads:
JavaScript execution error: Uncaught --> My custom error <--. in RAISE_ERROR at '
throw MESSAGE;' position 4 stackstrace: RAISE_ERROR line: 2
It's not the tidiest of error messages, but it will allow you to embed a custom error message if you need help identifying the error. The arrows should help direct people to the real error message thrown in the stack.
SELECT IFF(true, 1::number, (1/0)::number);
then:
IFF(TRUE, 1::NUMBER, (1/0)::NUMBER)
1
where-as
SELECT IFF(false, 1::number, (1/0)::number);
gives:
Division by zero

SQL Contains: Query operators

I got a query working from long ago, the query is build by JPA, but today threw an exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [n/a]; SQL state [99999]; error code [29902]; could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
Long story short, it gives SQL state [99999]; error code [29902]; a parameter problem.
The query its build like this:
select * from mytable where CONTAINS(field1, 'BT');
A little google-fu show me that BT its a query operator for Contains. This error can be reproduced searching by NOT, DIFMERGE, ABOUT, AND..
The question is, there is a way to escape the text so i can search by the word BT or his friends?
EDIT: i build the contains like this:
return builder.greaterThan(
builder.function("CONTAINS", Integer.class, exp, builder.literal(((String) param.getValue()).toUpperCase())),
0);
EDIT: I tried converting the text BT to unicode, but doesn't work either.
select * from myTableWHERE CONTAINS(field1, UNISTR('\0042\0054')) > 0

Throwing a message to the user in SQL Server

I need to have a nested if statement in an update trigger. How do I say with an If statement in sql -- if two columns don't equal each other - throw an error message (don't shut down the system - just throw a message alerting the user).
If(#order_tot_paid_amt > 0) -- that means that the user has entered a value. (and its calculated)
I've reviewed a few of the existing posts, and they differ from what I am asking. Do I need a catch statement? (I know in c++ you need a catch statement otherwise things shut down).
What I have so far is (and I know I'm missing data).
IF (#order_tot_paid_amt > 0)
IF #order_tot_paid_amt <> (select pmt_rcvd_amt from LT_CHC_TOURS_RSV_CS where id_key = #id_key)
THROW ...
CATCH ...
I don't know where to get all the commands for throw and catch.

Inserting data into PostgreSQL table from MATLAB with JDBC throws BatchUpdateException

I am trying to write to a PostgreSQL database table from MATLAB. I have got the connection working using JDBC and created the table, but I am getting a BatchUpdateException when I try to insert a record.
The MATLAB query to insert the data is:
user_table = 'rm_user';
colNames = {user_id};
data = {longRecords(iterator)};
fastinsert(conn, user_table, colNames, data);
The exception says:
java.sql.BatchUpdateException: Batch entry 0 INSERT INTO rm_user (user_id) VALUES ( '4') was aborted. Call getNextException to see the cause.
But I don't know how to call getNextException from MATLAB.
Any ideas what's causing the problem or how I can find out more about the exception?
EDIT
Turns out I was looking at documentation for a newer version of MATLAB than mine. I have changed from fastinsert to insert and it is now working. However, I'm still interested in knowing if there is a way I could use getNextException from MATLAB.
This should work:
try
user_table = 'rm_user';
colNames = {user_id};
data = {longRecords(iterator)};
fastinsert(conn, user_table, colNames, data);
catch err
err.getNextException ()
end
Alternatively, just look at the caught error, it should contain the same information.
Also, Matlab has a function lasterr which will give you the last error without a catch statement. The function is deprecated, but you can find the documentation for replacements at the link provided.

SQL Try catch purpose unclear

Let's suppose I want to inform the application about what happened / returned the SQL server. Let's have this code block:
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() as ErrorState,
ERROR_PROCEDURE() as ErrorProcedure,
ERROR_LINE() as ErrorLine,
ERROR_MESSAGE() as ErrorMessage;
END CATCH;
GO
and Let's have this code block:
SELECT 1/0;
My question is:
Both return the division by zero error. What I don't understand clearly is that why I should surround it with the try catch clausule when I got that error in both cases ?
Isn't it true that this error will be in both cases propagated to the client application ?
Yes, the only reason for a Try Catch, (as in ordinary code) is if you can "Handle" the error, i.e., you can correct for the error and successfully complete whatever function the procedure was tasked to do, or, if want to do something with the error before returning it to the client (like modify the message, or store it in an error log table or send someone an email, etc. (althought i'd prefer to do most of those things from the DAL layer )
Technically, however, the catch clause is not returning an error. it is just returning a resultset with error information. This is very different, as it will not cause an exception in client code. This is why your conclusion is correct, ou should just let the original error propagate directly back to the client code.
As you have written it, no error will be returned to the client. As in ordinary code, if you do not handle (correct for) the error in a catch clause, you should always rethrow it (in sql that means Raiserror function) in a catch clause. What you have done above, in general is bad, the client code may or may not have any capability to properly deal with
a completely different recordset (one with error info) from what it was expecting. Some calls (like Inserts updates or deletes) may not be expecting or looking for a returned recordset at all... Instead, if you want or need to do something with the error in the procedure before returning it to the client, use Raiserror() function
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Other code to do logging, whatever ...
Raiserror(ERROR_MESSAGE(), ERROR_NUMBER(), ERROR_STATE() )
END CATCH;
Both return the division by zero
error.
Yes, but using different return paths.
The difference is that in the first example, you are anticipating the error and dealing with it in some way. The error enters the application as a regular result - it is not propagated via the error handling mechanism. In fact, if the application doesn't look specifically as the shape of the result, then it may be unaware that an error has occurred.
In the second instance, the error will propagate to your application typically via an error reporting mechanism, such as an exception. This will abort the operation. How big an impact this has will depend upon the application's exception handling. Maybe it will abort just the current operation, or the entire app may fail, depending upon the app's design and tolerance to exceptions.
You choose what makes sense for your application. Can the app meaningfully handle the error - if so, propagate the error (2nd example), or is it best handled in the query (1st example), with errors being "smoothed over" by returning default results, such as an empty rowset.
Try Catch is not as useful when all you have in the try portion is a select. However if you have a transaction with multiple steps, the catch block is used to roll all the steps back and possibly to record details about what caused the problem in a log. But the most important part is the rollback to ensure data integrity.
If you are creating dynamic SQl within the Try block, it is also helpful to log the dynamic SQl variable that failed and any parameters passed in. This can help resolve some hard-to-catch, "we don't have any idea what the user actually did to cause the problem" errors.
No, by executing Select 1/0 in a TRY/CATCH block the select statement returns nothing and the select statement in the catch block displays the error details gracefully. The query completes successfully - no errors are thrown.
If you run Select 1/0 on it's own the query does not complete successfully - it bombs out with an error.
Using a catch block within SQL gives you the chance to do something about it there and then not just let the error bubble up to the application.
The only reason you see the error details is because you are selecting them. If there was no code within the Catch block you wouldn't see any error information.
Using the first method, you wont get the error from SQL Server directly
The second method may stop the execution of the statements that follow it
So it is better you catch it in advance