0

我有以下 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 年也尝试过同样的操作并且遇到了同样的问题)。

4

1 回答 1

2

更新:基于问题的先前版本,该版本正在加入 #tmp 表而不是 sys.objects

这看起来像是 tempdb 和当前数据库之间的排序规则差异。如果您使用一种排序规则安装 sql server 并使用不同的排序规则创建/恢复数据库,通常会发生这种情况。

系统数据库将使用安装排序规则。大多数情况下会导致#tmp 表出现问题。

(基于马丁的史密斯的建议解决了问题的事实来回答)

于 2015-02-26T14:44:34.393 回答