2012-03-02 61 views
9

我正在嘗試編寫以下SQL。無法將CTE結果分配給varchar變量?

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 = ...

回答

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 
+2

看起來很熟悉...... – 2012-03-02 22:13:01

+2

@Abe - _「原創性的祕訣就是忘記來源」__1給你的答案。 – 2013-11-25 14:43:56

7

我認爲這只是您要分配價值的方式。嘗試使用下面的方法來代替:

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而不是您的查詢,並按預期工作。

+0

的'爲xml'可能使得可行不? – ca9163d9 2012-03-02 21:54:58

+0

我不確定。目前我無法測試它。我會建議嘗試我上面提供的方法。您得到的錯誤似乎與使用'for xml'沒有關係...... – 2012-03-02 22:00:59

+0

「如果CTE用於作爲批處理一部分的語句中,則在它之前的語句必須後跟分號「。 (...),溫度(值)爲(...)'時,需要將temp(as ... for xml ...)''temp'改爲' – HABO 2012-03-02 22:10:52

10

您需要將@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>