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

T-SQL 高级查询

将 varchar 数据类型转换为 datetime 数据类型导致 TSQL 中的值超出范围

如何把SQL datetime转换成varchar