【问题标题】:sys.objects.type_desc column won't match with anchor in recursive CTEsys.objects.type_desc 列与递归 CTE 中的锚点不匹配
【发布时间】:2015-02-26 14:28:15
【问题描述】:

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

【问题讨论】:

  • 为我工作。如果在 CTE 的两个部分的该列之后添加 COLLATE DATABASE_DEFAULT 会怎样?
  • 有趣...现在可以了!这两个表达式如何使用不同的排序规则?
  • type_desc 的排序规则是 Latin1_General_CI_AS_KS_WS,而字符串文字的排序规则应该是 DATABASE_DEFAULT(我认为)。

标签: sql-server common-table-expression type-conversion sqldatatypes system-tables


【解决方案1】:

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

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

系统数据库将使用安装排序规则。最常导致#tmp 表出现问题。

(根据 Martin 的 Smith 的建议解决问题的事实来回答)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-30
    • 2014-07-13
    • 2019-05-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多