将 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 值“Collect_Date”转换为数据类型 int 时转换失败
将 varchar 值“A0001”转换为数据类型 int 时转换失败
将 varchar 值“xxx”转换为数据类型 int 时,函数错误中的光标转换失败