生成 HTML 响应的存储过程不起作用

Posted

技术标签:

【中文标题】生成 HTML 响应的存储过程不起作用【英文标题】:Stored procedure to generate HTML response doesnot work 【发布时间】:2022-01-08 09:40:26 【问题描述】:

我正在尝试从存储过程中获取 html,以便可以在我的 SSIS 包中使用此存储过程来发送带有此正文的电子邮件。

这是 SQL 查询:

SELECT 
    cus.CustomerNumber AS CustomerNumber,
    cus.Location AS ReceivingLocation, 
    i.StrainName AS StrainName, i.StrainCode AS StrainCode,
    i.Age AS Age, i.Sex AS Sex, 
    i.Genotype AS Genotype, i.RoomNumber AS SentFrom,
    io.OrderQuantity AS OrderQuantity
FROM 
    [dbo].[MouseOrder] mo
JOIN 
    [dbo].[Customer] cus ON cus.Customer_ID = mo.CustomerId
JOIN 
    [dbo].[InventoryOrder] io ON io.OrderId = mo.MouseOrder_ID
JOIN 
    [dbo].[Inventory] i ON i.Inventory_ID =  io.InventoryId 
WHERE 
    mo.OrderDate = CONVERT(date, GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time') 
    AND mo.SAMAccountEmail = 'abc.def@inc.org'

我尝试将其作为存储过程执行,以便它可以生成 HTML 响应

CREATE PROCEDURE GenerateEmailBody
AS
BEGIN
    DECLARE @xhtmlBody XML,
            @body NVARCHAR(MAX),
            @tableCaption VARCHAR(30) = 'Orderlist';

    SET @xhtmlBody = (SELECT (
SELECT cus.CustomerNumber as CustomerNumber,cus.Location as ReceivingLocation, 
       i.StrainName as StrainName,i.StrainCode as StrainCode,i.Age as Age,
       i.Sex as Sex,i.Genotype as Genotype,i.RoomNumber as SentFrom,io.OrderQuantity as OrderQuantity
FROM [dbo].[MouseOrder] mo
JOIN [dbo].[Customer] cus on cus.Customer_ID = mo.CustomerId
JOIN [dbo].[InventoryOrder] io on io.OrderId = mo.MouseOrder_ID
JOIN [dbo].[Inventory] i on i.Inventory_ID =  io.InventoryId 
WHERE mo.OrderDate = convert(date,getdate() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time') and mo.SAMAccountEmail = 'abc.def@inc.org'
FOR XML PATH('row'), TYPE, ROOT('root'))
.query('<html><head>
            <meta charset="utf-8"/>
            (: including embedded CSS styling :)
            <style>
            table <![CDATA[ border-collapse: collapse;  width: 300px; ]]>
            th <![CDATA[ background-color: #4CAF50; color: white; ]]>
            th, td <![CDATA[  text-align: left; padding: 8px; ]]>
            tr:nth-child(even) <![CDATA[ background-color: #f2f2f2; ]]>
            #green <![CDATA[ background-color: lightgreen; ]]>
         </style>
         </head>
         <body>
<table border="1">
   <caption><h2>sql:variable("@tableCaption")</h2></caption>
   <thead>
      <tr>
        <th>Cust Numb</th>
        <th>Rec Location</th>
        <th>Strain</th>
        <th>Strain Code</th>
        <th>Age</th>
        <th>Sex</th>
        <th>Genotype</th>
        <th>Sent From</th>
        <th>Order Quantity</th>
      </tr>
   </thead>
   <tbody>

    for $row in /root/row
    return <tr>
            <td>data($row/CustomerNumber)</td>
            <td>data($row/ReceivingLocation)</td>
            <td>data($row/StrainName)</td>
            <td>data($row/StrainCode)</td>
            <td>data($row/Age)</td>
            <td>data($row/Sex)</td>
            <td>data($row/Genotype)</td>
            <td>data($row/SentFrom)</td>
            <td>data($row/OrderQuantity)</td>
        </tr>

</tbody></table></body></html>'));

SELECT @xhtmlBody;

SET @body = CAST(@xhtmlBody AS NVARCHAR(MAX));
END
GO

当我尝试执行存储过程时,它返回 int,如下所示:

这是我第一次尝试存储过程 - 我不确定我错过了什么 - 非常感谢任何帮助

******编辑******

执行 SQL 任务

Scipt 如下所示

namespace ST_c2e68b3edd6842c4a6554376987c97c1

    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    

        enum ScriptResults
        
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        

        public void Main()
        
            string data = Dts.Variables["User::EmailData"].Value.ToString();
            SendEmail(data);
            Dts.TaskResult = (int)ScriptResults.Success;
        

        private void SendEmail(string messageBody)
        
            ConnectionManager smtpConnectionManager = Dts.Connections["SMTP Connection Manager"];
            SmtpClient emailClient = new SmtpClient(smtpConnectionManager.Properties["SmtpServer"].GetValue(smtpConnectionManager).ToString());

            MailMessage email = new MailMessage();
            email.Priority = MailPriority.Normal;
            email.IsBodyHtml = true; 
            email.From = new MailAddress("abc.def@inc.org");
            email.To.Add("abc.def@inc.org"); 
            email.Body = messageBody;
            emailClient.Send(email);
      

它会抛出类似的错误

Error: 0xC002F210 at Execute SQL Task, Execute SQL Task: Executing the query "EXEC dbo.GenerateEmailBody ?" failed with the following error: "Parameter name is unrecognized.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly. Task failed: Execute SQL Task

【问题讨论】:

那是因为存储过程只会返回一个整数。它用于指示执行的状态。您需要使用 OUTPUT 参数来保存您在此处尝试的数据。 您的存储过程正在运行。 ???您需要按如下方式启动:EXEC dbo.GenerateEmailBody @YitzhakKhabinsky 如何在 where 子句中参数化这个 mo.SAMAccountEmail 以便我可以将值动态传递给 SP 【参考方案1】:

假设您想要@body,您可以将其设为输出参数:

CREATE PROCEDURE GenerateEmailBody (@body NVARCHAR(MAX) OUTPUT)
AS
BEGIN
DECLARE @xhtmlBody XML
      , @tableCaption VARCHAR(30) = 'Orderlist';
...

然后这样称呼它:

DECLARE @return_value int
DECLARE @html NVARCHAR(MAX)

exec @return_value = [dbo].[GenerateEmailBody] @html OUTPUT
select @html

【讨论】:

【参考方案2】:

如下:

SQL

CREATE PROCEDURE dbo.usp_GenerateEmailBody
(
   @SAMAccountEmail VARCHAR(100)
)
AS
BEGIN
...
... and mo.SAMAccountEmail = @SAMAccountEmail -- usage of the SP parameter

【讨论】:

非常感谢您耐心地帮助我让这件事正常工作。非常感谢。我再次陷入困境。我已经编辑了现在失败的问题 @对不起,我在办公室无法连接

以上是关于生成 HTML 响应的存储过程不起作用的主要内容,如果未能解决你的问题,请参考以下文章

VS 2010 - 带有 MySql 存储过程的实体框架似乎不起作用

执行存储过程不起作用,但在存储过程中工作的单个语句

存储过程不起作用,我不知道为啥

.NET Oracle Provider:为啥我的存储过程不起作用?

更新存储过程在 SQL Server 中不起作用

实体框架 4 函数导入不起作用