SQL Catching a warning thrown by remote procedure - sql

I have an issue where I call a stored procedure from a linked server and it times out. However I have no good way of catching this. Though it occurs rarely I am wondering if there is any way to catch this particular warning:
OLE DB provider "SQLNCLI10" for linked server "serverName" returned message "Query timeout expired".
Unfortunatly warnings aren't caught by try/catch and MS does have an open issue that this should be an error: http://connect.microsoft.com/SQLServer/feedback/details/337043/no-error-raised-when-a-remote-procedure-times-out
I don't want to increase the timeout property, and I know I can do something like:
Declare #ret int
select #ret = 4417
Exec #ret=Server.DB.dbo.RemoteSP
If #ret is null afterwards it means the call failed, however it does not tell me exactly what the cause was. Is there anyway to essentially catch that warning? What are the best practices in for remote procedure calls error handling?

As of 2019 there is still no way to properly catch SQL Server remote timeout errors.
It applies both to remote SP calls and constructs like execute ('select 1') at REMOTESQLSERVER.
As per comment from N.Nelu:
Microsoft docs state under "Errors Unaffected by a TRY...CATCH Construct".
Errors Unaffected by a TRY...CATCH Construct
TRY...CATCH constructs do not trap the following conditions:
Warnings or informational messages that have a severity of 10 or
lower.
Errors that have a severity of 20 or higher that stop the SQL Server Database Engine task processing for the session. If an error
occurs that has severity of 20 or higher and the database connection
is not disrupted, TRY...CATCH will handle the error.
Attentions, such as client-interrupt requests or broken client connections.
When the session is ended by a system administrator by using the KILL statement.
Connect link you have provided is dead but you still can vote to fix this feature here. See also this excellent article on SQL Error handling under 4.3 Query Timeout on Linked Servers.

Related

What causes the "procedure has not been executed or has no result" error and how to prevent it?

Recently we are getting the "procedure has not been executed or has no result" across our PowerBuilder Application. This error is random, but is triggered in places where we have calls to Stored Procedures or some dynamic SQL queries. After each call to the procedure, we close the procedure in powerbuilder. We need to know the cause of this error because this is not caused on our environment, only in the production environment. Even better would be a way to resolve this issue.
The database is SQL Server. The exact error details are as follows:
ERROR Code: -1
ERROR Text: procedure has not been executed or has no result
Row Count: 0
Terminating application-
I am not even sure if the error is from Database or from Powerbuilder itself. The code is a simple call to a procedure. Here is some code that is causing this issue:
DECLARE setRequestStatus PROCEDURE FOR sRequestStatus
// parameters here
USING SQLCA;
EXECUTE setRequestStatus;
FETCH setRequestStatus into :statusCode;
CLOSE sp_PfW_ERxSetRequestStatus;
RETURN statusCode
Do reply if you need any more details.
Thanks in advance!
According to this post, the problem is an exception being raised by your stored procedure-- possibly due to transaction size. Follow the link to get more details.

ORA-02048 - Attempt to begin distributed transaction without loggin on

anyone know something about this error?
ORA-02048: attempt to begin distributed transaction without logging on
ORA-02063: preceding line from ..dblink
It occurs when I invoke since Java a PL/SQL Package that contains dblinks to access to other database for insert data. The dblink works good with other clauses, but not in this Package.
If I invoke this PL/SQL Package since TOAD, it works good.
I'm trying to reproduce this error, and I see this error arises from a pattern:
When I click the button which makes the PL run, the log shows me an error "ora-02292 integrity constraint child record found", and the next time I click the button, appears the error "ORA-02048", it is like the first error did lose the connection with remote database.
Thanks in advance
Without seeing a minimal testcase that demonstrates the problem, it's impossible to say.
However, looking up the error message:
-bash-4.1$ oerr ora 2048
02048, 00000, "attempt to begin distributed transaction without logging on"
// *Cause: client program must issue a distributed transaction login.
// *Action: contact support.
So, I'd recommend contacting Oracle support and opening an SR. But, the first thing they're likely to ask for is a working test case that demonstrates the problem.
The problem was thatI have different procedures, like that:
procedure1 -> (call) -> procedure 2 -> (call) -> procedure3
In procedure3 I have a clausure with dblink that insert into a remote table.
Procedure1 catchs the exceptions that may occur in procedure 2 and procedure3.
The problem is when an exception is throw in procedure3. In this case the rollback placed in the exception catch of procedure1, should finish the transaction, but it isn't working as I expected. The transaction is this case remains open and the second time in the procedure executions, oracle shows me the ORA-02048 error.
The solution was moving the exception catch into procedure3.

Can SQL Server automatically log stored procedure errors

