【问题标题】:Conversion failed when converting the varchar to data type int: SQL将 varchar 转换为数据类型 int 时转换失败:SQL
【发布时间】:2019-08-01 06:24:41
【问题描述】:

我在 asp.net mvc 中创建一个网络应用程序我有一个如下所示的查询

using (SqlConnection conn = new SqlConnection(_connStr))
{
    conn.Open();

    var p = new DynamicParameters();
    p.Add("@SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
    p.Add("@SP_UserId", userId, dbType: DbType.Int32, direction: ParameterDirection.Input);

    var obj = conn.Query<PendingKmsRequest>(sql: "SELECT [f].[id] AS [FileId],[fvr].[Id] AS [RequestId], [au].[Name]"
                        + ", [fvr].[RequestByUserId], [fvr].[FromDate], [fvr].[ToDate],[f].[Title], [fvr].[Status], [fvr].[StatusRemarks]"
                        + "FROM [dbo].[File] AS[f]"
                        + "INNER JOIN [dbo].[FileViewRequest] AS [fvr] ON [f].[CurrentFileVersionId] = [fvr].[FileVersionId]"
                        + "INNER JOIN [Access].[User] AS [au] ON [fvr].[RequestByUserId] = [au].[Id]"
                        + "WHERE ([fvr].[Status] = 'P' OR ([fvr].[Status] = 'A' AND [fvr].[StatusByUserId] = @SP_UserId AND GETDATE() BETWEEN [fvr].[FromDate] AND [fvr].[ToDate]))"
                        + "AND (SELECT 1 FROM [Access].[UserRoleMap] WHERE UserId=@SP_UserId AND RoleId IN(@SP_RoleId)) = 1", param: p, commandType: CommandType.Text);

    if (obj != null && obj.Count() > 0)
        return obj.ToList();
    else
        return new List<PendingKmsRequest>();
}

注意:角色 id 总是像 (7,8,9) 并且它是数据库中的 int 列。

我在这行代码中得到这个转换错误:

 WHERE UserId = @SP_UserId AND RoleId IN (@SP_RoleId))

这是错误:

将 nvarchar 值 '7,9,10' 转换为数据类型 int 时转换失败。

如何防止出现此错误?

【问题讨论】:

  • RoleID 作为列是一个 int,但是当您的条件包含逗号 ',' 时,您的条件是一个字符串,而不是一个 int。
  • 看解决方案here
  • 您使用的是什么版本的 SQL Server?
  • sql server 2008 我不能使用 string_split

标签: asp.net sql-server dapper dynamicparameters


【解决方案1】:

无需在array 或任何字符串split() 函数中使用转换字符串

如果你有逗号分隔的字符串,那么你可以像下面的步骤检查它,

  1. 如果你有@SP_RoleId = "7, 8, 9"
  2. 您可以将此字符串转换如下
    @SP_RoleId = ",7,8,9," (',' + ltrim(rtrim( @SP_RoleId )) + ',')
  3. 现在使用Like 来检查,UserId,

更新代码如下

using (SqlConnection conn = new SqlConnection(_connStr))
{
    conn.Open();

    var p = new DynamicParameters();
    p.Add("@SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
    p.Add("@SP_UserId", userId, dbType: DbType.Int32, direction: ParameterDirection.Input);

    var obj = conn.Query<PendingKmsRequest>(sql: "SELECT [f].[id] AS [FileId],[fvr].[Id] AS [RequestId], [au].[Name]"
                        + ", [fvr].[RequestByUserId], [fvr].[FromDate], [fvr].[ToDate],[f].[Title], [fvr].[Status], [fvr].[StatusRemarks]"
                        + "FROM [dbo].[File] AS[f]"
                        + "INNER JOIN [dbo].[FileViewRequest] AS [fvr] ON [f].[CurrentFileVersionId] = [fvr].[FileVersionId]"
                        + "INNER JOIN [Access].[User] AS [au] ON [fvr].[RequestByUserId] = [au].[Id]"
                        + "WHERE ([fvr].[Status] = 'P' OR ([fvr].[Status] = 'A' AND [fvr].[StatusByUserId] = @SP_UserId AND GETDATE() BETWEEN [fvr].[FromDate] AND [fvr].[ToDate]))"
                        + "AND (SELECT 1 FROM [Access].[UserRoleMap] WHERE ',' +  lTrim(rTrim(@SP_RoleId)) + ',' like '%,' + lTrim(rTrim(UserId) + ',%' " // Updated line
                        + "AND RoleId IN(@SP_RoleId)) = 1", param: p, commandType: CommandType.Text);

    if (obj != null && obj.Count() > 0)
        return obj.ToList();
    else
        return new List<PendingKmsRequest>();
}

【讨论】:

  • 如果您在@SP_RoleId 中有"7,8,9" 作为字符串,则无需将其转换为数组。您可以在查询字符串的开头和结尾添加逗号,并使用Like 来检查,UserID,ltrim()rtrim() 用于删除多余的空格
  • @Ibrahim Shaikh,答案已更新描述
【解决方案2】:

问题代码中的以下行:

p.Add("@SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);

"7,8,9"是字符串,参数类型DbType.String也是字符串。

但是,您说这是您数据库中的int。这是不匹配的。

此外,您的查询:

WHERE UserId = @SP_UserId AND RoleId IN (@SP_RoleId))

查询正在使用IN 子句。

如果传入IEnumerable,Dapper 可以将您的值转换为IN 子句。

修改如下代码行:

p.Add("@SP_RoleId", new[] {7,8,9}, dbType: DbType.Int32, direction: ParameterDirection.Input);

【讨论】:

    猜你喜欢
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多