Script to Retrieve All Error Numbers and Messages from the SQL Server Error Log
The undocumented function
xp_readerrorlog provides us the ability to read the SQL Server error log using T-SQL and
perform some basic text searches, but this function is very limited. For example,
if we want to retrieve the error number and related message, since they are located
on different rows, and a text search won’t work on those cases.
First, let us see how any given error is stored in the error log, just doing
a simple check using SQL Server Management Studio of any error, you can see two
rows, first the error number and then the error message:
For this example, if we would like to obtain all the errors in the current error
log, we would use something like this, by filtering the text:
--- Filter all events with the word 'Error' in the text EXEC master.dbo.xp_readerrorlog 0, 1,"Error", null, null, null
and we obtain the following output:
As you can see, we only have the error numbers and that is not very descriptive
So now imagine that you want also the related error message, that is stored in
the next row after the error number, you must write some custom code to achieve
this. Check out this tip to see how this can be done.
Starting with SQL Server 2012, the
LAG() function was introduced
and it allows any query to access a row given an offset from the current row.
LAG() function and a temporary table, I will show you how
an error number and its related message can be retrieved.
How does the SQL Server LAG() Function work?
Basic syntax of the SQL Server LAG function is:
LAG (scalar_expression [,offset] [,default]) OVER ( [ partition_by_clause ] order_by_clause )
To be able to use this function, we first store all the error log output in a
temporary table, after that we apply the function with the table order by date,
to retrieve the very next row, that contains the error message.
This is just a part of the script, just to see where this function is used:
SELECT [date], [processinfo], [text] as [MessageText], LAG([text],1,'') OVER (ORDER BY [date]) as [error] FROM #ErrorLog
In this case, the OVER is an order by date, and we use an offset of 1, to obtain
the next row.
The empty string ” indicates to the function as a default value if no next row
Note that we use a temporary table #ErrorLog to be able to achieve
this, since we cannot perform it directly from the xp_readerrorlog
stored procedure output.
Using the full script
As we stated earlier, that SELECT statement was just a part of the script, at
a glance, the full script will do the following:
- Declare variables to use and assign them values, so we can parametrize it.
- Declare the temporary table to use.
- Inserting all the error log entries in the temporary table from the error
- Select from the temporary table the required values.
- Filter the results with the text we want. For this example, we will filter
all the entries with the text “error”.
- Drop the temporary table.
This is the full script to obtain the error numbers and messages:
DECLARE @ArchiveID INT ,@Filter1Text NVARCHAR(4000) ,@Filter2Text NVARCHAR(4000) ,@FirstEntry SMALLDATETIME ,@LastEntry SMALLDATETIME SELECT @ArchiveID = 0 ,@Filter1Text = '' ,@Filter2Text = '' -- this will only take the logs from the current day, --you can change the date ranges to suit your needs ,@FirstEntry = DATEADD(DAY, - 1, getdate()) ,@LastEntry = getdate() CREATE TABLE #ErrorLog ( [date] [datetime] NULL ,[processinfo] [varchar](2000) NOT NULL ,[text] [varchar](2000) NULL ) ON [PRIMARY] INSERT INTO #ErrorLog EXEC master.dbo.xp_readerrorlog @ArchiveID ,1 ,@Filter1Text ,@Filter2Text ,@FirstEntry ,@LastEntry ,N'asc' SELECT * FROM ( SELECT [date] ,[processinfo] ,[text] AS [MessageText] ,LAG([text], 1, '') OVER ( ORDER BY [date] ) AS [error] FROM #ErrorLog ) AS ErrTable WHERE [error] LIKE 'Error%' -- you can change the text to filter above. DROP TABLE #ErrorLog
Just run the above code and you will obtain output like this:
Now, if you filter the text by “error” you can obtain more information
about the error message related to the error.
Please note that at the beginning of the script there are some parameters that
are used, so for example if you have an automated process to retrieve this information,
you can filter it by date, since by default, we retrieve information just for the
Also, you can replace the temporary table information and use a permanent table,
so you can store this information for later analysis.
For the text to filter, additional messages you want to track can be included
as well or only to filter specific error numbers.
- Remember, the
LAG()function is available since SQL Server
2012, so this script won’t work prior to that version.
- You can check the LAG official documentation at the
- You can customize the query to make it run automatically and store the results
to any table. Also, you can put the date range to suit your needs.
- Note that some special error log events will require custom filtering, but
you can implement this custom filtering using the script provided as a base.
- In the SQL Server feature request site, I have submitted a request to include
a documented, more robust DMO to be able to query the error log via T-SQL, you
can support the feature
- Take a look at this tip as well
Simple way to find errors in SQL Server error log.
Last Update: 2018-08-10
About the author
Eduardo Pivaral is an MCSA, SQL Server Database Administrator and Developer with over 15 years experience working in large environments.
View all my tips