M
Mark Rae
Hi,
I'm currently working writing a Windows service in C# which needs, among
other things, to interface with Microsoft Great Plains 8.0, specifically to
add General Ledger entries. In order to add a new General Ledger entry to a
Great Plains database, it's necessary to supply a journal entry number -
Microsoft provide a stored procedure which calculates the most recent
journal entry number used, increments this value by one, and returns this to
the caller in the form of an output parameter. The top of the procedure is
as follows:
CREATE PROCEDURE dbo.glGetNextJournalEntry
@l_tINCheckWORKFiles tinyint = NULL,
@I_iSQLSessionID int = NULL,
@IO_iOUTJournalEntry int = NULL output,
@O_tOUTOK tinyint = NULL output,
@O_iErrorState int = NULL output
AS
IF((@l_tINCheckWORKFiles IS NULL) OR (@IO_iOUTJournalEntry IS NULL) OR
(@I_iSQLSessionID IS NULL))
BEGIN
SELECT
@O_iErrorState = 20159,
@IO_iOUTJournalEntry = 0,
@O_tOUTOK = 0
RETURN
END
<snipped rest of proc>
@IO_iOUTJournalEntry returns the next journal entry number
@O_tOUTOK returns 0 or 1 depending on whether the procedure succeeds or
fails
@O_iErrorState contains 0 if the procedure succeeds, or the error state if
it fails
I'm calling the procedure as follows:
SqlConnection mobjSqlConn;
SqlCommand mobjSqlCommand;
SqlParameter mobjSqlParameter;
ArrayList maobjSqlParameters = new ArrayList();
SqlDataReader mobjDR = null;
maobjSqlParameters.Clear();
mobjSqlParameter = new SqlParameter("@l_tINCheckWORKFiles",
SqlDbType.TinyInt);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlParameter = new SqlParameter("@I_iSQLSessionID", SqlDbType.Int);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlParameter = new SqlParameter("@IO_iOUTJournalEntry", SqlDbType.Int);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Direction = ParameterDirection.Output;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlParameter = new SqlParameter("@O_tOUTOK", SqlDbType.TinyInt);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Direction = ParameterDirection.Output;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlParameter = new SqlParameter("@O_iErrorState", SqlDbType.Int);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Direction = ParameterDirection.Output;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlConn = new SqlConnection(CGlobal.gstrSQLConnectionString);
mobjSqlCommand = new SqlCommand("glGetNextJournalEntry", mobjSqlConn);
mobjSqlCommand.CommandType = CommandType.StoredProcedure;
foreach(SqlParameter objSqlParameter in maobjSqlParameters)
{
mobjSqlCommand.Parameters.Add(objSqlParameter);
}
mobjSqlCommand.Connection.Open();
mobjDR = mobjSqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
It all works as far as here, i.e. there are no errors and mobjDR contains an
SqlDataReader, obviously with no records. However, the procedure does not
return the next journal entry number. The values of the three output
parameters are as follows:
@IO_iOUTJournalEntry - 0
@O_tOUTOK - 0
@O_iErrorState - 20159
Clearly, the procedure is not getting past the first validation (see above).
So I enabled SQL debugging in the probject and set a breakpoint at the top
of the procedure - turns out that all three output parameters have lost
their initial values by the time they get passed into the procedure i.e.
they are all being passed in as NULL.
Therefore, I tried to send a hardcoded SQL string to the procedure instead
i.e.
string strSQL = "";
strSQL += "DECLARE @IO_iOUTJournalEntry int, @O_tOUTOK tinyint,
@O_iErrorState int ";
strSQL += "SELECT @IO_iOUTJournalEntry = 0, @O_tOUTOK = 0, @O_iErrorState =
0 ";
strSQL += "EXEC glGetNextJournalEntry 0, 0, @IO_iOUTJournalEntry out,
@O_tOUTOK out, @O_iErrorState out ";
strSQL += "SELECT @IO_iOUTJournalEntry";
mobjSqlConn = new SqlConnection(pstrSqlConnectionString);
mobjSqlCommand = new SqlCommand(pstrSQL, mobjSqlConn);
mobjSqlCommand.Connection.Open();
mobjDR = mobjSqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
mobjDR.Read();
intNextJournalEntry = mobjDR.GetInt32(0);
mobjDR.Close();
This worked perfectly.
Can anyone please tell me what I'm doing wrong? Is there something specific
about passing output parameters to SQL Server stored procedures in the
SqlCommand's Parameters collection which makes them lose their initial
values?
Any assistance gratefully received.
Regards,
Mark Rae
I'm currently working writing a Windows service in C# which needs, among
other things, to interface with Microsoft Great Plains 8.0, specifically to
add General Ledger entries. In order to add a new General Ledger entry to a
Great Plains database, it's necessary to supply a journal entry number -
Microsoft provide a stored procedure which calculates the most recent
journal entry number used, increments this value by one, and returns this to
the caller in the form of an output parameter. The top of the procedure is
as follows:
CREATE PROCEDURE dbo.glGetNextJournalEntry
@l_tINCheckWORKFiles tinyint = NULL,
@I_iSQLSessionID int = NULL,
@IO_iOUTJournalEntry int = NULL output,
@O_tOUTOK tinyint = NULL output,
@O_iErrorState int = NULL output
AS
IF((@l_tINCheckWORKFiles IS NULL) OR (@IO_iOUTJournalEntry IS NULL) OR
(@I_iSQLSessionID IS NULL))
BEGIN
SELECT
@O_iErrorState = 20159,
@IO_iOUTJournalEntry = 0,
@O_tOUTOK = 0
RETURN
END
<snipped rest of proc>
@IO_iOUTJournalEntry returns the next journal entry number
@O_tOUTOK returns 0 or 1 depending on whether the procedure succeeds or
fails
@O_iErrorState contains 0 if the procedure succeeds, or the error state if
it fails
I'm calling the procedure as follows:
SqlConnection mobjSqlConn;
SqlCommand mobjSqlCommand;
SqlParameter mobjSqlParameter;
ArrayList maobjSqlParameters = new ArrayList();
SqlDataReader mobjDR = null;
maobjSqlParameters.Clear();
mobjSqlParameter = new SqlParameter("@l_tINCheckWORKFiles",
SqlDbType.TinyInt);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlParameter = new SqlParameter("@I_iSQLSessionID", SqlDbType.Int);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlParameter = new SqlParameter("@IO_iOUTJournalEntry", SqlDbType.Int);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Direction = ParameterDirection.Output;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlParameter = new SqlParameter("@O_tOUTOK", SqlDbType.TinyInt);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Direction = ParameterDirection.Output;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlParameter = new SqlParameter("@O_iErrorState", SqlDbType.Int);
mobjSqlParameter.IsNullable = true;
mobjSqlParameter.Direction = ParameterDirection.Output;
mobjSqlParameter.Value = 0;
maobjSqlParameters.Add(mobjSqlParameter);
mobjSqlConn = new SqlConnection(CGlobal.gstrSQLConnectionString);
mobjSqlCommand = new SqlCommand("glGetNextJournalEntry", mobjSqlConn);
mobjSqlCommand.CommandType = CommandType.StoredProcedure;
foreach(SqlParameter objSqlParameter in maobjSqlParameters)
{
mobjSqlCommand.Parameters.Add(objSqlParameter);
}
mobjSqlCommand.Connection.Open();
mobjDR = mobjSqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
It all works as far as here, i.e. there are no errors and mobjDR contains an
SqlDataReader, obviously with no records. However, the procedure does not
return the next journal entry number. The values of the three output
parameters are as follows:
@IO_iOUTJournalEntry - 0
@O_tOUTOK - 0
@O_iErrorState - 20159
Clearly, the procedure is not getting past the first validation (see above).
So I enabled SQL debugging in the probject and set a breakpoint at the top
of the procedure - turns out that all three output parameters have lost
their initial values by the time they get passed into the procedure i.e.
they are all being passed in as NULL.
Therefore, I tried to send a hardcoded SQL string to the procedure instead
i.e.
string strSQL = "";
strSQL += "DECLARE @IO_iOUTJournalEntry int, @O_tOUTOK tinyint,
@O_iErrorState int ";
strSQL += "SELECT @IO_iOUTJournalEntry = 0, @O_tOUTOK = 0, @O_iErrorState =
0 ";
strSQL += "EXEC glGetNextJournalEntry 0, 0, @IO_iOUTJournalEntry out,
@O_tOUTOK out, @O_iErrorState out ";
strSQL += "SELECT @IO_iOUTJournalEntry";
mobjSqlConn = new SqlConnection(pstrSqlConnectionString);
mobjSqlCommand = new SqlCommand(pstrSQL, mobjSqlConn);
mobjSqlCommand.Connection.Open();
mobjDR = mobjSqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
mobjDR.Read();
intNextJournalEntry = mobjDR.GetInt32(0);
mobjDR.Close();
This worked perfectly.
Can anyone please tell me what I'm doing wrong? Is there something specific
about passing output parameters to SQL Server stored procedures in the
SqlCommand's Parameters collection which makes them lose their initial
values?
Any assistance gratefully received.
Regards,
Mark Rae