SQL 递归查询中“(”附近的服务器语法不正确

SQL Server Incorrect syntax near '(' in recursive query

我正在尝试将 IBM db2 查询转换为 SQL 服务器查询。我对WITH AS结构不是很熟悉

db2 查询(有效)是:

with ZoneList (id, name, parent_name, parent_id, level) as 
(select id, name, '', parent_id, 1 as level 
from products.zones where id = 1 
union all 
select z.id, z.name, l.name, z.parent_id, level + 1 
from products.zones z, ZoneList l
where z.parent_id = l.id) 
select id, name || ' (' || parent_name || ')' as description 
from ZoneList
where level = 4 
order by ZoneList.name

我的 SQL 服务器版本是:

with ZoneList (id, name, cast((parent_name) as varchar(45)), parent_id, 
level) as 
(select id, name, cast(('') as varchar(45)), parent_id, 1 as level 
from products.zones where id = 1 
union all 
select z.id, z.name, cast((l.name) as varchar(45)), z.parent_id, level + 1 
from products.zones z, ZoneList l 
where z.parent_id = l.id) 
select id, name + ' (' + parent_name + ')' as description 
from ZoneList 
where level = 4 
order by ZoneList.name

我添加了转换以避免不兼容类型错误,但现在我在'('附近遇到语法错误。

试试这个:

;with ZoneList (id, name, parent_name, parent_id, level)
as (
    select id
        , name
        , cast('' as varchar(45))
        , parent_id
        , 1 as level
    from products.zones
    where id = 1

    union all

    select z.id
        , z.name
        , cast(l.name as varchar(45))
        , z.parent_id
        , level + 1
    from products.zones z
        inner join ZoneList l 
            on z.parent_id = l.id
    )
select id
    , name + ' (' + parent_name + ')' as description
from ZoneList
where level = 4
order by ZoneList.name

您不需要在第一行中进行任何显式转换,因为在第一行中您枚举了 CTE 的列,您没有定义它们的数据类型或大小等。

您甚至可以完全删除 CTE 顶部的列枚举,只要您为 CTE 中的每一列添加别名,例如:

;with ZoneList
as (
    select id
        , name
        , cast('' as varchar(45)) as [parent_name]
        , parent_id
        , 1 as level
    from products.zones
    where id = 1

    union all

    select z.id
        , z.name
        , cast(l.name as varchar(45))  as [parent_name]
        , z.parent_id
        , level + 1
    from products.zones z
        inner join ZoneList l 
            on z.parent_id = l.id
    )
select id
    , name + ' (' + parent_name + ')' as description
from ZoneList
where level = 4
order by ZoneList.name

common table expression 的列列表不是您要转换该值的位置。

with ZoneList  (id, name, parent_name, parent_id, level) as (
select 
    id
  , name
  , cast(('') as varchar(45)) as parent_name
  , parent_id
  , 1 as level 
from products.zones where id = 1 

union all 

select 
    z.id
  , z.name
  , cast((l.name) as varchar(45)) as parent_name
  , z.parent_id
  , level + 1 
from products.zones z
  inner join ZoneList l 
    on z.parent_id = l.id
) 
select 
    id
  , name + ' (' + parent_name + ')' as description 
from ZoneList 
where level = 4 
order by ZoneList.name