SQL 函数:将变量从 varchar 转换为 tinyint
Posted
技术标签:
【中文标题】SQL 函数:将变量从 varchar 转换为 tinyint【英文标题】:SQL Function: convert variable from varchar into tinyint 【发布时间】:2018-12-05 13:01:06 【问题描述】:我创建了一个函数,我在其中放入了 3 个变量:
@yy int、@kW int、@Wert varchar(50)
在这个函数内部,我将值插入@return_variable。
@Wert 出现如下问题:'14,15,1,2,4,5,6,7,27'
create FUNCTION [dbo].[F_Work](@yy int, @kW int, @Wert varchar(50) )
RETURNS
@return_variable TABLE
( Stunden int,
kW int,
Wert varchar(50)
)
AS
BEGIN
declare @Tag date;
declare @wk int ;
BEGIN
set @TAg = (select top 1 StartTime from [dbo].[Work]
where DATEPART(ISO_WEEK, StartTime) = @kW and DATEPART( YY, StartTime) = @yy order by Starttime desc)
Insert into @return_variable (Stunden, kW, Wert )
select SUM(ROUND(CAST(DATEDIFF(minute, A.StartTime, A.EndTime) AS float) / 60, - 0)) , DATEPART( ISO_WEEK, A.StartTime ) as KW, B.Wert
FROM
[dbo].[Work] A join
[dbo].[Workload] B on A.TS_ID = B.TS_ID
where
A.TS_ID in (@Wert )
group by DATEPART( ISO_WEEK, A.StartTime ), B.Wert
order by 3,2
END
return
END
-- select Stunden from [dbo].[F_Work](2018,40,'14,15,1,2,4,5,6,7,27')
我收到一个错误: 将 varchar 值 '14,15,1,2,4,5,6,7,27' 转换为数据类型 tinyint 时转换失败。
如何在函数内部输入这个值。
【问题讨论】:
你不明白错误的哪一部分?您不应该将数字列表作为字符串传递。研究定义表类型以将列表传递给存储函数。IN
不能那样工作。有alternate approaches。
问题是,我不能在函数内部进行 CAST。
如果您包含重现该案例所需的完整 SQL,包括创建表,将很容易得到答案。但是 in 需要一个整数序列,并且您不能将字符串与序列本身一起传递,除非您将 sql 命令组合为要使用带有 OUTPUT 的 sp_executesql 命令执行的字符串
如果您将其设为内联表值函数,您将获得一些明确的性能优势。你这里有多个语句,它们的性能通常比标量函数还要差。
【参考方案1】:
在像where A.TS_ID in (@Wert)
这样的表达式中,参数不会被它的字符串表示“替换”并执行结果。您可以使用动态 SQL 执行此操作 - 将查询构造为字符串并使用 sp_executesql
执行它。
如果您使用的是 SQL Server 2016 或更高版本,则可以利用 STRING_SPLIT 函数并将查询更改为类似的内容:
where A.TS_ID in (select try_cast(value as int) from STRING_SPLIT(@Wert, ','))
但最好的解决方案是只传递列表 if 值作为真正的列表,而不是作为逗号分隔值的字符串。您可以通过使用一列定义用户定义的表类型并将@Wert 参数设置为table-valued parameter 来做到这一点:
CREATE TYPE dbo.ListOfInts AS TABLE (IntValue INT);
GO
然后将函数的定义更改为:
create FUNCTION [dbo].[F_Work](@yy int, @kW int, @Wert dbo.ListOfInts READONLY)
然后你可以在你的查询中使用它:
where A.TS_ID in (select IntValue from @Wert)
【讨论】:
听起来不错,但输入值 (@Wert) 是 SQL 格式的 varchar,而不是整数。我必须格式化吗?我得到了答案:操作数类型冲突:varchar 与 ListOfInts 不兼容 当然,如果你改变了参数的类型,你也应该改变你调用函数的方式!只需声明一个这种类型的表变量declare @Wert dbo.ListOfInts
,在其中插入值insert into @Wert(IntValue) values(1),(2),(3)
,然后调用将这个变量作为参数传递的函数。
我必须拆分这些值吗?声明@Wert dbo.ListOfInts insert into @Wet(IntValue) values('14,15,1,2,4,5,6,7,27') 有同样的错误
是的,我在之前的评论中展示过。您必须插入像这样的值declare @Wert dbo.ListOfInts insert into @Wet(IntValue) values(14),(15),(1),(2),(4),(5),(6),(7),(27)
。
在 SQL 上它可以工作 :-) 我怎样才能赋予 ListOfInts 的权利?通常它:将 ListOfInts 上的选择(或执行)授予 USERNAME。在这种情况下它不起作用。以上是关于SQL 函数:将变量从 varchar 转换为 tinyint的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 将变量 varchar 字段转换为货币/小数/带小数位的东西
在sql查询中,如何将string类型的变量转换为varchar
在单个查询中将VARCHAR(max)列转换为大写,然后转换为XML