Набор данных SqlDataAdapter заполняет строку заполнения 0

Возникла странная проблема с использованием SqlDataAdapter для выполнения хранимой процедуры и возврата набора результатов. Процедура возвращает одно строковое значение, выполняется правильно и возвращает правильное значение при выполнении в SSMS. Но по какой-то причине SqlDataAdapter.Fill для DataSet приводит к тому, что результат дополняется начальными 0 символами.

Например, выполнение sp в базе данных возвращает «175190336289169307», но выполнение с помощью метода .Fill (или также ExecuteScalar) возвращает «000000000000000175190336289169307».

Есть идеи, что происходит? Есть ли способ преобразовать или преобразовать этот результат, чтобы сделать его правильным? Спасибо.

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

Это скелет кода SQL. Довольно просто на самом деле. Существует оболочка sp, которая вызывает базовую скалярную функцию. Тип возвращаемого значения функции (в конечном итоге также тип возвращаемого значения sp) — VARCHAR(255). Возвращаемое значение начинается с пустой строки и формируется по частям для создания возвращаемой строки. Вызов функции или оболочки sp в SSMS возвращает только окончательную строку. Нет ведущих 0 символов.

-- 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

person KeithB    schedule 01.10.2013    source источник
comment
Можете ли вы показать код вашего сохраненного процесса?   -  person GrandMasterFlush    schedule 01.10.2013
comment
Сделанный. Добавлен код, показывающий суть происходящего, а не точный код. Спасибо.   -  person KeithB    schedule 01.10.2013
comment
Является ли общая длина заполненной возвращаемой строки 255 символов?   -  person GrandMasterFlush    schedule 02.10.2013
comment
Нет, это 32 символа.   -  person KeithB    schedule 02.10.2013
comment
Я попытался запустить тест с вашим кодом, и он вернул данные без каких-либо дополнений. Единственное, что я не мог заставить работать с вашим кодом, это тип SPParam, поэтому я установил параметры SP в коде. Я предполагаю, что проблема может заключаться здесь. Не могли бы вы рассказать, что такое SPParam?   -  person GrandMasterFlush    schedule 02.10.2013


Ответы (1)


Оказывается, дело мусора в мусоре.

Параметр varchar @p_1, передаваемый в sp из приложения .net, исходил из переменной типа String. Эта переменная была определена как имеющая длину 20, так как это определенная длина источника, из которого эта переменная считывается. Однако на практике длина желаемой строки (с точки зрения непробельных и ненулевых символов) короче 20. но полная строка, нулевые символы и все остальное, передавалось в sp, что было причиной для обивка.

Не найдя способа напрямую указать или изменить длину строкового типа в .net, я добавил быстрый цикл для обрезки строки, и проблема была решена.

Однако его сложно найти, потому что, глядя на значение строки в Visual Studio, вы видите нужную строку (без отображаемых непечатаемых символов), поэтому сразу не видно, что фактическая строка длиннее. Он не щелкал, пока я не посмотрел на свойство .Len и не увидел значение 20.

person KeithB    schedule 05.10.2013