【问题标题】:SqlException, Error converting data type nvarchar to intSqlException,将数据类型 nvarchar 转换为 int 时出错
【发布时间】:2017-04-08 04:30:18
【问题描述】:

有一个奇怪的问题,认为它与我的存储过程中的 OUT 参数有关?

存储过程:

ALTER PROCEDURE [dbo].[uspProcessResetRequest] 
    @user uniqueidentifier, 
    @company uniqueidentifier,
    @mobile nvarchar(50) OUT, -- return phone number
    @system nvarchar(256) OUT -- return system name
AS
BEGIN
    SET NOCOUNT ON;

    SET @mobile = 'error' --for debugging
    SET @system = 'error' --for debugging

    -- Select matching row from ResetQueue into temporary table
    INSERT INTO ResetHistory ([User_ID], MobilePhone, Company_ID, [System], [Status], ResetIP)
        SELECT 
            rq.[User_ID], u.MobilePhone, u.Company_ID, rq.[System], '3', rq.ResetIP 
        FROM  
            ResetQueue rq
        INNER JOIN 
            [User] u ON rq.[User_ID] = u.ObjectGuid
        WHERE 
            u.Company_ID = @company 
            AND rq.[User_ID] = @user 
            AND rq.[Status] = '2'           

    SELECT @mobile = u.[MobilePhone] 
    FROM [user] u 
    WHERE u.ObjectGuid = @user

    SELECT @system = rq.[system] 
    FROM ResetQueue rq 
    WHERE rq.[User_ID] = @user

    DELETE FROM ResetQueue 
    WHERE [User_ID] = @user
END

调用 C# 代码:

try
{
    using (SqlConnection conn = new SqlConnection(strConnection))
    {
        using (SqlCommand cmd = new SqlCommand("dbo.uspProcessResetRequest", conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@user", SqlDbType.UniqueIdentifier).Value = strUser;
            cmd.Parameters.AddWithValue("@company", SqlDbType.UniqueIdentifier).Value = strCompany;
            cmd.Parameters.AddWithValue("@mobile", SqlDbType.NVarChar).Direction = ParameterDirection.Output;
            cmd.Parameters.AddWithValue("@system", SqlDbType.NVarChar).Direction = ParameterDirection.Output;

            conn.Open();
            cmd.ExecuteNonQuery();
            conn.Close();

            string[] strResult = new string[] { (string)cmd.Parameters["@mobile"].Value, (string)cmd.Parameters["@system"].Value };

            return strResult;
        }
    }
}
catch (Exception err)
{
    string strError = err.Message; // Log error
    return new string[] { "", "" };
}

存储过程运行良好——所有代码都被执行,但cmd.ExecuteNonQuery(); 抛出异常:

SqlException:将数据类型 nvarchar 转换为 int 时出错。

所以我失去了输出值。

我怀疑 OUT 参数面临一些问题,但似乎无法解决这个问题......

我发现的有关此问题的大多数其他帖子都与提交给 SqlInt 参数的文本值有关。这似乎不是这种情况,因为存储过程实际上会按预期执行和移动数据。

【问题讨论】:

  • 你能用minimal demo替换大量代码来简化你的问题吗?
  • 不 ExecuteNonQuery() 返回一个 int...因此您的存储过程也应该返回一个 int?你可能想调用 ExecuteScalar() 来返回一个对象
  • @Gwasshoppa ExecuteNonQuery 返回 ROWCOUNT 值,而不是存储过程的返回值。
  • Doh...好点...误读了 C# 抱歉
  • user_id 的类型是什么。我赌INT

标签: c# sql sql-server stored-procedures


【解决方案1】:

@Gwashoppa,感谢您花时间回答我的问题。据我了解,返回值不能与 OUTPUT 参数混合。但无论如何我找到了解决方案 - 需要明确设置数据类型和长度:

cmd.Parameters["@mobile"].SqlDbType = SqlDbType.NVarChar;
cmd.Parameters["@mobile"].Size = 50;

我以为 AddWithValue 函数中发生了这种情况,但显然不是。

【讨论】:

    【解决方案2】:

    您的 C# 代码看起来不错...cmd.ExecuteNonQuery(); 行引发异常这一事实表明该错误必须与 SP 使用的某些参数有关。

    您需要逐步隔离您的 SP 以确定问题区域...

    例如,在此语句中,ResetHistory 表是否与您的选择中使用的列类型相同?

    INSERT INTO ResetHistory ([User_ID], MobilePhone, Company_ID, [System], [Status], ResetIP)
    SELECT rq.[User_ID], u.MobilePhone, u.Company_ID, rq.[System], '3', rq.ResetIP
    FROM ResetQueue rq
    ...
    

    在这个语句中,手机列是否返回Varchar值?

    SELECT u.[MobilePhone] 
    FROM [user] u 
    WHERE u.ObjectGuid = @user
    

    在此语句中,系统列是否返回 Varchar 值?

    SELECT rq.[system] 
    FROM ResetQueue rq 
    WHERE rq.[User_ID] = @user
    

    【讨论】:

      猜你喜欢
      • 2015-03-14
      • 2015-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多