We just updated to odp.net 4 and we have a date field on a form that when we try to pass this to our oracle procedure in the backend it get's a Not a Valid Month.
Looking at the code it in the Attachparameter code below it checks for null but this doesn't seem to work. We tried to put in a check and reset the value to DBNull.Value but we still get that not a valid Month error. Any help would
be appreciated.
We tried setting p.Value = OracleString.DBnull but that gave an oracle error. We got it to find the null with p.value=(object)System.Dbnull.value and directly set the p.value=Dbnull.value but
that still gave the Oracle month error. So were not sure how to fix this issue.(code below)
dpDataParamArr = New ArrayList
dpDataParamArr.Add(New DataParameter(STP_Constants.SAVE_ORG_REQ, STP_Constants.P_APPROVAL_DT, "DATETIME", Now, ParameterDirection.Input, 10, Req_Contants.COL_APPROVAL_DT, DataRowVersion.Current)) <--field iwth nulll
UpdateDatasetTable(dsRequestSchema, dsRequestSchema.Tables(RequestSchema.ELEMENTS).TableName, Nothing, arrParameters, STP_Constants.PKG_M
STP_Constants.SAVE, STP_Constants.SAVE, "DELETE", idbConn, idbtrax) <--procedure to call dll that interfaces with oracle
helper.UpdateDataset(IdbInsertCommand, IdbDeleteCommand, IdbUpdateCommand, dsSrcDataset, strTableName)
DLL code below:
public void UpdateDataset(IDbCommand insertCommand, IDbCommand deleteCommand, IDbCommand updateCommand,
DataSet dataSet, string tableName, RowUpdatingHandler rowUpdatingHandler, RowUpdatedHandler rowUpdatedHandler)
{
int rowsAffected = 0;
if( tableName == null || tableName.Length == 0 ) throw new ArgumentNullException( "tableName" );
// Create an IDbDataAdapter, and dispose of it after we are done
IDbDataAdapter dataAdapter = null;
try
{
bool mustCloseUpdateConnection = false;
bool mustCloseInsertConnection = false;
bool mustCloseDeleteConnection = false;
dataAdapter = GetDataAdapter();
// Set the data adapter commands
dataAdapter.UpdateCommand = SetCommand(updateCommand, out mustCloseUpdateConnection);
dataAdapter.InsertCommand = SetCommand(insertCommand, out mustCloseInsertConnection);
dataAdapter.DeleteCommand = SetCommand(deleteCommand, out mustCloseDeleteConnection);
AddUpdateEventHandlers(dataAdapter, rowUpdatingHandler, rowUpdatedHandler);
if( dataAdapter is DbDataAdapter )
{
// Update the DataSet changes in the data source
try
{
rowsAffected = ((DbDataAdapter)dataAdapter).Update(dataSet, tableName);
}
catch (Exception ex)
{
// Don't just throw ex. It changes the call stack. But we want the ex around for debugging, so...
Debug.WriteLine(ex);
dataAdapter = null;
if (mustCloseUpdateConnection)
{
updateCommand.Connection.Close();
}
if (mustCloseInsertConnection)
{
insertCommand.Connection.Close();
}
if (mustCloseDeleteConnection)
{
deleteCommand.Connection.Close();
}
ExceptionManager.Publish(ex);
throw ex;
}
}
else
{
dataAdapter.TableMappings.Add(tableName, "Table");
// Update the DataSet changes in the data source
rowsAffected = dataAdapter.Update (dataSet);
}
// Commit all the changes made to the DataSet
dataSet.Tables[tableName].AcceptChanges();
if (mustCloseUpdateConnection)
{
updateCommand.Connection.Close();
}
if (mustCloseInsertConnection)
{
insertCommand.Connection.Close();
}
if (mustCloseDeleteConnection)
{
deleteCommand.Connection.Close();
}
}catch (Exception e)
{
Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManager.Publish(e);
throw e;
}
finally
{
if ( insertCommand != null )
{
insertCommand.Dispose();
//dataAdapter.InsertCommand.Dispose();
}
if ( updateCommand != null )
{
updateCommand.Dispose();
//dataAdapter.UpdateCommand.Dispose();
}
if ( deleteCommand != null )
{
deleteCommand.Dispose();
//dataAdapter.DeleteCommand.Dispose();
}
IDisposable id = dataAdapter as IDisposable;
if( id != null ) id.Dispose();
}
}
protected virtual IDbCommand SetCommand(IDbCommand command, out bool mustCloseConnection )
{
mustCloseConnection = false;
if (command != null)
{
IDataParameter[] commandParameters = new IDataParameter[ command.Parameters.Count ];
command.Parameters.CopyTo( commandParameters, 0 );
command.Parameters.Clear();
this.PrepareCommand( command, command.Connection, null, command.CommandType, command.CommandText, commandParameters, out mustCloseConnection );
CleanParameterSyntax(command);
}
return command;
}
protected virtual void PrepareCommand(IDbCommand command, IDbConnection connection, IDbTransaction transaction, CommandType commandType, string commandText,
IDataParameter[] commandParameters, out bool mustCloseConnection )
{
if( command == null ) throw new ArgumentNullException( "command" );
if( commandText == null || commandText.Length == 0 ) throw new ArgumentNullException( "commandText" );
// If the provided connection is not open, we will open it
if (connection.State != ConnectionState.Open)
{
mustCloseConnection = true;
connection.Open();
}
else
{
mustCloseConnection = false;
}
// Associate the connection with the command
command.Connection = connection;
// Set the command text (stored procedure name or SQL statement)
command.CommandText = commandText;
// If we were provided a transaction, assign it
if (transaction != null)
{
if( transaction.Connection == null ) throw new ArgumentException( "The transaction was rolled back or commited, please provide an open transaction.", "transaction"
);
command.Transaction = transaction;
}
// Set the command type
command.CommandType = commandType;
// Attach the command parameters if they are provided
if (commandParameters != null)
{
AttachParameters(command, commandParameters);
}
return;
}
protected virtual void AttachParameters(IDbCommand command, IDataParameter[] commandParameters)
{
if( command == null ) throw new ArgumentNullException( "command" );
if( commandParameters != null )
{
foreach (IDataParameter p in commandParameters)
{
if( p != null )
{
// Check for derived output value with no value assigned
if ( ( p.Direction == ParameterDirection.InputOutput ||
p.Direction == ParameterDirection.Input ) &&
(p.Value == null)) <--doesn't find
{
p.Value = DBNull.Value;
}
if (p.DbType == DbType.Binary)
{
// special handling for BLOBs
command.Parameters.Add(GetBlobParameter(command.Connection, p));
}
else if (p.DbType == DbType.Object)//special handle for large strings
{
command.Parameters.Add(GetClobParameter(command.Connection, p));
}
else
{
command.Parameters.Add(p);
}
}
}
}
}