You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归查询'manager'中'manager_name'列锚点与递归部分类型不匹配排查

递归查询manager_name列类型不匹配问题解决

问题现象

执行递归查询时反复出现以下错误:

Types don't match between the anchor and the recursive part in column "manager_name" of recursive query "manager".

即使对所有列执行了CAST转换,错误仍未消除。

原查询语句

WITH manager (
    full_name,
    first_name,
    email,
    crm_user_id,
    "role",
    parent_role,
    manager_name,
    manager_email,
    crm_manager_id,
    role_path,
    manager_path
)
AS (
    SELECT
        CAST(full_name as VARCHAR(512)),
        CAST(first_name as VARCHAR(512)),
        CAST(email as VARCHAR(512)),
        CAST(crm_user_id as VARCHAR(18)),
        CAST([role] as VARCHAR(128)),
        CAST(parent_role as VARCHAR(128)),
        CAST(NULL as VARCHAR(512)),
        CAST(NULL as VARCHAR(512)),
        CAST(NULL as VARCHAR(18)),
        CAST([role] as VARCHAR(max)),
        CAST(full_name as VARCHAR(max))
    FROM dbo.Forecast_owners
    WHERE parent_role IS NULL
UNION ALL
    SELECT
        CAST(employee.full_name as VARCHAR(512)),
        CAST(employee.first_name as VARCHAR(512)),
        CAST(employee.email as VARCHAR(512)),
        CAST(employee.crm_user_id as VARCHAR(18)),
        CAST(employee.[role] as VARCHAR(128)),
        CAST(employee.parent_role as VARCHAR(128)),
        CAST(manager.full_name as VARCHAR(512)),
        CAST(manager.email as VARCHAR(512)),
        CAST(manager.crm_user_id as VARCHAR(18)),
        CAST((manager.role_path + '/' + employee.[role]) as VARCHAR(max)),
        CAST((manager.manager_path + '/' + employee.full_name) as VARCHAR(max))
    FROM
        dbo.Forecast_owners employee
    JOIN manager ON employee.parent_role = manager.[role]
)
SELECT 
    *
FROM
    manager

表结构DDL

CREATE TABLE Forecast_owners (
    full_name varchar(512) COLLATE Latin1_General_CI_AS NULL,
    first_name varchar(512) COLLATE Latin1_General_CI_AS NULL,
    email varchar(512) COLLATE Latin1_General_CI_AS NULL,
    crm_user_id varchar(18) COLLATE Latin1_General_CI_AS NULL,
    [role] varchar(128) COLLATE Latin1_General_CI_AS NULL,
    parent_role varchar(128) COLLATE Latin1_General_CI_AS NULL
);

服务器排序规则

执行SELECT CONVERT (varchar(256), SERVERPROPERTY('collation'));得到结果:SQL_Latin1_General_CP1_CI_AS

问题原因

错误根源是排序规则不匹配:

  • 锚点查询中,CAST(NULL as VARCHAR(512))这类语句会默认使用服务器排序规则SQL_Latin1_General_CP1_CI_AS
  • 递归查询中,manager.full_name等列来自Forecast_owners表,该表列的排序规则是Latin1_General_CI_AS
  • SQL Server会将排序规则视为类型的一部分,两者不一致时,就会判定为“类型不匹配”

解决方法

方法一:锚点部分指定NULL的排序规则,与表列保持一致

修改锚点查询中三个NULL列的CAST语句,添加排序规则指定:

CAST(NULL as VARCHAR(512)) COLLATE Latin1_General_CI_AS,
CAST(NULL as VARCHAR(512)) COLLATE Latin1_General_CI_AS,
CAST(NULL as VARCHAR(18)) COLLATE Latin1_General_CI_AS,

方法二:递归部分指定列的排序规则,与锚点保持一致

修改递归查询中对应列的CAST语句,添加服务器默认排序规则:

CAST(manager.full_name as VARCHAR(512)) COLLATE SQL_Latin1_General_CP1_CI_AS,
CAST(manager.email as VARCHAR(512)) COLLATE SQL_Latin1_General_CP1_CI_AS,
CAST(manager.crm_user_id as VARCHAR(18)) COLLATE SQL_Latin1_General_CP1_CI_AS,

修改后的完整查询(方法一示例)

WITH manager (
    full_name,
    first_name,
    email,
    crm_user_id,
    "role",
    parent_role,
    manager_name,
    manager_email,
    crm_manager_id,
    role_path,
    manager_path
)
AS (
    SELECT
        CAST(full_name as VARCHAR(512)),
        CAST(first_name as VARCHAR(512)),
        CAST(email as VARCHAR(512)),
        CAST(crm_user_id as VARCHAR(18)),
        CAST([role] as VARCHAR(128)),
        CAST(parent_role as VARCHAR(128)),
        CAST(NULL as VARCHAR(512)) COLLATE Latin1_General_CI_AS,
        CAST(NULL as VARCHAR(512)) COLLATE Latin1_General_CI_AS,
        CAST(NULL as VARCHAR(18)) COLLATE Latin1_General_CI_AS,
        CAST([role] as VARCHAR(max)),
        CAST(full_name as VARCHAR(max))
    FROM dbo.Forecast_owners
    WHERE parent_role IS NULL
UNION ALL
    SELECT
        CAST(employee.full_name as VARCHAR(512)),
        CAST(employee.first_name as VARCHAR(512)),
        CAST(employee.email as VARCHAR(512)),
        CAST(employee.crm_user_id as VARCHAR(18)),
        CAST(employee.[role] as VARCHAR(128)),
        CAST(employee.parent_role as VARCHAR(128)),
        CAST(manager.full_name as VARCHAR(512)),
        CAST(manager.email as VARCHAR(512)),
        CAST(manager.crm_user_id as VARCHAR(18)),
        CAST((manager.role_path + '/' + employee.[role]) as VARCHAR(max)),
        CAST((manager.manager_path + '/' + employee.full_name) as VARCHAR(max))
    FROM
        dbo.Forecast_owners employee
    JOIN manager ON employee.parent_role = manager.[role]
)
SELECT 
    *
FROM
    manager

内容的提问来源于stack exchange,提问作者Pedro Paixao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:10:19