我有以下CTE:
;WITH Cte([Type], [Level]) AS
(
SELECT CONVERT(NVARCHAR(60), 'USER_TABLE'), 1
UNION ALL
SELECT CONVERT(NVARCHAR(60), o.type_desc), Cte.[Level] + 1
FROM sys.objects o
JOIN Cte ON 1 = 1
WHERE Level < 3
)
SELECT * FROM Cte
并且它返回消息'类型在锚和递归部分中的递归部分“类型”递归查询“Cte”之间不匹配。 sys.objects.type_desc应该是一个NVARCHAR(60),所以不应该在它上面使用CONVERT但是在收到错误之后我没有添加它以确定或是什么。
如果我在递归部分中将JOIN移除到Cte并硬编码[Level]以使CTE不再递归,则SQL运行正常。如果我将sys.objects的内容插入到临时表中并用临时表替换CTE的递归部分中的sys.objects,则SQL运行正常。任何尝试使用CAST而不是CONVERT或将目标类型从NVARCHAR(60)更改为另一个NVARCHAR或VARCHAR都不会更改结果。
有什么想法在这里发生了什么?
由于
(显然,SQL也没用,它只是一个例子,可以重现我遇到的更大代码时出现的错误。)
编辑:还应该补充一下,我在这里运行SQL Server 2012(尽管我在2014年也尝试过同样的问题)。答案 0 :(得分:1)
更新:是基于加入#tmp表而不是sys.objects的问题的先前版本
这看起来像tempdb和当前数据库之间的排序规则差异。如果您使用一个排序规则安装sql server并使用不同的排序规则创建/恢复数据库,通常会发生这种情况。
系统数据库将使用安装排序规则。大多数情况下会导致#tmp表出现问题。
(基于马丁史密斯的建议解决了这个问题的答案)