Hi All, I'm currently evaluating ibatis.net to use with a database which only allows access through a fixed set of stored procedures. The insert procedures return the identity value with the sql return statement rather than an out parameter, like so:
CREATE PROCEDURE [dbo].[DoFoo] @foo int AS INSERT INTO Foos (foo) VALUES (@foo) RETURN @@IDENTITY And I need to get access to the return value. So far I've got the statement like so: <procedure id="CreateFoo" parameterMap="FooClass" resultClass="int">DoFoo</procedure> The procedure executes as planned ( new foo inserted in the DB), but this code: int id = ( int ) Mapper.Instance ( ).Insert ( "CreateFoo", fooInstance ) ; Always returns a value of 0. I know ibatis supports the use of out parameters to sprocs, but in this case I'd rather avoid modifying the sproc code. So when looking at the ExecuteInsert method on MappedStatement, I realize that I can never get a hold of the return value since there is never added a parameter to the command with a direction of ReturnValue. And if the identity is returned using a return rather than a select, either one will be null. So I can safely assume that is the return value from ExecuteScalar is null and the value of the return value parameters is not null, I can assume that the idendity value is being returned througth the return statement. So I'd suggest modifying ExecuteInsert: 1. Add a default return value parameter to the command before execution. 2. Check the scalar value if it is null, if not, use the scalar value, then check if the return parameter value is null, if not, then use the return value. If no resultClass is defined for that statement, then a null will be returned. Refined ExecuteInsert: public virtual object ExecuteInsert(IDalSession session, object parameterObject ) { object generatedKey = null; SelectKey selectKeyStatement = null; RequestScope request = _statement.Sql.GetRequestScope(parameterObject, session);; if (_statement is Insert) { selectKeyStatement = ((Insert)_statement).SelectKey; } if (selectKeyStatement != null && !selectKeyStatement.isAfter) { MappedStatement mappedStatement = _sqlMap.GetMappedStatement( selectKeyStatement.Id ); generatedKey = mappedStatement.ExecuteQueryForObject(session, parameterObject); ObjectProbe.SetPropertyValue(parameterObject, selectKeyStatement.PropertyName, generatedKey); } //using (IDbCommand command = CreatePreparedCommand(request, session, parameterObject )) using ( IDbCommand command = _preparedCommand.Create( request, session, this.Statement, parameterObject ) ) { if (_statement is Insert) { command.ExecuteNonQuery(); } else { IDataParameter returnValueParameter = command.CreateParameter(); returnValueParameter.ParameterName = "@return_value"; returnValueParameter.Direction = ParameterDirection.ReturnValue; command.Parameters.Add(returnValueParameter); generatedKey = command.ExecuteScalar(); if ( (generatedKey != null) && (_statement.ResultClass!=null) && _sqlMap.TypeHandlerFactory.IsSimpleType(_statement.ResultClass) ) { ITypeHandler typeHandler = _sqlMap.TypeHandlerFactory.GetTypeHandler(_statement.ResultClass); generatedKey = typeHandler.GetDataBaseValue(generatedKey, _statement.ResultClass); }else if ( (generatedKey == null) && (returnValueParameter.Value != null) &&(_statement.ResultClass!=null) && _sqlMap.TypeHandlerFactory.IsSimpleType(_statement.ResultClass) ) { ITypeHandler typeHandler = _sqlMap.TypeHandlerFactory.GetTypeHandler(_statement.ResultClass); generatedKey = typeHandler.GetDataBaseValue(returnValueParameter.Value, _statement.ResultClass); } } if (selectKeyStatement != null && selectKeyStatement.isAfter) { MappedStatement mappedStatement = _sqlMap.GetMappedStatement( selectKeyStatement.Id ); generatedKey = mappedStatement.ExecuteQueryForObject(session, parameterObject); ObjectProbe.SetPropertyValue(parameterObject, selectKeyStatement.PropertyName, generatedKey); } ExecutePostSelect( session, request); RetrieveOutputParameters(request, session, command, parameterObject); } RaiseExecuteEvent(); return generatedKey; } - Oddur Magnusson