Question

Having a strange issue using SqlDataAdapter to execute a stored procedure and return the result set. The procedure returns a single string value, and executes correctly and returns the proper value when executed in SSMS. But for some reason the SqlDataAdapter.Fill to a DataSet is causing the result to be padded out with leading 0 characters.

For example, executing the sp in the database returns '175190336289169307', but executing via the .Fill method (or ExecuteScalar as well) returns '00000000000000175190336289169307'.

Any ideas what is going on? Is there some way to cast or convert this result to make it correct? Thanks.

Dim param As SPParam
Dim r As String = ""

_cn = New SqlConnection(_connection)
_cn.Open()

_da = New SqlDataAdapter
_cmd = _cn.CreateCommand

_cmd.CommandType = CommandType.StoredProcedure
_cmd.CommandText = _StoredProcName


For Each param In _SPParams
    _cmd.Parameters.Add(param.SQLParam)
Next

Select Case Type
    Case ExecuteType.Scalar
        r = _cmd.ExecuteScalar.ToString
    Case ExecuteType.CommandOnly
        r = _cmd.ExecuteNonQuery
    Case ExecuteType.Tabular
        _da.SelectCommand = _cmd
        _ds = New DataSet
        _da.Fill(_ds)
End Select

For Each param In _SPParams
    param.Value = param.SQLParam.Value
Next

Return r

This is the skeleton of the SQL code. Fairly simple really. There is a wrapper sp that calls an underlying scalar function. The function return value type (ultimately also the return type of the sp) is VARCHAR(255). The return value starts as an empty string, and is built up a chunk at a time to create the return string. Calling either the function, or the wrapper sp in SSMS returns just the final string. There are no leading 0 characters.

-- wrapper stored procedure
CREATE PROCedure [dbo].[sp_fubar] 
    @p_1 VARCHAR(120),
    @p_Status INT = 0 Output ,
    @p_ErrMsg VARCHAR(1000) = '' Output
AS

BEGIN TRY
    Set NOCOUNT ON;

    Set @p_Status = 99
    Set @p_ErrMsg = 'Unknown error'

    SELECT dbo.BaseFunction(@p_1) as [Result]

    Set @p_Status = 0
    Set @p_ErrMsg = 'Success'


END TRY
BEGIN CATCH
    Set @p_Status = 16
    Set @p_ErrMsg = 'Error in sp_fubar: ' + ERROR_MESSAGE()
END CATCH;

GO

-- base function call
CREATE FUNCTION [dbo].[BaseFunction] (
    @p_InputData VARCHAR(40)
)
RETURNS VARCHAR(255)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @p_ReturnData VARCHAR(255)

    declare
        @len as integer,
        @c as integer

    -- Trim off access spaces
    set @p_InputData = ltrim(rtrim(@p_InputData))

    -- Get the length of the given data
    set @len = len(@p_InputData)

    while (@len >= 1)
    begin
        -- Get the ascii value of each character
        set @c = ascii(substring(@p_InputData, @len, 1))

        -- Do stuff with @c

        set @p_ReturnData = @p_ReturnData + cast(@c as varchar)
        set @len = @len - 1 
    end

    -- Return the result of the function
    RETURN @p_ReturnData

END

GO
Was it helpful?

Solution

Turns out to be a case of garbage in garbage out.

The varchar @p_1 parameter being passed to the sp from the .net app was coming from a String type variable. This variable was defined as having a length of 20, as this is the defined length of the source where this variable is read from. In practice though, the length of the desired string (in terms of non-whitespace and non-null characters) is shorter than 20. but the full string, null characters and all, was getting passed to the sp, which was the reason for the padding.

Not finding a way to directly specify or re-dimension the length of a string type in .net, I added a quick loop to trim the string, and problem solved.

Tough one to find though, because looking at the value of the string in Visual Studio you see the string you want (without the non-printing characters displayed), so it isn't immediately apparent that the actual string is longer. It didn't click until I looked at the .Len property and saw a value of 20.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top