SqlException has the property Number.
Then there is this: http://msdn.microsoft.com/en-us/library/cc645603.aspx
and this: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
And it seems to be one or the other
QUESTION:
How is it decided which?
REASON FOR ASKING:
I need to catch certain SqlExceptions and decide how to deal with them based on the Number property but I don't know which list I should look at when it seems like the system is using messages from both, and I don't know what criteria is used for choosing.
For example:
Number 53 - from server error message list (exists on both)
Number 10054 - from system error message list (exists on both)
Number -1 - from server error message list (exists only on server list)
Number 121 - from system error message list (exists on both)
......
The theory goes that it's the SQL error number, eg. the server side ERROR_NUMBER(). In other words, the first list.
However there are a number of exceptions reported by SqlClient that occur on the client side, not on the server side. A typical example would be an error like failure to connect to the server, since you did not connect there is no server side error to speak of. For example a bad server name (does not resolve in DNS), in such cases the InnerException will point toward a Win32Exception with NativeErrorCode value of ERROR_BAD_NETPATH. In this case 53, the OS system error code, will be reported as SqlException error number.
Other cases the error reported by the SqlClient is a socket error, like an abrupt disconnect. Again, there is no 'server side' error to speak of, and the SqlException will wrap an InnerException of type SocketException (a subclass of Win32Error) with the NativeErrorCode of one of the well known WSA error numbers, like WSAECONNRESET. In this case the SqlException.ErrorNumber will be 10054, but it's the 10054 from the WSA range, not the 10054 from the SQL Server errors range. I know...
So what are you supposed to do? Make sure you check the InnerException, if it's a Win32Exception then the ErrorNumber is coming from a system error code (OS error). Otherwise it should be a SQL Server error number.
Oh, and then there is -1... I think that is reported by SqlClient itself (eg. some internal state errors) but I'm not sure.
I would look at the documentation for the SqlException.Number property.
This is what it says
This is a wrapper for the Number property of the first SqlError in the
Errors property. For more information on SQL Server engine errors, see
SQL Server Books Online.
Related
I set up the system first by
[old_path]=which('rdsamp');if(~isempty(old_path)) rmpath(old_path(1:end-8)); end
wfdb_url='http://physionet.org/physiotools/matlab/wfdb-app-matlab/wfdb-app-toolbox-0-9-3.zip';
[filestr,status] = urlwrite(wfdb_url,'wfdb-app-toolbox-0-9-3.zip');
unzip('wfdb-app-toolbox-0-9-3.zip');
cd mcode
addpath(pwd);savepath
I am trying to read databases from Physionet.
I have successfully reached one database mitdb by
[tm,sig]=rdsamp('mitdb/100',1)
but I want to reach the database ptbdb unsuccessfully by
[tm,sig]=rdsamp('ptbdb/100',1)
and get the error
Warning: Could not get signal information. Attempting to read signal without buffering.
> In rdsamp at 107
Error: Cannot convert to double:
init: can't open header for record ptbdb/100
Error using rdsamp (line 145)
Java exception occurred:
java.lang.NumberFormatException: Cannot convert
at org.physionet.wfdb.Wfdbexec.execToDoubleArray(Unknown Source)
The first error message refers to these lines in rdsamp.m:
if(isempty(N))
[siginfo,~]=wfdbdesc(recordName);
if(~isempty(siginfo))
N=siginfo(1).LengthSamples;
else
warning('Could not get signal information. Attempting to read signal without buffering.')
end
end
This line if(~isempty(siginfo)) is false means that the siginfo is empty that is there is no signal. Why? No access to the database, I think.
I think other errors follow from it.
So the error must follow from this line
[siginfo,~]=wfdbdesc(recordName);
What does the snake mean here in the brackets?
How can you get data from ptbdb by Matlab?
So
Does this error mean that the connection cannot be established to the database?
or
that there does not exists such data in the database?
It would be very nice to know how you can check if you have connection to the database like in Postrgres. It would be much easier to debug.
If you run physionetdb("ptdb",1) it will download the files to your computer. You will then be able to see the available records in the <current-dir>/ptdb/
Source: physionetdb function documentation. You are interested in the DoBatchDownload parameter.
After downloading it, I believe every command from the toolbox will check if you have the files locally before fetching from the server (as long as you give the function the correct path to the local files).
The problem is that the data unit "100" does not exist in the database ptbdb.
I run finally successfully after waiting 35 minutes with 100Mb cable broadband:
db_list = physionetdb('ptbdb')
and get not complete data finally to the patient 54 - there should be 294 patients.
'ptbdb/patient001/s0014lre' 'ptbdb/patient001/s0014lre' ... cut ...
The main developer, Ikaro's' answer helped me to wait so long:
The WFDB Toolbox connects to PhysioNet's file server. The databases
accessible through the WFDB Toolbox are not SQL database, they consist
of flat files. The error message that you are getting regarding the
ptdb/100 database is because you are attempting to get a record that
does not exist on the database.
For more information on a particular database or record in PhysioNet
please type:
help physionetdb
and
physionetdb('ptdb')
This flat file system is really a bottle neck in the system.
It would be a good time to change to SQL.
I'm using Delphi-XE2 Enterprise, SQLServer 2008 R2 on Windows Server 2008 R2. When a SQL error is raised, the DataSnap server captures it and returns it to the client application. This all works, except the error message it truncated to 256 characters.
A stack track of the DataSnap server when the error is raised shows the SQL error message is truncated when the SQL DB Error is retrieved through the DBX Framework using the [file:Data.DBXDynalink]TDBXMethodTable.RaiseError() method. The following line of code from the RaiseError() method sets the MessageLength to 256, even when the error message is longer. Thus the error message returned to the client is never longer than 256 characters.
Status := FDBXBase_GetErrorMessageLength(DBXHandle, DBXResult, MessageLength);
FDBXBase_GetErrorMessageLength is of type TDBXCommon_GetErrorMessageLength, which is defined as:
TDBXCommon_GetErrorMessageLength = function(Handle: TDBXCommonHandle; LastErrorCode: TDBXErrorCode; out ErrorLen: TInt32): TDBXErrorCode; stdcall;
Is there a way to increase the buffer size to allow more of the database error to be sent to the client (e.g., 512 characters), or is this just a limitation of the DBX Framework?
#Sertac found a very similar problem that Carlos had with a driver truncating the error messages. Carlos found that changing the midas.dll to increase the error buffersize fixed his problem. I'm sure the solution is the same for my issue.
Thanks #Sertac for providing the link to Carlos' question:
Reconcile Error: Has anyone had problems with truncated error messages?
I seem to be experiencing a strange issue when using the SqlErrText from a DataWindow in our application.
The DataWindow executes a stored procedure, lets call it vp_ut_storedProc, and in my case it throws an error when the DataWindow is updated.
When I go into the function to build the error message for our application, the SqlErrText is passed in as follows (as parameter asErrText):
SQLSTATE = 42000
Microsoft SQL Server Native Client 10.0
TimestampNV|Someone Has Updated the Record. Please Refresh.
No changes made to the database
execute dbo.vp_ut_storedProc
I know that PowerBuilder receives the entire error text which is a good thing. But, when we try to save the error text into a local variable
isErrText = asErrText
The value of isErrText is: SQLSTATE = 42000
So, for some reason, it completely ignores everything after the second line. I figure it has something to do with the way the PowerBuilder is reading in the string, but I don't know why this happens.
I should also note that it's not just limited to this one DataWindow. It happens on quite a few of them.
put this in your dberror event of your datawindow
string s_temp
long l_start, l_end
l_start = 42 +Pos(sqlerrtext,'Microsoft SQL Server Native Client 10.0')
l_end = Pos(sqlerrtext,sqlsyntax) - l_start - 3
IF l_end <=0 THEN l_end = Len(sqlerrtext) - l_start
s_temp = Mid(sqlerrtext,l_start,l_end)
fw_msg(s_temp) //can write this at messagebox(this.title,s_temp) // instead
RETURN 1
if its insert or select error. it ignores the syntax and outputs the error. if its a different error. it shows the rest of the errcode
i'm trying to trap a "timeout expired" error from ADO.
When a timeout happens, ADO returns:
Number: 0x80040E31 (DB_E_ABORTLIMITREACHED in oledberr.h)
SQLState: HYT00
NativeError: 0
The NativeError of zero makes sense, since the timeout is not a function of the database engine (i.e. SQL Server), but of ADO's internal timeout mechanism.
The Number (i.e. the COM hresult) looks useful, but the definition of DB_E_ABORTLIMITREACHED in oledberr.h says:
Execution stopped because a resource limit was reached. No results were returned.
This error could apply to things besides "timeout expired" (some potentially server-side), such as a governor that limits:
CPU usage
I/O reads/writes
network bandwidth
and stops a query.
The final useful piece is SQLState, which is a database-independent error code system. Unfortunately the only reference for SQLState error codes i can find have no mention of HYT00.
What to do?
What do do?
Note: i can't trust
0x80040E31 (DB_E_ABORTLIMITREACHED)
to mean "timeout expired", anymore than i could trust
0x80004005 (E_UNSPECIFIED_ERROR)
to mean "Transaction was deadlocked on lock resources with another process and has been chosen as the deadlock victim".
My pseudo-question becomes: does anyone have documentation on what the SQLState "HYT000" means?
And my real question still remains: How can i specifically trap an ADO timeout expired exception thrown by ADO?
Gotta love the questions where the developer is trying to "do the right thing", but nobody knows how to do the right thing. Also gotta love how googling for DB_E_ABORTLIMITREACHED and this question is #9, with MSDN nowhere to be found.
Update 3
From the OLEdb ICommand.Execute reference:
DB_E_ABORTLIMITREACHED
Execution has been aborted because a resource limit has been reached. For example, a query timed out. No results have been returned.
"For example", meaning not an exhaustive list.
Update Three
Found it. Answer applied as answer.
You can safely use HYT00 to mean "Timeout expired". The following comes from Microsoft's SQLSTATEs reference. It mentions the HYT00 SQLSTATE:
The following SQLSTATEs indicate run-time errors or warnings and are good candidates on which to base programming logic. However, there is no guarantee that all drivers return them.
01004 (Data truncated)
01S02 (Option value changed)
HY008 (Operation canceled)
HYC00 (Optional feature not implemented)
HYT00 (Timeout expired)
Which then links to Appendix A: ODBC Error Codes of the ODBC Programmer's Reference, which documents the SQLSTATE values:
HYT00 Timeout expired, and interestingly also
HYT01 Connection timeout expired
So you can use HYT00 for "Timeout expired".
Is it not just -2 or is it too obvious?
You can generate this in both SSMS and from Ado.net and we use this to decide whether to retry.
Old SO Question and a link and MSDN
I have an exception handler for the type SqlException and I'm looking at the SqlException.Number property of the exception to determine if a dead-lock occurred (1205). I'm currious, instead of writing SqlException.Number == 1205, is there an enum I can refer to that would produce something similar to SqlException.Number == SqlExceptionNumberEnum.DeadLockVictim?
It may not be feasible due to the shear volume of potential error messages/numbers but thought it was worth asking. Thanks!
Not that I know of. In particular, you can define your own error numbers with sp_addmessage, and the errors change (grow) per SQL-Server version, so it would quickly be a problem if (for example) you were using .NET 2.0 with SQL Server 2008, as your numbers would exist.
Unfortunately I don't think this is feasible. If you run the following query,
select * from sys.messages where language_id=1033 and severity between 11 and 16
it produces over six thousand rows. You could write a small app to parse the table and produce a C# class with const properties representing each message, but it's probably not worth the effort.