目前我正在重写旧的T-SQL过程,今天我发现了一些困难。
变量中有一个长查询集。
set @Sql='
....
....
where ('+ case when @p_TypeOfDataZak = 1 then 'cdn.MS_VatToDate(TrN_VatYear,
TrN_VatMouth, TrN_VatDay) between cdn.MS_CDNDateToDate('+@DateFromv+') and cdn.MS_CDNDateToDate('+@DateTov+')'
else 'TrN_DataMag between '+@DateFromv+' and '+@DateTov
end +')
....
....
exec (@Sql);
现在我想将其修改为普通查询,但在CASE表达式中使用between语法时遇到了问题。它应该是这样的。
where (case when @p_TypeOfDataZak = 1 then cdn.MS_VatToDate(TrN_VatYear, TrN_VatMouth, TrN_VatDay) between cdn.MS_CDNDateToDate(@DateFromv) and cdn.MS_CDNDateToDate(@DateTov)
else TrN_DataMag between @DateFromv and @DateTov
end )
您应该使用变量和sp_execute_sql
——尤其是在更新代码时!
因此:
set @Sql='
....
....
where (' +
case when @p_TypeOfDataZak = 1 then
then 'cdn.MS_VatToDate(TrN_VatYear, TrN_VatMouth, TrN_VatDay) between cdn.MS_CDNDateToDate(@DateFromv) and cdn.MS_CDNDateToDate(@DateTov)'
else 'TrN_DataMag between @DateFromv and @DateTov
end + ')
....
exec sp_executesql @Sql,
N'@DateTov date, @DateFromv date',
@DateTov=@dateTov, @DateFromv=@DateFromv
初始化后,@Sql
变量是包含以下内容的字符串:
如果@p_TypeOfDataZak = 1
:
where (
cdn.MS_VatToDate(TrN_VatYear, TrN_VatMouth, TrN_VatDay)
between cdn.MS_CDNDateToDate('+@DateFromv+')
and cdn.MS_CDNDateToDate('+@DateTov+')
)
如果@p_TypeOfDataZak <> 1
:
where (
TrN_DataMag between '+@DateFromv+' and '+@DateTov+'
)
如果您想删除case/when
和dynamic
sql构造,请尝试以下操作:
where
(
cdn.MS_VatToDate(TrN_VatYear, TrN_VatMouth, TrN_VatDay)
between cdn.MS_CDNDateToDate('+@DateFromv+')
and cdn.MS_CDNDateToDate('+@DateTov+')
and @p_TypeOfDataZak = 1
)
or
(
TrN_DataMag between '+@DateFromv+' and '+@DateTov+'
and @p_TypeOfDataZak <> 1
)