Programming4us
         
 
 
SQL Server

SQL Server 2008 : Implementing Error Handling - Managing and Raising User-Defined Errors

11/14/2010 4:27:08 PM
As mentioned, SQL Server allows you to create customized error messages and raise them inside your code. As a database developer, you should create a set list of additional messages for use by your application so you can reuse them inside your programmable objects. Also, user-defined errors can significantly improve readability of operations and problems that occur in your application. Remember that these user-defined error messages help you customize and standardize messages returned from the procedures, functions, and other programmable objects in your database. This feature also provides you with an efficient way to develop code with the reuse of the same messages.

System Procedures and Parameters

User-defined error messages can be managed with the use of three system procedures: sp_addmessage, sp_altermessage, and sp_dropmessage. The sp_addmessage procedure lets you store a user-defined error message in an instance. Remember that these messages can be viewed using the sys.messages catalog view. The syntax of this procedure is as follows:

sp_addmessage [ @msgnum = ] msg_id, [ @severity = ] severity,
[ @msgtext = ] 'msg'
[, [ @lang = ] 'language' ]
[, [ @with_log = ] { 'TRUE' | 'FALSE' } ]
[, [ @replace = ] 'replace' ]

When you compare the syntax of this procedure with the structure of the sys.messages catalog view, you can easily understand how to use it. The first parameter is the message ID number. For user-defined error messages, you can define an ID number as an integer between 50,001 and 2,147,483,647. As you saw in the sys.messages structure, the combination of this number and language must be unique. This parameter is mandatory.

The second parameter is severity level. The severity value must be an integer between 1 and 25. Keep in mind that you should choose the severity level of this customized error message according to SQL Server severity levels, easing maintenance, organization, and usability. This parameter is also mandatory.

The last mandatory input parameter is the text of the error message. This parameter accepts text in NVARCHAR(255) and supports arguments passed by RAISERROR statements. This ability to utilize arguments provides a flexible and rich use of user-defined error messages, including ways to show important information such as the login that executed the code that raised the error message.

One of the most interesting parameters of the sp_addmessage procedure is language. This optional input allows you to add the same message in different languages. SQL Server offers support for 33 languages, whose information is stored in the sys.syslanguages table. Languages supported by SQL Server include English (British and American), Portuguese, Spanish, Italian, and Japanese. Because multiple languages may be installed on the same server, this parameter specifies the language in which the message is written. If you don’t inform the input, the default language of the session is the assumed value of this parameter.

If you need to create an error that must write to the Windows application log, the @with_log parameter is the key. This parameter accepts TRUE or FALSE values. If you inform TRUE, your error will always be written to the Windows application log. If you inform FALSE, your user-defined error may still be written to the log depending on how the error is raised. An important feature of this parameter is that only members of the sysadmin server role can use it. Also, when an error is written to the Windows application log, it is also written to the Database Engine error log file.

The last parameter, replace, is used to update the message text, severity level, and log option of an existing error message. An interesting feature useful in multiple language environments is that when you replace a U.S. English message, the severity level is replicated for all messages in all other languages with the same ID number.

Another way to change the log option of a user-defined error is with the sp_altermessage procedure. Contrary to what the name suggests, this procedure doesn’t alter error messages: it just changes their log option value. The syntax of this procedure is as follows:

sp_altermessage [ @message_id = ] message_number, 'WITH_LOG', { 'TRUE'
| 'FALSE' }

This procedure is a straightforward statement: you only need to inform the message ID number and the WITH_LOG parameter value, which can be TRUE or FALSE. Like the WITH_LOG parameter in the sp_addmessage, this procedure can only be executed by members of the sysadmin server role.

You can drop a user-defined error using the sp_dropmessage procedure. The syntax of this procedure is as follows:

sp_dropmessage [ @msgnum = ] message_number
[, [ @lang = ] 'language' ]

By default, you only need to inform the ID number of the error message you want to drop. One cool thing about this procedure is the optional language parameter. You can drop a language version of an error message, while keeping the other languages versions intact. If you want to drop all language versions of a message, you need to specify the ALL value for the language parameter.

Configuring & Implementing...: Database Documentation

As a database developer, you should always document your database. Documentation describes all aspects of your solution and provides information that helps you manage, control, and update objects created such as tables, procedures, and functions. Also, documentation is essential for troubleshooting, since it gives you a history of your database and the changes realized.

