这是应该由 ssms 作业返回 html 报告的代码。
DECLARE @DataInicialMesAnterior DATE, @DataFinalMesAnterior DATE;
SET @DataInicialMesAnterior = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0);
SET @DataFinalMesAnterior = DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0));
DECLARE @tableHTML2 NVARCHAR(MAX), @corpo2 AS NVARCHAR(50);
SET @tableHTML2 =
N'<font size="1"><H1>Produção Mensal Tecelagem Entre ' + CONVERT(VARCHAR, @DataInicialMesAnterior, 104) + ' - ' + CONVERT(VARCHAR, @DataFinalMesAnterior, 104) + ' </H1> ' +
N'<style> th {color:#FFFFFF; background-color: #6193AC } </style>' +
N'<table border="1" cellpadding="3" cellspacing="0" style="width: 100%">' +
N'<tr><th rowspan="3">Maquina</th><th rowspan="3">Artigo</th><th rowspan="3">Descrição</th><th rowspan="3">Total Metros</th><th rowspan="3">Total Kgs</th></tr>' +
N'<tr></tr><tr><th></th></tr>' +
CAST((
WITH ProductionData AS (
SELECT
'Tear - ' + LTRIM(RTRIM(STR(cast(substring(BI.U_MED1, 2, 2) as int)))) as td,
BI.REF as td1,
ISNULL(ST.design, '') as td2, --design
SUM(CASE WHEN stobs.u_dobramal=1 THEN BI.QTT*2 ELSE bi.qtt END) as 'Metros Produzidos', -- Soma de metros por tear e ref
SUM(CAST(BI.U_MED3 as float)) as 'Kgs Produzidos' -- Soma de kgs por tear e ref
FROM carlom.dbo.BI bi (nolock)
LEFT JOIN carlom.dbo.st ST (nolock) ON ST.ref = BI.REF
INNER JOIN carlom.dbo.stobs stobs (nolock) ON st.ref = stobs.ref
WHERE BI.NDOS = 20
AND BI.u_data2 BETWEEN @DataInicialMesAnterior AND @DataFinalMesAnterior
GROUP BY 'Tear - ' + LTRIM(RTRIM(STR(cast(substring(BI.U_MED1, 2, 2) as int)))), BI.REF, ST.design
), Totals AS (
SELECT
td,
td1,
MAX(td2) as td2,
SUM([Metros Produzidos]) as 'Metros Produzidos',
SUM([Kgs Produzidos]) as 'Kgs Produzidos'
FROM ProductionData
GROUP BY td, td1
HAVING SUM([Metros Produzidos]) > 0 OR SUM([Kgs Produzidos]) > 0
), AllData AS (
SELECT
td,
td1,
MAX(td2) as td2,
SUM([Metros Produzidos]) as 'Metros Produzidos',
SUM([Kgs Produzidos]) as 'Kgs Produzidos'
FROM Totals
GROUP BY td, td1
HAVING SUM([Metros Produzidos]) > 0 OR SUM([Kgs Produzidos]) > 0
), OrderedData AS (
SELECT
td,
td1,
MAX(td2) as td2,
SUM([Metros Produzidos]) as 'Metros Produzidos',
SUM([Kgs Produzidos]) as 'Kgs Produzidos',
0 as TotalOrder
FROM AllData
GROUP BY td, td1
UNION ALL
SELECT
'Total' as td,
'' as td1,
'' as td2,
SUM([Metros Produzidos]) as 'Metros Produzidos',
SUM([Kgs Produzidos]) as 'Kgs Produzidos',
1 as TotalOrder
FROM AllData
)
SELECT
td,
td1,
MAX(td2) as td2,
MAX([Metros Produzidos]) as 'Metros Produzidos',
MAX([Kgs Produzidos]) as 'Kgs Produzidos'
FROM OrderedData
GROUP BY td, td1, TotalOrder
ORDER BY
CASE WHEN TotalOrder = 1 THEN 1 ELSE 0 END,
CASE WHEN ISNUMERIC(SUBSTRING(td, LEN('Tear - ') + 1, LEN(td))) = 1 THEN CAST(SUBSTRING(td, LEN('Tear - ') + 1, LEN(td)) AS INT) ELSE 99999 END,
td
FOR XML PATH('tr'), TYPE
).value('.', 'NVARCHAR(MAX)')) + N'</font></table>';
SET @corpo2 = 'Produção do Mês';
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'PHC',
@recipients = '[email protected]',
@subject = @corpo2,
@body = @tableHTML2,
@body_format = 'HTML';
代码检索以下错误
消息 156,第 15 级,状态 1,第 13 行
关键字“WITH”附近的语法不正确。
消息 319,第 15 级,状态 1,第 13 行
关键字“with”附近的语法不正确。如果此语句是公用表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前一个语句必须以分号终止。
消息 102,第 15 级,状态 1,第 26 行
“,”附近的语法不正确。
消息 102,第 15 级,状态 1,第 36 行
“,”附近的语法不正确。
消息 102,第 15 级,状态 1,第 46 行
“,”附近的语法不正确。
消息 102,第 15 级,状态 1,第 79 行
')' 附近的语法不正确。
您在
CAST
函数中转储了一堆 CTE 声明;那是不允许的。 CTE 必须在语句的“开始”处定义,而不是在中间。您还有一个 CAST
但没有 AS <Data Type>
子句。我解决了一半问题,但您需要添加数据类型。DECLARE @DataInicialMesAnterior DATE, @DataFinalMesAnterior DATE;
SET @DataInicialMesAnterior = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0);
SET @DataFinalMesAnterior = DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0));
DECLARE @tableHTML2 NVARCHAR(MAX), @corpo2 AS NVARCHAR(50);
WITH ProductionData AS (
SELECT
'Tear - ' + LTRIM(RTRIM(STR(cast(substring(BI.U_MED1, 2, 2) as int)))) as td,
BI.REF as td1,
ISNULL(ST.design, '') as td2, --design
SUM(CASE WHEN stobs.u_dobramal=1 THEN BI.QTT*2 ELSE bi.qtt END) as 'Metros Produzidos', -- Soma de metros por tear e ref
SUM(CAST(BI.U_MED3 as float)) as 'Kgs Produzidos' -- Soma de kgs por tear e ref
FROM carlom.dbo.BI bi (nolock)
LEFT JOIN carlom.dbo.st ST (nolock) ON ST.ref = BI.REF
INNER JOIN carlom.dbo.stobs stobs (nolock) ON st.ref = stobs.ref
WHERE BI.NDOS = 20
AND BI.u_data2 BETWEEN @DataInicialMesAnterior AND @DataFinalMesAnterior
GROUP BY 'Tear - ' + LTRIM(RTRIM(STR(cast(substring(BI.U_MED1, 2, 2) as int)))), BI.REF, ST.design
), Totals AS (
SELECT
td,
td1,
MAX(td2) as td2,
SUM([Metros Produzidos]) as 'Metros Produzidos',
SUM([Kgs Produzidos]) as 'Kgs Produzidos'
FROM ProductionData
GROUP BY td, td1
HAVING SUM([Metros Produzidos]) > 0 OR SUM([Kgs Produzidos]) > 0
), AllData AS (
SELECT
td,
td1,
MAX(td2) as td2,
SUM([Metros Produzidos]) as 'Metros Produzidos',
SUM([Kgs Produzidos]) as 'Kgs Produzidos'
FROM Totals
GROUP BY td, td1
HAVING SUM([Metros Produzidos]) > 0 OR SUM([Kgs Produzidos]) > 0
), OrderedData AS (
SELECT
td,
td1,
MAX(td2) as td2,
SUM([Metros Produzidos]) as 'Metros Produzidos',
SUM([Kgs Produzidos]) as 'Kgs Produzidos',
0 as TotalOrder
FROM AllData
GROUP BY td, td1
UNION ALL
SELECT
'Total' as td,
'' as td1,
'' as td2,
SUM([Metros Produzidos]) as 'Metros Produzidos',
SUM([Kgs Produzidos]) as 'Kgs Produzidos',
1 as TotalOrder
FROM AllData
)
SELECT @tableHTML2 =
N'<font size="1"><H1>Produção Mensal Tecelagem Entre ' + CONVERT(VARCHAR, @DataInicialMesAnterior, 104) + N' - ' + CONVERT(VARCHAR, @DataFinalMesAnterior, 104) + N' </H1> ' +
N'<style> th {color:#FFFFFF; background-color: #6193AC } </style>' +
N'<table border="1" cellpadding="3" cellspacing="0" style="width: 100%">' +
N'<tr><th rowspan="3">Maquina</th><th rowspan="3">Artigo</th><th rowspan="3">Descrição</th><th rowspan="3">Total Metros</th><th rowspan="3">Total Kgs</th></tr>' +
N'<tr></tr><tr><th></th></tr>' +
CAST((
SELECT
td,
td1,
MAX(td2) as td2,
MAX([Metros Produzidos]) as 'Metros Produzidos',
MAX([Kgs Produzidos]) as 'Kgs Produzidos'
FROM OrderedData
GROUP BY td, td1, TotalOrder
ORDER BY
CASE WHEN TotalOrder = 1 THEN 1 ELSE 0 END,
CASE WHEN ISNUMERIC(SUBSTRING(td, LEN('Tear - ') + 1, LEN(td))) = 1 THEN CAST(SUBSTRING(td, LEN('Tear - ') + 1, LEN(td)) AS INT) ELSE 99999 END,
td
FOR XML PATH('tr'), TYPE
).value('.', 'NVARCHAR(MAX)') AS <DATA TYPE>) + N'</font></table>';
SET @corpo2 = N'Produção do Mês';
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'PHC',
@recipients = '[email protected]',
@subject = @corpo2,
@body = @tableHTML2,
@body_format = 'HTML';
nvarchar(max)
,但如果您不指定
FOR XML
,无论如何 ,TYPE
都会这样做。代码还存在各种其他问题:
LEFT JOIN
INNER JOIN
是没有意义的:要么两者都应该是 INNER
,要么都是 LEFT
(或者您可以嵌套连接条件)。请勿使用nolock
Totals
AllData
完全相同。没有进行进一步的聚合,因为它们按相同的列进行分组。OrderedData
UNION ALL
也可以使用 GROUPING SETS
来省略。 GROUPING()
函数将告诉您该行是否已分组为列。LTRIM(RTRIM(STR(cast(substring(...) as int))))
int
只是为了将其投射回来?如果您想确保它是 int
而不会引发错误,只需使用 TRY_CAST
。不要在开头添加TEAR -
VARCHAR
NVARCHAR
的长度。请勿使用 ''
[]
。而不是ORDER BY CASE WHEN TotalOrder = 1 THEN 1 ELSE 0 END
ODRER BY TotalOrder
。使用 EOMONTH
DATEFROMPARTS
构造日期。在较新的版本中,您还可以使用 DATETRUNC(month
。
DECLARE @DataFinalMesAnterior DATE = EOMONTH(GETDATE(), -1);
DECLARE @DataInicialMesAnterior DATE = DATEFROMPARTS(DATEPART(year, @DataFinalMesAnterior), DATEPART(month, @DataFinalMesAnterior), 1);
DECLARE @tableHTML2 NVARCHAR(MAX), @corpo2 AS NVARCHAR(50);
WITH ProductionData AS (
SELECT
ISNULL(TRY_CAST(SUBSTRING(BI.U_MED1, 2, 2) as int), 99999) as td,
BI.REF as td1,
ISNULL(ST.design, '') as td2, --design
SUM(BI.QTT * IIF(stobs.u_dobramal = 1, 2, 1)) as [Metros Produzidos], -- Soma de metros por tear e ref
SUM(CAST(BI.U_MED3 as float)) as [Kgs Produzidos] -- Soma de kgs por tear e ref
FROM carlom.dbo.BI bi
INNER JOIN carlom.dbo.st ST ON ST.ref = BI.REF
INNER JOIN carlom.dbo.stobs stobs ON st.ref = stobs.ref
WHERE BI.NDOS = 20
AND BI.u_data2 BETWEEN @DataInicialMesAnterior AND @DataFinalMesAnterior
GROUP BY
ISNULL(TRY_CAST(SUBSTRING(BI.U_MED1, 2, 2) as int), 99999),
BI.REF,
ST.design
),
Totals AS (
SELECT
td AS tdOrdering,
IIF(GROUPING(td) = 0, CONCAT('Tear - ', IIF(td = 99999, NULL, td)), 'Total') AS td,
IIF(GROUPING(td) = 0, td1, '') AS td1,
IIF(GROUPING(td) = 0, MAX(td2), '') as td2,
SUM([Metros Produzidos]) as [Metros Produzidos],
SUM([Kgs Produzidos]) as [Kgs Produzidos],
GROUPING(td) as TotalOrder
FROM ProductionData
GROUP BY GROUPING SETS (
(td, td1),
()
)
HAVING SUM([Metros Produzidos]) > 0
OR SUM([Kgs Produzidos]) > 0
)
SELECT @tableHTML2 =
N'<font size="1"><H1>Produção Mensal Tecelagem Entre ' + CONVERT(NVARCHAR(30), @DataInicialMesAnterior, 104) + N' - ' + CONVERT(NVARCHAR(30), @DataFinalMesAnterior, 104) + N' </H1> ' +
N'<style> th {color:#FFFFFF; background-color: #6193AC } </style>' +
N'<table border="1" cellpadding="3" cellspacing="0" style="width: 100%">' +
N'<tr><th rowspan="3">Maquina</th><th rowspan="3">Artigo</th><th rowspan="3">Descrição</th><th rowspan="3">Total Metros</th><th rowspan="3">Total Kgs</th></tr>' +
N'<tr></tr><tr><th></th></tr>' +
(
SELECT
td,
td1,
td2,
[Metros Produzidos],
[Kgs Produzidos]
FROM OrderedData
ORDER BY
TotalOrder,
tdOrdering
FOR XML PATH('tr')
) + N'</font></table>';