我有一个用户定义的函数来将整数列表拆分成一个值表。我正在使用它来解析输入以为给定的一组类型或状态选择一组记录。SQL服务器 - 转换失败错误,但不是真的
这工作:
select * from RequestStatus
where RequestStatusUID in (select [value] from dbo.SplitIDs('1,2,3', ','))
这不:
select * from Requests
where RequestStatusUID in (select [value] from dbo.SplitIDs('1,2,3', ','))
的请求的查询将返回错误“转换为varchar值 '1,2,3' 到的数据类型时转换失败int。“两个表上的RequestStatusUID都是int列。这两个解释计划对我来说都是一样的。该函数在无关查询中以完全相同的方式工作。据我所知,只有Requests表有问题。
CREATE TABLE [dbo].[Requests] (
[RequestUID] int IDENTITY(1,1) NOT NULL,
[UserUID] int NOT NULL,
[LocationUID] int NOT NULL,
[DateOpened] date NULL,
[DateClosed] date NULL,
[RequestStatusUID] int NOT NULL,
[DiscussionUID] int NULL,
[RequestTypeUID] int NOT NULL,
[RequestNo] varchar(16) NOT NULL,
[LastUpdateUID] int NOT NULL,
[LastUpdated] date NOT NULL,
CONSTRAINT [PK_Requests] PRIMARY KEY NONCLUSTERED([RequestUID])
如果我使用不同的函数返回VARCHAR处理它的工作和我的RequestStatusUID列转换为VARCHAR,以及:
select * from Requests
where cast(RequestStatusUID as varchar(4)) in (select [value] from dbo.Split('1,2,3', ','))
作为参考,SplitIDs功能我使用(一Arnold Fribble's solution的修改版本)。分割功能没有投为INT末相同:
ALTER FUNCTION [dbo].[SplitIDs] (@str VARCHAR(MAX), @delim char(1)=',')
RETURNS TABLE
AS
RETURN
(
with cte as (
select 0 a, 1 b
union all
select b, cast(charindex(@delim, @str, b) + 1 as int)
from cte
where b > a
)
select cast(substring(@str,a,
case when b > 1 then b-a-1 else len(@str) - a + 1 end) as int) [value]
from cte where a >0
)
我可以使用转换到字符串解决方案,但我真的很想知道这是为什么摆在首位失败。
此外,选择*。这只是我需要有一个变量,而不是字符串文字。 – ERR 2013-03-26 20:01:46
即使我在函数结尾处取消了显式演员,我也无法重现。你能在sqlfiddle.com上设置一个完整的repro吗?还有,你是否尝试过任何返回INT的其他* TVF,或者你是否结婚了这个特定的函数?由于观察到性能问题,我倾向于远离TVF内的递归CTE方法。 – 2013-03-26 20:04:42
我无法在sqlfiddle.com上重现它,直到我添加了外键约束... [链接](http://sqlfiddle.com/#!3/ab4a9/1) – ERR 2013-03-26 20:25:10