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

时间:2018-10-11 20:19:32

标签: sql sql-server

下面是我写的查询

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],       [雇用公司],[就业类型],[状态],[优先级],       [ExperienceLevel],[Salary],[Location],[AssignedRecruiter],       [PipelineCount],[CreationDate],       [部门],[发布状态],当f.Id> 0 THEN 1 ELSE 0 END为时       来自
的最爱       JobListView v左联接(从EntityType ='Job'的收藏夹中选择*       并将IsDeleted = 0和userId ='转换为数据类型int。

我可以知道查询中错过了什么吗?

3 个答案:

答案 0 :(得分:3)

通过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子句中。

答案 1 :(得分: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

答案 2 :(得分:1)

您需要使用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;