Sql server 表值函数不起作用的子查询
运行此命令时出现以下错误 将varchar值“1,2”转换为数据类型时,转换失败 内部的 代码:Sql server 表值函数不起作用的子查询,sql-server,tsql,Sql Server,Tsql,运行此命令时出现以下错误 将varchar值“1,2”转换为数据类型时,转换失败 内部的 代码: 试试这个。此拆分可以在没有函数的情况下使用 CREATE function [dbo].[FN_SplitStrings] ( @StringToSplit varchar(8000), @Separator varchar(128) ) RETURN TABLE AS RETURN with indices as ( sele
试试这个。此拆分可以在没有函数的情况下使用
CREATE function [dbo].[FN_SplitStrings]
(
@StringToSplit varchar(8000),
@Separator varchar(128)
)
RETURN TABLE
AS
RETURN
with indices as
(
select
0 S, 1 E
union all
select
E, charindex(@Separator, @StringToSplit, E) + len(@Separator)
from
indices
where E > S
)
select
substring(@StringToSplit,S, case when E > len(@Separator)
then e-s-len(@Separator) else len(@StringToSplit) - s + 1 end) String ,
S StartIndex
from
indices
where
S > 0
查询
ALTER FUNCTION dbo.FN_SplitStrings(@StringToSplit varchar(8000),@Separator char(1))
RETURNS table
AS
RETURN (
WITH splitter_cte AS (
SELECT CHARINDEX(@Separator, @StringToSplit) as pos, 0 as lastPos
UNION ALL
SELECT CHARINDEX(@Separator, @StringToSplit, pos + 1), pos
FROM splitter_cte
WHERE pos > 0
)
SELECT SUBSTRING(@StringToSplit, lastPos + 1,
case when pos = 0 then 80000
else pos - lastPos -1 end) as String
FROM splitter_cte
)
where S>0
,并使用1,2
执行该函数,则函数的结果为:
DECLARE @temp AS TABLE (id INT, NAME VARCHAR(20) )
DECLARE @str VARCHAR(20) = '1,2'
INSERT INTO @temp (id, NAME)
VALUES (1, ''), (2, ''), (2, '')
SELECT *
FROM @temp a
WHERE id IN ((SELECT String FROM dbo.FN_SplitStrings(@str,',')))
注意第一行的值是1,2
当优化器处理查询时,在计算函数的where子句之前,将对列id
进行比较。在这种比较中,您有一个隐式转换为int
,而1,2
不能转换为int
要解决此问题,您可以确保split函数的String列始终是int
(可能在过程中更改列的名称)
想用表值函数解决问题。谢谢你的回答。你能发布函数吗?这可能是因为函数中存在错误@MujahidAbove我添加了一个函数,这个函数只用于分割字符串,对吗@圣战者
ALTER FUNCTION dbo.FN_SplitStrings(@StringToSplit varchar(8000),@Separator char(1))
RETURNS table
AS
RETURN (
WITH splitter_cte AS (
SELECT CHARINDEX(@Separator, @StringToSplit) as pos, 0 as lastPos
UNION ALL
SELECT CHARINDEX(@Separator, @StringToSplit, pos + 1), pos
FROM splitter_cte
WHERE pos > 0
)
SELECT SUBSTRING(@StringToSplit, lastPos + 1,
case when pos = 0 then 80000
else pos - lastPos -1 end) as String
FROM splitter_cte
)
DECLARE @temp AS TABLE (id INT, NAME VARCHAR(20) )
DECLARE @str VARCHAR(20) = '1,2'
INSERT INTO @temp (id, NAME)
VALUES (1, ''), (2, ''), (2, '')
SELECT *
FROM @temp a
WHERE id IN ((SELECT String FROM dbo.FN_SplitStrings(@str,',')))
String
------
1,2
1
2
select
cast(substring(@StringToSplit,S, case when E > len(@Separator)
then e-s-len(@Separator)
else len(@StringToSplit) - s + 1
end) as int) String ,