Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Either UserType 19 or 36 is required for 'text', 'text_locator' or 'unitext' typed input parameter in the stored proc #187

Closed
ngvtien opened this issue Jul 17, 2020 · 2 comments · Fixed by #184
Labels
Milestone

Comments

@ngvtien
Copy link
Contributor

ngvtien commented Jul 17, 2020

Describe the bug
If neither UserType 36 nor 19 is set for when the byte count for the text value is greater than 16384 then we will get an exception thrown
The token datastream length was not correct. This is an internal protocol error.

To Reproduce
Please provide C#/SQL necessary to reproduce the issue, and steps to follow:
SQL:

create procedure [dbo].[sp_test_text_type_coloumn]
  @text_locator_input text_locator,
  @text_input text,
  @output int output
as
begin
  set @output = 10
end

C#

public void TextTypeColumn_Procedure_Failed_When_Incorrect_UserType_Set()
{
    using (var connection = new AseConnection(ConnectionStrings.Pooled))
    {
        connection.Open();
        using (var command = connection.CreateCommand())
        {
            command.CommandText = "sp_test_text_type_coloumn";
            command.CommandType = CommandType.StoredProcedure;

            var text_locator = new string('x', 16384);
            var just_text = new string('y', 1024);

            var p = command.CreateParameter();
            p.ParameterName = "@text_locator_input";
            p.Value = text_locator;
            p.DbType = DbType.String;
            command.Parameters.Add(p);

            p = command.CreateParameter();
            p.ParameterName = "@text_input";
            p.Value = just_text;
            p.DbType = DbType.String;
            command.Parameters.Add(p);

            var pOut = command.CreateParameter();
            pOut.ParameterName = "@output";
            pOut.Value = DBNull.Value;
            pOut.DbType = DbType.Int32;
            pOut.Direction = ParameterDirection.Output;
            command.Parameters.Add(pOut);

            command.ExecuteNonQuery();
        }
    }
}

If you break into the code and set UserType for the 1st parameter to either 19 or 36 then it would work but not when 35 is set

Expected behavior
It shouldn't throw any exception.

Environment

  • .NET Framework or Core version (all versions)
  • AdoNetCore.AseClient nuget package version 0.18.0

Additional context
One of the work-around for me at this stage is to allow AseParameter class to have an additional internal property to over write the user type and that can be set at the time when the parameter is created. eg something like this

var p = command.CreateParameter();
p.ParameterName = "@text_locator_input";
p.Value = text_locator;
p.DbType = DbType.String;
p.OverrideUserType = 36; //19;
command.Parameters.Add(p);

and when it comes to creating the FormatItem we would check for any previous value set like so

var format = new FormatItem
{
    ParameterName = parameter.ParameterName,
    IsOutput = parameter.IsOutput,
    IsNullable = parameter.IsNullable,
    Length = length,
    DataType = TypeMap.GetTdsDataType(dbType, parameter.SendableValue, length, parameter.ParameterName),
    UserType = parameter.OverrideUserType ?? TypeMap.GetTdsUserType(dbType)
};
@formicas
Copy link
Contributor

@ngvtien the workaround breaks the drop-in replacement paradigm. GetTdsUserType is missing the full context to work properly. It should probably be based on the output of GetTdsDataType, not just the DbType

@ngvtien
Copy link
Contributor Author

ngvtien commented Aug 12, 2020

Actually, with the recent commit I've addressed this issue already, similar to to how we're dealing with UserType 34 and 35

@ngvtien ngvtien added this to the 0.19.0 milestone Sep 2, 2020
@valente500 valente500 linked a pull request Sep 2, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants