2012-03-02 34 views
9

Estoy tratando de escribir el siguiente SQL.No se puede asignar el resultado CTE a una variable 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 
); 

Sin embargo, es una sintaxis incorrecta (continuación se muestra el mensaje de error). ¿Debo convertirlo a subconsultas? Estoy tratando de evitar expandir el CTE en múltiples lugares.

Sintaxis incorrecta cerca de la palabra clave 'con'. Si esta instrucción es una expresión de tabla común, una cláusula xmlnamespaces o una cláusula de contexto de seguimiento de cambios, la instrucción anterior debe terminarse con un punto y coma.

Actualización:
El for xml y order by hace select @s = ...

Respuesta

3

Bien, lo descubrí. No se puede hacer en una instrucción de declaración e inicialización.

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

Parece familiar ... –

+2

@Abe - _ "el secreto de la originalidad es olvidar la fuente" _ +1 a su respuesta. –

7

Creo que es sólo la forma en que está intentando asignar el valor. Trate de usar el método siguiente en su lugar:

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 

Como dice el mensaje de error, el problema real es que la declaración antes de su CTE no se termina con un ; que es un requisito cuando se utiliza un CTE.

Ejecuté lo anterior con select 'test' as value definiendo el CTE en lugar de su consulta y funcionó como se esperaba.

+0

El 'para xml' probablemente hace que no sea factible? – ca9163d9

+0

No estoy seguro. No puedo probarlo en este momento. Recomendaría probar el método que proporcioné arriba. El error que estaba obteniendo no parece estar relacionado con el uso de 'for xml' ... –

+0

" Cuando se utiliza un CTE en una declaración que es parte de un lote, la declaración anterior debe ir seguida de un punto y coma " – HABO

10

necesita separar la declaración de @s de la asignación.

Algo como esto funcionará para usted.

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 

Resultado:

<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> 
Cuestiones relacionadas