【问题标题】:CTE triggers casting error from anchor and recursive partCTE 从锚点和递归部分触发铸造错误
【发布时间】:2019-09-27 08:20:33
【问题描述】:

我有一个如下的 CTE,它实际上是从 VSTS 数据中找到所有工作项及其父项。

;with cte(wtype,id,parent,title,ptype,WILevel,ParentTitle) as
(
select WorkItemType,wi_id,parent,title,ParentType,0 as WILevel,'' as ParentTitle from tbl_VSTS_AllWorkItems where Parent is null and state<>'Removed'
union all
select WorkItemType,wi_id,W.parent,W.title,ParentType=t2.wtype,(t2.WILevel+1) as WILevel, t2.title as ParentTitle  from tbl_VSTS_AllWorkItems W inner join cte t2 on t2.id=W.Parent where state<>'Removed'
)

select * from cte where WILevel=0;

但是我得到如下的转换错误。

消息 240,第 16 级,状态 1,第 8 行 递归查询“cte”的“ParentTitle”列中的锚点和递归部分的类型不匹配。

我不明白这个问题,因为标题字段只是 varchar 类型。那么为什么类型不匹配?

【问题讨论】:

标签: sql tsql common-table-expression


【解决方案1】:

我自己承认,我搜索了您的错误消息并发现了this SO question,其中讨论了类似的问题。

这里的技巧是,即使您的两列都是文本,它们也不是同一类型的文本(例如宽度等)。

假设tbl_VSTS_AllWorkItems.title 列是varchar(50),您可以通过将空字符串也转换为varchar(50) 来解决此错误,例如

WITH cte (wtype,id,parent,title,ptype,WILevel,ParentTitle) AS (
    SELECT ..., CAST('' AS varchar(50)) AS ParentTitle
    FROM tbl_VSTS_AllWorkItems
    WHERE ...
    UNION ALL
    SELECT ..., t2.title
    FROM tbl_VSTS_AllWorkItems
    WHERE ...
)

旁注:您只需在联合查询的第一个选择中使用别名。事实上,联合的后续部分中的别名将被忽略。

【讨论】:

  • 由于在第一行的 CTE 声明中提供了列名,因此在锚部分中实际上也不需要别名。 ;)
  • 完美!!!这就是原因..我像这样投射了标题栏,效果很好.. '' as ParentTitle into cast('' as varchar(100)) as ParentTitle
【解决方案2】:

union all 的第一部分,我认为您希望在创建'' as ParentTitle 时明确说明它实际上是列的类型。例如convert(varchar(30), null) as ParentTitle

【讨论】:

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