带有 html 报告的 SQL 作业

问题描述 投票:0回答:2

这是应该由 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 行
')' 附近的语法不正确。

html sql tsql ssms
2个回答
0
投票

您在

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';



0
投票
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>';
© www.soinside.com 2019 - 2024. All rights reserved.