Sunday, October 5, 2008

Accessing return value of SPs

When working with databases, it is recommended that all the database queries should be moved to Stored Procedures (hereafter referred to as SP). This makes perfect sense because having all the queries in one place makes it easy to debug in case the database integration is not working as well as makes it less cumbersome to make changes (since it is known where those changes need to be made and the changes need not be duplicated in multiple code files). Given this best practice, it is often a requirement to capture the return value of the SP in order to determine whether the SP execution succeeded or failed.

ADO.NET has the SqlCommand and SqlConnection objects to allow the user to invoke the SP and have access to the results returned by the SP. Specifically, there are 3 methods that can be used to execute a query or an SP on the database :
  1. SqlCommand.ExecuteNonQuery() : Used for queries which don't return any value, i.e. insert, update and delete queries
  2. SqlCommand.ExecuteScalar() : Used for queries which are guaranteed to return a single value
  3. SqlCommand.ExecuteReader() : Used for queries that return multi column and/or multi row result sets

There is 1 important difference in the use of these 3 methods when it comes to accessing return values. It turns out that when using ExecuteScalar() and ExecuteNonQuery(), we can access the return value immediately following this method call whereas, for the ExecuteReader() method this is not the case. If we try to access the value of the parameter object created for the return value, it will have a null value. The return value is set only after we iterate through the entire result set returned by the reader object. The reasoning behind this behaviour can be as follows. If the result set was returned successfully, it means the SP succeeded so there's no point of checking the return value. It only makes sense to check the return value in case there was no result returned. The return value will then enable us to determine whether there was actually no data in the database for the given query or there is a bug which caused incorrect results to be returned.

Do keep this slight variation in the behaviour of the ExecuteReader() the next time you use it.

No comments:

Post a Comment