«Ошибка преобразования типа данных nvarchar в int» при выполнении хранимой процедуры и чтении возвращаемого значения - PullRequest
0 голосов
/ 25 мая 2018

У меня есть хранимая процедура clr с выходным значением, которое я вызываю sp из приложения vb.net с кодом ниже.Я получаю сообщение об ошибке «Ошибка преобразования типа данных nvarchar в int.1125092 | 63688 | Ok 'значения - это именно то, что я ожидаю от sp, но я не могу понять, почему я получаю ошибку преобразования, может кто-нибудь помочь с этим.

Код Вызов sp:

Try
            Dim CN As New SqlConnection
            CN.ConnectionString = My.Settings.myConnection
            CN.Open()

            Dim Profile As String = "40T"
            Dim StartPosition As String = "53.6924582,-2.8730636000"
            Dim Destination As String = "46.18186,1.380222"
            Dim RetValue As String = "Testvalue"

            Dim test As String ="53.816408201,-2.990582799997"

            Dim cmd As SqlCommand = New SqlCommand("GetDistanceAndTime", CN)
            cmd.CommandType = CommandType.StoredProcedure
            cmd.CommandText = "GetDistanceAndTime"
            cmd.Parameters.AddWithValue("@Profile", Profile )
            cmd.Parameters.AddWithValue("@StartPosition", StartPosition)
            cmd.Parameters.AddWithValue("@Destination", Destination)
            cmd.Parameters.AddWithValue("@Result", SqlDbType.NVarChar )
            cmd.Parameters("@Result").Direction = ParameterDirection.Output
            Try

             cmd.ExecuteNonQuery()
                RetValue = cmd.Parameters ("@Result").value
                If RetValue .Length > 2 Then

                End If
            Catch ex As Exception
                MessageBox.Show(Err.Description)
            End Try
        Catch ex As Exception
            MessageBox.Show(Err.Description)
        End Try

Код clr ​​sp:

public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void SqlStoredProcedure1(SqlString Profile, SqlString StartPosition, SqlString Destination, ref SqlString Result)
    {
        SqlString result;
        try
        {           
            SqlPipe sqlPipe = SqlContext.Pipe;

            result = DistanceRequest.InvokeService(Profile.ToString(), StartPosition.ToString(), Destination.ToString());
            Result = result.ToString();          
            SqlContext.Pipe.Send(result.ToString());
        }
        catch (Exception ex)
        {
            result = ex.Message;
            SqlContext.Pipe.Send(result.ToString());
        }

    }
}

Странно, когда я выполняю хранимую процедуру из диспетчера сервера sql, она возвращает возвращаемое значение как int!Я еще больше сбит с толку.

USE [myDB] GO

DECLARE @return_value int, @Result nvarchar(50)

EXEC @return_value = [dbo].[GetDistanceAndTime]
  @Profile = N'40T',
  @StartPosition = N'53.6924582,-2.8730636000',
  @Destination = N'46.18186,1.380222',
  @Result = @Result OUTPUT

SELECT  @Result as N'@Result'

SELECT  'Return Value' = @return_value

GO

1 Ответ

0 голосов
/ 25 мая 2018

Основная проблема с этой строкой:

AddWithValue("@Result", SqlDbType.NVarChar )

Проблема в том, что SqlDbType.NVarChar является enum, но используется здесь неправильно как "значение" дляподразумевает тип данных из.Тип данных по умолчанию int.Вот почему вы получаете ошибку при преобразовании параметра Result хранимой процедуры в int, который был объявлен для параметра SqlCommand через строку, показанную выше.

Вторичная проблема:

Хотя я не имею ничего против вызова веб-служб из SQLCLR, это следует делать только тогда, когда процесс полностью содержится в T-SQL.Если вы уже находитесь в коде .NET, нет смысла выполнять хранимую процедуру только для вызова веб-службы.Это крайне неэффективно как для уровня приложения, так и для уровня базы данных.

Несколько других вещей:

  1. Ваш код .NET возвращает void изметод, поэтому не используйте захват @return_value
  2. Не используйте метод AddWithValue.Вместо этого создайте каждый параметр с правильным типом данных и затем установите значение, а затем добавьте его в коллекцию Parameters.
  3. Несмотря на то, что это уже упоминалось как проблема, связанная с созданием таких параметров в будущем,даже используя Add: AddWithValue("@Result", SqlDbType.NVarChar ) При установке типа данных для строкового типа, обязательно также укажите maxsize / length
  4. Это может быть проблемой: RetValue = cmd.Parameters ("@Result").value SqlParameter значения имеют тип object.Так что либо приведите к строке, либо добавьте .ToString() к value.
  5. Вам не нужно вызывать ToString() для входных параметров SqlString.Все типы Sql* имеют свойство Value, которое возвращает значение в ожидаемом типе .NET.Значение Profile.Value возвращает искомую строку.
  6. Вы создаете SqlPipe sqlPipe = SqlContext.Pipe;, но никогда не используете ее.Вы можете использовать его в обоих местах, которые вы делаете SqlContext.Pipe.Send().Так что вместо этого используйте: sqlPipe.Send().
...