SQL Server 2008 - цикл WHILE - PullRequest
       29

SQL Server 2008 - цикл WHILE

0 голосов
/ 18 мая 2018

У меня есть проблема, которую я не могу решить, моя конечная цель - сделать триггер, который запускается каждый раз, когда он вставляется в таблицу 'factura', а затем заполнить промежуточную таблицу, в которой есть только одно поле (varchar max), потому что?, потому что у меня есть компонент в Java, который читает это поле и генерирует файл file.txt, который он позже использовал, но у меня есть проблема, которую я не могу решить, я видел, что может быть с курсором или еще лучше с В то время как цикл, но я запутался, BD-менеджер, который я использую, является SQL Server 2008, запрос на выборку, который я использую для генерации данных, которые будут заполнены в промежуточной таблице в триггере, состоит из двух частей, заголовка и деталей. Я пытаюсь сделать так, чтобы он отображал только одну строку на заголовок, но, поскольку в некоторых случаях более 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 ИТОГО ||||||| 1000 |||| 0,00 | 0,00 | 0,00 || DB | ЧИСЛО 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 ИТОГО ||||||| 1000 |||| 0,00 | 0,00 | 0,00 || DB | ЧИСЛО 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 ИТОГО ||||||| 1000 |||| 0,00 | 0,00 | 0,00 || DB | ЧИСЛО ROW | 220 | NIU | 1 | TODO EL DIA | 8,47 | 10,00 | 1,53 | 10 | 0,00 || 10,00 | 0,00 || 0,00 || DB | ЧИСЛО ROW | 230 | NIU | 1 | 10 MIN FIN DE SEMANA | 16,94 | 0,00 | 3,06 | 10 | 0,00 || 20,00 | 0,00 || 0,00 ||

Кто-нибудь может мне помочь? или дайте мне структуру, чтобы я мог ее достичь, пожалуйста, я был бы очень благодарен.

1 Ответ

0 голосов
/ 21 мая 2018

Вот запрос, который добавит подробные данные, когда есть идентичные данные заголовка. Запрос медленный, так как включает в себя JOIN для строки и большого столбца. Вы можете заменить 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
...