I have a database that I am working on with over 900 SP's. None of the SP's have any error handling. Is there a utility within SQL Server 2005 or 2008 that would automatically log the SP and the error into a table?
If the SPs are being called from code in a separate data layer, you could possibly add a global exception handler for that class. There is no 'global' error handling, per-se in sql server as far as stored procedures go - think about code - in code, if you had a gazillion classes, and there was no ineritance of any sort, you would have to implement error handling on each class separately. Sql server SPs have their own error handling, such as try-catch and ##error - look on books online, or http://www.codeproject.com/KB/database/ErrorHandling.aspx

SQL Server Query log for failed/incorrect queries?

I am using SQL Server 2008 and I would like to know if there's a way to find invalid SQL queries that have been executed in a database. For example:
SELECT * FROM NonExistingTable
...where the database didn't exist or a SELECT/INSERT/UPDATE with incorrect syntax.
SQL Server doesn't keep a log of these things, so if you want to capture them you'll have to do so using a server-side trace with a filter to only capture statements with errors. It will be quite an expensive trace, and you'll get some false positives if you do things like RAISERROR WITH NOWAIT... I guess it's easier than implementing TRY/CATCH everywhere and logging the errors yourself?
There may be ways to do it with SQL Server Audit (depending on your edition)
or Extended Events but I haven't tried to do this specific thing with either...
Logging of the message 229 severity 14 would definitely help you identify when these errors take place.
SELECT * FROM master.sys.messages
WHERE language_id=1033
AND severity=14
AND message_id=229;
You can enable it by using:
EXEC sp_altermessage 229, 'WITH_LOG', 'true';
I'd create an alert on Severity 14 errors to be notified when they happen, for that you'd need to set an operator too.
The only limitation that this has is that it does not give you the login, host name or IP address of the session that had the error. It does log the SPID and you'd have to retrieve it by using EXEC xp_readerrorlog by using something like
EXEC xp_readerrorlog 0,1,'permission',NULL,NULL,NULL,'desc'
or opening it on SSMS and then correlate it with what you find on sysprocesses using
SELECT * FROM master.dbo.sysprocesses WHERE SPID='LoggedSPID'
You can enable the logging of other messages you may want to be aware of, for this purpose, primarily dig on severity 14 and enable as needed.
SELECT * FROM master.sys.messages
WHERE language_id=1033
AND severity=14;

How to get inner errors from try/catch clause in SQL Server

I am running a stored procedure in SQL Server 2008 inside a try/catch. The stored procedure and the stored procs it calls raise a few errors but in the try/catch you only get the last error from the stored procedure that you are running.
Is there a way/trick to be able to somehow catch ALL the errors generated by child stored proc calls while running a particular stored procedure? (assume that you have no access to any stored procedures so you can't modify where they can write the error, i.e. you can't just change all the stored procedures to stop raising errors and instead write them to some table and in your catch read from that table)
Here is a good resource for how to deal with error handling in SQL Server.
http://www.sqlservercentral.com/articles/Development/anerrorhandlingtemplatefor2005/2295/
However, some of the methods require that you have the ability to change the code in order to capture the errors. There is really no way of getting around this. You can't just ignore the error, keep processing, and then come around later to deal with the error. In most, if not all, languages, exceptions have to be dealt with at the time the exception was raised. T-SQL is no different.
I personally use a stored procedure to log any error whenever it occurs. Here is what I use:
CREATE PROCEDURE [dbo].[Error_Handler]
#returnMessage bit = 'False'
WITH EXEC AS CALLER
AS
BEGIN
INSERT INTO Errors (Number,Severity,State,[Procedure],Line,[Message])
VALUES (
ERROR_NUMBER(),
ERROR_SEVERITY(),
ERROR_STATE(),
isnull(ERROR_PROCEDURE(),'Ad-Hoc Query'),
isnull(ERROR_LINE(),0),
ERROR_MESSAGE())
IF(#returnMessage = 'True')
BEGIN
select Number,Severity,State,[Procedure],Line,[Message]
from Errors
where ErrorID = scope_identity()
END
END
If you have stored procs that are raising more than one error, they need to be replaced no matter what. You probably have data integrity errors in your database. That is a critical, "everything needs to stop right now until this is fixed" kind of issue. If you can't replace them and they were incorrectly written to allow processing to continue when an error was reached, then I know of no way to find the errors. Errors are not recorded unless you tell them to be recorded. If the stored procs belong to a product you bought from another vendor and that's why you can't change them, your best bet is to change to a vendor that actually understands how to program database code because there is no salvaging a product written that badly.
You wouldn't have a Java or c# methods raising error after error. Why do you expect SQL to allow this? An exception is an exception
If the DB Engine is throwing errors then you have problems.
What I've done before is to separate testing and checking code: find out what is wronf first and throw one exception If no errors, do your writes.