It is especially convenient that your library of user-defined error messages allows you to develop this documentation faster and with more consistency.


Example: Creating User-Defined Error Messages

In this example, we will create an error message in three languages and see how to manage them in SQL Server. The first part is creating the message in English, Portuguese, and Spanish using the sp_addmessage procedure. Figure 1 shows the syntax of this process.

Figure 1. Creating an Error Message in Three Languages


Let’s take a better look at the code in the figure. You can see that we used the sp_addmessage procedure three times, using the same error number but a different language each time. Observe that the severity is the same for all three procedures: the severity level of one language version of a particular error message must be the same as the severity level of the other language versions.

The next step is to see these messages stored inside SQL Server using the sys.messages catalog view. Figure 5.2 shows a SELECT statement that returns your new message and its language versions.

Figure 2. New Error Message in SQL Server


We used an INNER JOIN statement with the sys.syslanguages system table to retrieve the language name, giving us a better look at the result set. You can see that all three versions of the error message are stored inside SQL Server with the same number and severity. Also, this error message isn’t logged, as the is_event_logged column has the value 0.

Now we will change the severity value of this message from 5 to 7. Remember that sp_addmessage is also capable of making changes to the message using the @replace parameter. Figure 3 shows the code that executes the desired change and the appearance of our error message inside SQL Server after the modification.

Figure 3. @replace Parameter and Result in sys.messages Catalog View


As you’ve seen before, when you change the severity of the English version of a message, this modification is replicated to the other language versions of the same message. Now all versions have a severity level of 7.

Now, let’s say that you wish to log this error when it arises. You could use the sp_addmessage with the @replace parameter to change this property, but let’s use an easier way: the sp_altermessage procedure. Figure 4 shows the syntax of sp_altermessage and its result in SQL Server.

Figure 4. Using sp_altermessage to Log an Error


As you can see, all versions now have the is_event_logged column with the value 1, indicating that this error will log when it arises. Now, let’s finish this example using the sp_dropmessage procedure to remove this error. First, we will remove the Spanish version of this message. Figure 5 shows how to drop one version of your message.

Figure 5. Using sp_dropmessage to Remove a Message Version


You can see that the Spanish version was removed from the sys.messages catalog view. Now, we will remove all language versions of this error message using the ALL value for the @language parameter. See the result in SQL Server in Figure 6.

Figure 6. Removing a Message with sp_dropmessage Using the ALL Value


Raising User-Defined Error Messages

Once your custom error messages are created, the next step is to understand how to return them to applications and users when they are executing your T-SQL codes. As mentioned before, SQL Server does not understand a user-defined error as an error until you tell it to raise a custom message as one. To manually raise a user-defined error message in SQL Server, you must use a RAISERROR statement. The general syntax of this statement is as follows:

RAISERROR ( { msg_id | msg_str | @local_variable }
{,severity,state }
[,argument [,...n ] ] )
[ WITH option [,...n ] ]

The RAISERROR statement is really easy to understand when you already know how to manage user-defined error messages. The statement is divided in four parts, plus a WITH clause. The first part is where you inform SQL Server which error you want to raise. If the error message that you wish to raise is already included in the sys.messages catalog view, you only need to indicate its ID number. That’s why you should standardize your messages and add them in SQL Server: you can reuse them inside your programmable objects and transactions.

A RAISERROR statement can also inform a customized text or a local variable of your script that stores a text as the error message. The customized text can have a maximum of 2,047 characters and the associated error number is 50000. If your message contains 2,048 or more characters, SQL Server will only display the first 2,044, and three ellipsis points will indicate that the message has been truncated.

Configuring & Implementing...: Avoid Using Customized Text Directly in theRAISERROR Statement

Although the RAISERROR statement allows you to customize text directly, the management of these messages becomes difficult if you use the same message many times across your database. Keep in mind that the best way to standardize, control, and manage error messages is by using the sys.messages catalog view, and you, as the database developer, should always use this method.


One of the most interesting things that customized text supports is the use of arguments. Arguments allow you to show important information, such as the database that the user was connected to when he executed the code that raised the error message. An argument can be a string or a value, and it’s placed inside the customized text. The general syntax of an argument is as follows:

% [[flag] [width] [. precision] [{h | l}]] type

The items between the percent symbol (%) and type are responsible for formatting the argument and are optional. The flag determines spacing and justification for your argument. Table 1 shows a list of flags supported by SQL Server:

