Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 表值函数不起作用的子查询_Sql Server_Tsql - Fatal编程技术网

Sql server 表值函数不起作用的子查询

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

运行此命令时出现以下错误

将varchar值“1,2”转换为数据类型时,转换失败 内部的

代码:


试试这个。此拆分可以在没有函数的情况下使用

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 ,