SQL Server 2008 - WHILE 循环

SQL Server 2008 - WHILE Loop

我有一个我无法解决的问题,我的最终目标是制作一个每次插入'factura'table时运行的触发器,然后填充一个中间table 只有一个字段(varchar max),因为?,因为我在 Java 中有一个组件读取这个字段并生成一个他后来使用的 file.txt,但我有一个问题,我无法解决,我看到游标可能是什么,或者更好的是 while 循环但我很纠结,我使用的 BD 管理器是 SQL Server 2008,我使用的 select 查询生成将在触发器中的中间 table 中填充的数据,由两部分组成, header 和细节,我试图做的是它只显示每个 [= 一行29=],但由于在某些情况下有超过 1 个详细信息,因此它显示重复的行。

这是我的查询:

select 
    --HEADER(CB),
    'CB' + '|' + CONVERT(varchar(10),(CONVERT(DATE, f.FECHA))) + '|' +
       '20601140897' + '|' + '03' + '|' +
       SUBSTRING(f.SERIE, 1, 2) + '0' + SUBSTRING(f.SERIE, 3, 2) + '-' + 
       REPLACE(STR(f.NUMERO, 8), SPACE(1), '0') + '|' + 
       CASE 
          WHEN f.CODIGO = '' THEN '99999999' 
          ELSE f.CODIGO 
       END + '|' + '0' + '|' +
       CASE 
          WHEN f.NOMBRE =''  THEN 'Clientes varios' 
          ELSE f.NOMBRE  
       END + '|PEN|' +
       CONVERT(varchar(13), (CAST(f.SUBTOTAL AS decimal(10, 2)))) + 
       '|0.00|0.00|' +
       CONVERT(varchar(13), (CAST(f.IMPUESTO AS decimal(10, 2)))) + 
       '|0.00|0.00|0.00|0.00|' +
       CONVERT(varchar(13), (cast(f.TOTAL as  decimal(10, 2)))) + '|0.00|0.00|' +
       'MONTO TOTAL' + '|||||||1000||||0.00|0.00|0.00||' + CHAR(13) + CHAR(10) +
  --DETAIL(DF)
  'DB' + '|' + 'NUMBER OF ROW' + '|' + d.PRODUCTO + '|' + 'NIU' + '|' + '1' + '|' +
     d.DESCRIPCIO + '|' + CONVERT(varchar(13),(ROUND((d.PRECIO/1.18), 2))) + '|' +
     CONVERT(varchar(13), (cast(d.PRECIO as decimal(10, 2)))) + '|' +
     CONVERT(varchar(13), (ROUND(((d.PRECIO/1.18) * 0.18), 2))) + '|10|0.00||' +
     CONVERT(varchar(13), (cast(d.TOTAL as decimal(10, 2)))) + '|0.00||0.00||'
FROM
    factura f 
FULL JOIN
    detalle d ON f.NUMERO = d.NUMERO 
FULL JOIN
    clientes c ON f.CODIGO = c.codigo

这是它显示的内容:

CB|2017-10-08|20601140897|03|B001-00002224|000700323|0|Clientes varios|PEN|25.42|0.00|0.00|4.58|0.00|0.00|0.00|0.00|30.00|0.00|0.00|MONTO TOTAL|||||||1000||||0.00|0.00|0.00|| DB|NUMBER OF ROW|220|NIU|1|TODO EL DIA|8.47|10.00|1.53|10|0.00||10.00|0.00||0.00||

CB|2017-10-08|20601140897|03|B001-00002224|000700323|0|Clientes varios|PEN|25.42|0.00|0.00|4.58|0.00|0.00|0.00|0.00|30.00|0.00|0.00|MONTO TOTAL|||||||1000||||0.00|0.00|0.00|| DB|NUMBER OF ROW|230|NIU|1|10 MIN FIN DE SEMANA|16.94|20.00|3.06|10|0.00||20.00|0.00||0.00||

我要找的东西:

CB|2017-10-08|20601140897|03|B001-00002224|000700323|0|Clientes varios|PEN|25.42|0.00|0.00|4.58|0.00|0.00|0.00|0.00|30.00|0.00|0.00|MONTO TOTAL|||||||1000||||0.00|0.00|0.00|| DB|NUMBER OF ROW|220|NIU|1|TODO EL DIA|8.47|10.00|1.53|10|0.00||10.00|0.00||0.00|| DB|NUMBER OF ROW|230|NIU|1|10 MIN FIN DE SEMANA|16.94|0.00|3.06|10|0.00||20.00|0.00||0.00||

有人可以帮助我吗?或者给我一个能够实现它的结构,我将不胜感激

这里是查询,当有相同的header数据时,它将追加详细数据。查询很慢,因为它涉及字符串和大列上的 JOIN,您可以用临时 table 替换 CTE,并通过添加索引可能会提供更好的性能。

;WITH CTE AS (
select 
    --HEADER(CB),
    'CB' + '|' + CONVERT(varchar(10),(CONVERT(DATE, f.FECHA))) + '|' +
       '20601140897' + '|' + '03' + '|' +
       SUBSTRING(f.SERIE, 1, 2) + '0' + SUBSTRING(f.SERIE, 3, 2) + '-' + 
       REPLACE(STR(f.NUMERO, 8), SPACE(1), '0') + '|' + 
       CASE 
          WHEN f.CODIGO = '' THEN '99999999' 
          ELSE f.CODIGO 
       END + '|' + '0' + '|' +
       CASE 
          WHEN f.NOMBRE =''  THEN 'Clientes varios' 
          ELSE f.NOMBRE  
       END + '|PEN|' +
       CONVERT(varchar(13), (CAST(f.SUBTOTAL AS decimal(10, 2)))) + 
       '|0.00|0.00|' +
       CONVERT(varchar(13), (CAST(f.IMPUESTO AS decimal(10, 2)))) + 
       '|0.00|0.00|0.00|0.00|' +
       CONVERT(varchar(13), (cast(f.TOTAL as  decimal(10, 2)))) + '|0.00|0.00|' +
       'MONTO TOTAL' + '|||||||1000||||0.00|0.00|0.00||' + CHAR(13) + CHAR(10) HeaderData,
  --DETAIL(DF)
  'DB' + '|' + 'NUMBER OF ROW' + '|' + d.PRODUCTO + '|' + 'NIU' + '|' + '1' + '|' +
     d.DESCRIPCIO + '|' + CONVERT(varchar(13),(ROUND((d.PRECIO/1.18), 2))) + '|' +
     CONVERT(varchar(13), (cast(d.PRECIO as decimal(10, 2)))) + '|' +
     CONVERT(varchar(13), (ROUND(((d.PRECIO/1.18) * 0.18), 2))) + '|10|0.00||' +
     CONVERT(varchar(13), (cast(d.TOTAL as decimal(10, 2)))) + '|0.00||0.00||' DetailData
FROM    factura f FULL JOIN    detalle d ON f.NUMERO = d.NUMERO 
        FULL JOIN    clientes c ON f.CODIGO = c.codigo
    )

    select HeaderData+STUFF((SELECT '|'+ DetailData
                             FROM CTE C
                             WHERE C.HeaderData=T.HeaderData
                             FOR XML PATH('')),1,1,'')
    FROM CTE T
    GROUP BY HeaderData