Table 1. Flags Supported by SQL Server
FlagDescription
- (dash or minus sign)Left-justify the argument value. Only makes a difference when you supply a fixed width.
+ (plus sign)Indicates the positive or negative nature if the parameter is a signed numeric type.
0 (zero)Tells SQL Server to pad the left side of a numeric value with zeros until the minimum width is reached.
# (pound sign)Tells SQL Server to use the appropriate prefix (0 or 0x) depending on whether it is octal or hexadecimal. Applies only to octal and hexadecimal values.
' ' (blank)Pads the left of a numeric value with spaces if positive

The width part of an argument sets the amount of space you want to hold for the argument value. This is an integer value. You can also specify an asterisk (*) to let SQL Server automatically determine the width according to the value you set for precision. The precision part determines the maximum number of digits or characters that will be outputted. For example, if a string has 10 characters and precision is set at 5, only the first 5 characters of the string value are used. On the other hand, the precision will be the minimum number of digits printed if your argument is an integer. Following precision, you can indicate if a value is an h ( shortint) or l ( longint) when the type parameter is set as an integer, octal, or hexadecimal value.

The last step is informing the value type for the argument. Table 2 shows the supported value types and their respective symbols.

Table 2. Argument Types Supported by SQL Server
Type of ArgumentSymbol
Signed integerd
Unsigned integeru
Strings
Unsigned octalo
Unsigned hexadecimalx

You can use a maximum of 20 arguments in a customized text. Their values are passed after the state part of the RAISERROR statement in the same sequence that they are placed inside the text. Arguments are also supported within the text of the sp_addmessage procedure, providing you great flexibility.


The next part of the RAISERROR statement is severity, where you inform the severity level associated with your error message. If you use the message ID number to raise your error, the severity specified here will override the severity specified in the sys.messages catalog view. Severity levels from 0 through 18 can be specified by any user. However, severity levels from 19 through 25 can only be specified by members of the sysadmin fixed server role. Also, messages with severity levels from 19 through 25 require logging.

After severity, the next part is to define the state of the error. The state is an integer value from 0 through 255 that helps you find the section of code raising the error, when same user-defined error can rise at multiple locations. To accomplish this, you only need to define a unique state number for each location that can raise the message. The state part is really useful when you are dealing with complex and long strings of code.

The argument is the last part and it’s optional. Here you provide values for the arguments defined in the text of your error message. The order of argument values must correspond to their respective arguments as defined in the text of the message. Remember that you can use 20 arguments at maximum. Each argument can be any of these data types: tinyint, smallint, int, char, varchar, nchar, nvarchar, binary, or varbinary. No other data types are supported.

Finally, the WITH clause makes three more options available: LOG, NOWAIT, and SETERROR. The LOG option logs the raised error in the error log and the application log for the instance. To use this option, the user executing the RAISERROR statement must be a member of the sysadmin fixed server role. The NOWAIT option forces the message to be delivered to the client immediately instead of waiting until everything is done. This option is really useful when dealing with long reports and debugging your code, since it displays all of the prints and selects ahead of it.

The SETERROR option allows you to set the value of the @@ERROR function to be equal to the last error ID number raised. By default, a RAISERROR statement doesn’t set @@ERROR to the value of the error ID you raised. Instead, it reflects the success or failure of your actual RAISERROR statement. The SETERROR@@ERROR variable to equal the last error ID number raised. Look for more about @@ERROR later in this chapter. option overrides this and sets the value of the

Example: Raising Messages Using the RAISERROR Statement

In this example, we will raise some error messages using the RAISERROR statement and some options. First, let’s raise a basic custom text. Figure 7 shows the code of the RAISERROR statement and its return to the user.

Figure 7. Raising a Basic Error Message Using RAISERROR


Let’s look at the return from SQL Server. First, it shows the text of the error message raised. Then, it shows the error number of this message. In this example, the error number is 50000 because we used a custom text. Remember that when you raise a user-defined error stored in SQL Server, the error ID number is from the message_id column of the sys.messages catalog view. SQL Server also exhibits the severity level and the state of the message. In this example, the severity level is 5 and the state is 1.

Now, let’s raise a more complex error message using arguments. Figure 8 shows a RAISERROR statement with four interesting arguments and the return to the user.

Figure 8. Raising an Error Message with Arguments


