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
我有一个我无法解决的问题,我的最终目标是制作一个每次插入'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