将 varchar 值转换为数据类型 int 时转换失败

Posted

技术标签:

【中文标题】将 varchar 值转换为数据类型 int 时转换失败【英文标题】:Conversion failed when converting the varchar value to datatype int 【发布时间】:2018-10-11 20:19:31 【问题描述】:

下面是我写的查询

DECLARE @entityName VARCHAR(20) = 'Job'
DECLARE @sql VARCHAR(MAX); 
DECLARE @userId INT = 4

SET @sql = 'select v.Id,[Title], [HiringCompany], [EmploymentType], 
                   [Status], [Priority], [ExperienceLevel], [Salary], 
                   [Location], [AssignedRecruiter], 
                   [PipelineCount], [CreationDate],
                   [Department], [PublishingStatus], 
                   CASE WHEN f.Id > 0 THEN 1 ELSE 0 END as IsFavourite 
             from JobListView v 
             left join (select * from Favourite 
                        where EntityType = '''+ @entityName +''' 
                          and IsDeleted = 0 and userId = '+ @userId +') f on v.Id = f.EntityId';

EXEC (@sql)  

这是我得到的例外:

转换 varchar 值时转换失败 'select v.Id,[Title], [HiringCompany]、[EmploymentType]、[Status]、[Priority]、 [ExperienceLevel]、[Salary]、[Location]、[AssignedRecruiter]、 [管道计数]、[创建日期]、 [部门],[PublishingStatus],当 f.Id > 0 THEN 1 ELSE 0 END as 最喜欢的来自 JobListView v Left join (select * from Favorite where EntityType = 'Job' 和 IsDeleted = 0 和 userId = ' 到数据类型 int。

我可以知道我在查询中遗漏了什么吗?

【问题讨论】:

你为什么首先使用动态sql?从您发布的内容来看,动态sql根本没有理由。这看起来应该只是一个参数化查询。 我没有发布完整的查询我正在传递动态列名,这就是我使用动态 SQL 的原因,否则就像你说的那样不需要它 【参考方案1】:

通过sp_executesql学习使用参数!

set @sql = '
select v.Id,[Title], [HiringCompany], [EmploymentType], [Status], [Priority], 
      [ExperienceLevel], [Salary], [Location], [AssignedRecruiter], 
      [PipelineCount], [CreationDate],
      [Department], [PublishingStatus], CASE WHEN f.Id > 0 THEN 1 ELSE 0 END as 
IsFavourite
from JobListView v Left join
     (select *
      from Favourite
      where EntityType = @entityName and
            IsDeleted = 0 and
            userId = @userId
     ) f
     on v.Id = f.EntityId';

exec sp_executesql @sql,
                   N'@entityName varchar(20), @userId int', 
                   @entityName=@entityName, @userId=@userId;

您也不需要left join 的子查询。我把它留在了,但过滤条件可以放在外面的where子句中。

【讨论】:

【参考方案2】:

我看不出有任何理由首先使用动态 sql。它只是增加了一层不必要的复杂性。这是没有动态 sql 的代码。

Declare @entityName VARCHAR(20) = 'Job'
    , @userId INT = 4

select v.Id
    ,Title
    , HiringCompany
    , EmploymentType
    , Status
    , Priority
    , ExperienceLevel
    , Salary
    , Location
    , AssignedRecruiter
    , PipelineCount
    , CreationDate
    , Department
    , PublishingStatus
    , CASE WHEN f.Id > 0 THEN 1 ELSE 0 END as IsFavourite 
from JobListView v 
Left join 
(
    select * 
    from Favourite 
    where EntityType = @entityName 
        and IsDeleted = 0 and userId = @userId
) f on v.Id = f.EntityId

【讨论】:

【参考方案3】:

你需要使用CAST:

Declare @entityName VARCHAR(20) = 'Job'
DECLARE @sql NVARCHAR(MAX); 
DECLARE @userId INT = 4;
SET @sql = 'select v.Id,[Title], [HiringCompany], [EmploymentType], 
[Status], 
[Priority], 
[ExperienceLevel], [Salary], [Location], [AssignedRecruiter], 
[PipelineCount], [CreationDate],
[Department], [PublishingStatus], CASE WHEN f.Id > 0 THEN 1 ELSE 0 END as 
IsFavourite from  
JobListView v Left join (select * from Favourite where EntityType = '''+ 
@entityName +''' 
and IsDeleted = 0 and userId = '+ CAST(@userId  AS VARCHAR(10))+') f on v.Id = f.EntityId';
                                 -- here

EXEC (@sql);

正确的方法是使用 sp_executesql:

Declare @entityName VARCHAR(20) = 'Job'
DECLARE @sql VARCHAR(MAX); 
DECLARE @userId INT = 4
SET @sql = 'select v.Id,[Title], [HiringCompany], [EmploymentType], 
[Status], 
[Priority], 
[ExperienceLevel], [Salary], [Location], [AssignedRecruiter], 
[PipelineCount], [CreationDate],
[Department], [PublishingStatus], CASE WHEN f.Id > 0 THEN 1 ELSE 0 END as 
IsFavourite from  
JobListView v Left join (select * from Favourite where EntityType = @EntityName  
and IsDeleted = 0 and userId = @userId) f on v.Id = f.EntityId';

EXEC sp_executesql @sql, N'@EntityName VARCHAR(20), @userId INT',
                   @EntityName, @userId;

【讨论】:

以上是关于将 varchar 值转换为数据类型 int 时转换失败的主要内容,如果未能解决你的问题,请参考以下文章

将 varchar 值转换为数据类型 int 时转换失败

将 varchar 值“Collect_Date”转换为数据类型 int 时转换失败

将 varchar 值“A0001”转换为数据类型 int 时转换失败

将 varchar 值“xxx”转换为数据类型 int 时,函数错误中的光标转换失败

将 varchar 值“FOT”转换为数据类型 int 时转换失败

将 varchar 值“Q4”转换为数据类型 int 时转换失败