Now, your error message is more dynamic and informational. In the text of the message, you defined four arguments: three strings (%s) and one unsigned integer (%u). You can see that these arguments show the user some important information such as the number of his process inside SQL Server. After the message text, severity, and state, you inform the value of the four arguments. The argument values must be in the same order as their respective arguments in the text of the message. Also, you can see that these arguments can be local variables of your script or global variables and functions of your instance. This property gives you great flexibility to develop your custom messages as your business requires.

Now, let’s assume that your error message is so important that it must be logged. To log this error, you only need to add WITH LOG at the end of the RAISERRORWITH LOG and Figure 9 displays your error in the SQL Server log. statement. The following code shows how to use

--Retrieve the current login
DECLARE @LOGINNAME VARCHAR(50)
SELECT @LOGINNAME = ORIGINAL_LOGIN()
--A custom error message using arguments
RAISERROR ('This is a custom error message.
Login: %s,
Language: %s,
SPID: %u,
Server Name: %s', 5,1,
@LOGINNAME, @@LANGUAGE, @@SPID, @@SERVERNAME) WITH LOG

Figure 9. Custom Error Written in SQL Server Log


Although this RAISERROR statement is great, you decide that this error message will be reused many times inside your database. So, to standardize this error message, you decide to use the sp_addmessage procedure and add it to SQL Server. Figure 10 shows the code to add the error message and the RAISERROR statement that raises it.

Figure 10. Using RAISERROR to Return User-Defined Error Messages


There is no need to indicate the text of the message and the log option in the RAISERROR statement. These were defined in the sp_addmessage procedure and will be retrieved at execution time. Also, observe that the RAISERROR statement is much smaller when you use a previously defined error message, easing the management of your code throughout your database.

Other -----------------
- SQL Server 2008 : Implementing Error Handling - Understanding Errors
- Implementing SQL Server Objects Using Managed Code (part 2)
- Implementing SQL Server Objects Using Managed Code (part 1)
- Encryption Catalog Views
- Built-In Cryptographic Functions
- SQL server 2008 : Managing Security - Permissions
- SQL server 2008 : Managing Security - Schemas
- SQL server 2008 : Managing Security - Users
- SQL server 2008 : Managing Security - Roles
- SQL Server 2008 : Managing Remote Servers
- Linked Servers
- Adding, Dropping, and Configuring Linked Servers
- Mapping Local Logins to Logins on Linked Servers
- Obtaining General Information About Linked Servers
- Executing a Stored Procedure via a Linked Server
- Setting Up Linked Servers Using SQL Server Management Studio
- Encryption basics for SQL Server : Cryptographic Keys
- Encryption basics for SQL Server : Key Maintenance
- Encryption basics for SQL Server : Key Algorithms
- SQL Server 2005 : Performing Database Backups
 
 
Most View
- Adding Macs to Your Windows 7 Network : Using a Mac to Make a Remote Desktop Connection to Windows 7
- Securing Windows 7 : Thwarting Snoops and Crackers (part 1) - First, Some Basic Precautions
- Windows Server 2008: Installing a Read-Only Domain Controller (part 1)
- Windows Azure Storage Characteristics
- Working with Multiple Local Group Policy Objects
- Text Tags and a Little CSS3 - Adding Style to Text with CSS3 (part 2) - Creating CSS3 classes and IDs
- SQL Server 2008 : Database Mail - Related Views and Procedures
- Exchange Server 2010 : Manage Permissions (part 1) - Understand the Exchange Server 2010 Administrative Model
- Using Cloud Services : Exploring Online Calendar Applications
- Sharepoint 2010 : Backup and Restore (part 4) - Backing up a farm in Central Administration
Top 10
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 3) - Configuring Recipient Filtering
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 2)
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 1)
- Implementing Edge Services for an Exchange Server 2007 Environment : Installing and Configuring the Edge Transport Server Components
- What's New in SharePoint 2013 (part 7) - BCS
- What's New in SharePoint 2013 (part 6) - SEARCH
- What's New in SharePoint 2013 (part 6) - WEB CONTENT MANAGEMENT
- What's New in SharePoint 2013 (part 5) - ENTERPRISE CONTENT MANAGEMENT
- What's New in SharePoint 2013 (part 4) - WORKFLOWS
- What's New in SharePoint 2013 (part 3) - REMOTE EVENTS