Output params from stored procs using MS Data Access Application Block
As my current client is early in the architecture phase, I’ve been reviewing the MS Data Access Application Block. I did a brief experiment, and I’m having problems retrieving output parameters from stored procedures. I created a simple stored proc (with CodeSmith):
[Edit: I just debugged this with one of the MS Consulting Services Architects on this project. There is a bug in the Data Access App Block that causes this problem when you call methods that take an array of objects that hold your parameter values. Calling the overload that takes a SqlParameter array works fine. He wasn't real suprised that there are problems with the DAAB.]
[Edit2: Bill Selznick's comment is right on. Most of the people that mail me about this problem are calling the wrong overload of ExecuteNonQuery. Step into the DAAB and make sure you are calling the overload that you intend to.]
CREATE PROCEDURE dbo.InsertValidationPolicy @Severity int, @Message nvarchar(50), @Required bit, @ValidationPolicyID uniqueidentifier OUTPUT AS SET @ValidationPolicyID = NEWID() INSERT INTO [ValidationPolicies] ( [ValidationPolicyID], [Severity], [Message], [Required] ) VALUES ( @ValidationPolicyID, @Severity, @Message, @Required ) GO
And created a simple data access object with static methods (doing the prototype before I build the CodeSmith template). The below method calls the stored procedure to create a new object. Notice the fourth parameter is an output parameter, and that the stored procedure is executed using SqlHelper (the main component in the Data Access App Block).
static public Guid CreateValidationPolicy(int severity, string message, bool required) { SqlParameter paramSeverity = new SqlParameter("Severity", SqlDbType.Int); paramSeverity.Value=severity; SqlParameter paramMessage = new SqlParameter("Message", SqlDbType.NVarChar); paramMessage.Value=message; SqlParameter paramRequired = new SqlParameter("Required", SqlDbType.Bit); paramRequired.Value=required; SqlParameter paramID = new SqlParameter("PolicyID",SqlDbType.UniqueIdentifier); paramID.Direction = ParameterDirection.Output; SqlParameter[] parameters = { paramSeverity, paramMessage, paramRequired, paramID }; SqlHelper.ExecuteNonQuery(ConnectionString, "InsertValidationPolicy", parameters); return (Guid)paramID.Value; }
This method throws an Exception complaining that, “Object must implement IConvertible”. It works fine if I don’t use output parameters. There are several threads discussing this problem in the newsgroup dedicated to the MS Building Blocks. The best discussion was started by Jim Bentley on 2/27/03 (sorry, but I don’t know how to link to news threads) and includes some responses from Microsoft, but no solutions.
Ted