无法将 CTE 结果分配给 varchar 变量?

Posted

技术标签:

【中文标题】无法将 CTE 结果分配给 varchar 变量?【英文标题】:Cannot assign CTE result to a varchar variable? 【发布时间】:2012-03-02 21:42:31 【问题描述】:

我正在尝试编写以下 SQL。

declare @s varchar(max) = (
  with c as (select ...)
  select a, b, c, d, ....
  from ... join c on .... join c on .... join c on ....
  order by ...
  for xml raw('...'), elements
);

但是,它的语法不正确(以下显示错误消息)。我必须将其转换为子查询吗?我试图避免在多个地方扩展 CTE。

关键字“with”附近的语法不正确。如果此语句是公用表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前面的语句必须以分号结束。

更新:for xmlorder by 使 select @s = ...

【问题讨论】:

【参考方案1】:

您需要将@s 的声明与赋值分开。

这样的东西对你有用。

declare @T table
(
  ID int,
  Col1 int
)

insert into @T values(1, 10),(2, 20)

declare @s varchar(max)

;with C as
(
  select *
  from @T
)
select @s = 
  (
    select *
    from C as C1
      inner join C as C2
        on C1.ID = C2.ID
    for xml raw, elements
  )

select @s

结果:

<row>
  <ID>1</ID>
  <Col1>10</Col1>
  <ID>1</ID>
  <Col1>10</Col1>
</row>
<row>
  <ID>2</ID>
  <Col1>20</Col1>
  <ID>2</ID>
  <Col1>20</Col1>
</row>

【讨论】:

【参考方案2】:

我认为这正是您尝试分配价值的方式。请尝试改用以下方法:

declare @s varchar(max);
with temp as
(
   select ....
  from ... join c on .... join c on .... join c on ....
  for xml raw('...'), elements
)
select @s = value from temp
select @s

正如错误消息所述,您的真正问题是 CTE 之前的语句没有以 ; 终止,这是使用 CTE 时的要求。

我用select 'test' as value 定义了 CTE 而不是您的查询运行了上述内容,它按预期工作。

【讨论】:

for xml 可能使它不可行? 我不确定。我目前无法对其进行测试。我建议尝试我上面提供的方法。您遇到的错误似乎与使用 for xml... 无关 “当 CTE 用于作为批处理一部分的语句中时,它之前的语句必须跟一个分号。” with temp as (select ... for xml...) 需要改为with c as (...), temp(value) as (...) 有人可以向我解释为什么SELECT @s = 有效,而SET @s = 无效吗?【参考方案3】:

好的,我想通了。它不能在一个声明和初始化语句中完成。

declare @s varchar(max);

with c as (select 1 a union all select 2 union all select 3)
, x(s) as (select a from c order by a desc for xml raw('tr'), elements)
select @s = s from x

【讨论】:

@Abe - “原创的秘诀是忘记来源” +1 回答。

以上是关于无法将 CTE 结果分配给 varchar 变量?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我无法将程序中找到的布尔结果的正确值分配给布尔变量并使用结果检查条件?

axios GET 请求有效,但无法将结果内容分配给变量

执行动态查询并将值分配给两个变量

执行动态查询并将值分配给两个变量

将查询结果分配给变量并返回变量

Dexie如何将结果分配给变量? [复制]