“执行存储过程并读取返回值时,将数据类型nvarchar转换为int时出错”

时间:2018-05-25 13:24:39

标签: .net sql-server stored-procedures return-value sqlclr

我有一个clr存储过程,它有一个输出值我从一个vb.net应用程序调用sp,代码如下。我收到一条错误,指出'将数据类型nvarchar转换为int时出错。 1125092 | 63688 |好的'价值正是我期待从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 server manager执行存储过程时,它将返回值编译为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 :(得分:0)

主要问题在于这一行:

AddWithValue("@Result", SqlDbType.NVarChar )

问题是SqlDbType.NVarCharenum但在这里被错误地用作暗示数据类型的“值”。默认情况下,数据类型为int。这就是为什么您将存储过程的Result参数转换为通过上面显示的行为int参数声明的SqlCommand时出错的原因。

第二个问题是:

虽然我没有反对在SQLCLR中调用Web服务,但只有当进程完全包含在T-SQL中时才应该这样做。如果您已经使用.NET代码,那么仅执行存储过程来调用Web服务是没有意义的。对于app层和DB层来说,这是非常低效的。

其他几件事:

  1. 您的.NET代码会从方法返回void,因此不能使用捕获@return_value
  2. 请勿使用AddWithValue方法。而是使用正确的数据类型创建每个参数,然后设置该值,然后将其添加到Parameters集合。
  3. 尽管已经提到这个问题,但是关于将来创建这样的参数,即使使用AddAddWithValue("@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()