创建动态 SQL 查询的问题
Posted
技术标签:
【中文标题】创建动态 SQL 查询的问题【英文标题】:Issues in creating dynamic SQL query 【发布时间】:2017-09-12 22:20:33 【问题描述】:我试图创建一个动态 SQL 查询,但不幸的是它显示了一个错误:
消息 245,第 16 级,状态 1,第 14 行 从 SimulationVisit SV inner join Students on s 转换 varchar 值 'select count (s.ID), count (distinct (s.ID)) 时转换失败。 ID=SV。学生 ID 内部加入 AC 上的 Activity Context AC。 ID=SV。 ActivityContextID WHERE (AC.TenantID = ' 到数据类型 int。
我的代码
declare @DateRangeStart [DATETIME2](7),
@DateRangeEnd [DATETIME2](7),
@TenantID [SMALLINT] ,
@ActivityContextID [INT],
@StudentID [INT] = NULL
'select count(s.ID),count(distinct(s.ID))
from SimulationVisit SV
inner join Student s on s.ID = SV.StudentID
inner join ActivityContext AC on AC.ID = SV.ActivityContextID
where (AC.TenantID = ' + @TenantID + ' OR @TenantID is null)
and (AC.ID =' + @ActivityContextID + ')
and (SV.StudentID = ' + @StudentID + ')';
请帮我解决这个问题
【问题讨论】:
为什么要为此创建动态 sql 查询。使用普通参数。 【参考方案1】:如果需要动态 sql,则使用参数化动态 sql 查询:
EXEC sp_executesql N'
SELECT COUNT(s.ID),COUNT(distinct(s.ID))
FROM SimulationVisit SV
INNER JOIN Student S ON s.ID=SV.StudentID
INNER JOIN ActivityContext AC ON AC.ID=SV.ActivityContextID
WHERE (AC.TenantID = @TenantID OR @TenantID is null)
AND (AC.ID = @ActivityContextID)
AND (SV.StudentID = @StudentID)',
N' @TenantID [SMALLINT] ,
@ActivityContextID [INT],
@StudentID [INT]',
@TenantID, @ActivityContextID, @StudentID
【讨论】:
【参考方案2】:由于这是动态sql,所以最终的sql语句需要是varchar。相应地转换输入参数
'select count(s.ID),count(distinct(s.ID)) from SimulationVisit SV inner join Student s on s.ID=SV.StudentID
inner join ActivityContext AC on AC.ID=SV.ActivityContextID
WHERE (AC.TenantID = '+Cast(@TenantID as varchar(50))+' OR '+Cast(@TenantID as varchar(50))+' is null)
AND (AC.ID =' +Cast(@ActivityContextID as varchar(50))+')
AND (SV.StudentID = '+Cast(@StudentID as varchar(50))+')'
【讨论】:
【参考方案3】:不要创建连接字符串的查询,这是一种不好的做法。只写:
select count(s.ID),count(distinct(s.ID))
from SimulationVisit SV
inner join Student s
on s.ID=SV.StudentID
inner join ActivityContext AC
on AC.ID=SV.ActivityContextID
WHERE (AC.TenantID = @TenantID OR @TenantID is null)
AND (AC.ID = @ActivityContextID)
AND (SV.StudentID = @StudentID)
【讨论】:
【参考方案4】:如下更新您的查询,您必须将变量转换为字符串/varchar 值才能执行动态查询
DECLARE
@DateRangeStart [DATETIME2](7),
@DateRangeEnd [DATETIME2](7),
@TenantID [SMALLINT] ,
@ActivityContextID [INT],
@StudentID [INT] = NULL
DECLARE @Query VARCHAR(8000)
SET @Query='select count(s.ID),count(distinct(s.ID)) from SimulationVisit SV inner join Student s on s.ID=SV.StudentID
inner join ActivityContext AC on AC.ID=SV.ActivityContextID
WHERE (AC.TenantID = '+CAST(@TenantID AS VARCHAR(10))+' OR @TenantID is null)
AND (AC.ID =' +CAST(@ActivityContextID AS VARCHAR(10))+')
AND (SV.StudentID = '+CAST(@StudentID AS VARCHAR(10))+')'
EXEC(@Query)
【讨论】:
【参考方案5】:将 INT 和 BIGINT 值转换为 VARCHAR 数据类型,格式如下:
'SELECT count(s.ID),count(distinct(s.ID))
FROM SimulationVisit SV
INNER JOIN Student s on s.ID = SV.StudentID
INNER JOIN ActivityContext AC on AC.ID = SV.ActivityContextID
WHERE (AC.TenantID = '+ CAST( @TenantID AS VARCHAR ) + ' OR
@TenantID is null) AND
(AC.ID =' + CAST ( @ActivityContextID AS VARCHAR ) + ')
AND (SV.StudentID = '+ CAST( @StudentID AS VARCHAR ) +')'
【讨论】:
以上是关于创建动态 SQL 查询的问题的主要内容,如果未能解决你的问题,请参考以下文章