C# 对SSIS中的列求和并发送电子邮件

C# 对SSIS中的列求和并发送电子邮件,c#,sql-server,ssis,C#,Sql Server,Ssis,我有一个表格,我需要汇总两列工资和奖金,并通过电子邮件发送给他们 停止使用SSI。我设法写了一个脚本来发送一封电子邮件,但无法用C语言对两列进行求和 public void Main() { String SendMailFrom = Dts.Variables["EmailFrom"].Value.ToString(); String SendMailTo = Dts.Variables["Ema

我有一个表格,我需要汇总两列工资和奖金,并通过电子邮件发送给他们 停止使用SSI。我设法写了一个脚本来发送一封电子邮件,但无法用C语言对两列进行求和

    public void Main()

            {
                String SendMailFrom = Dts.Variables["EmailFrom"].Value.ToString();
                String SendMailTo = Dts.Variables["EmailTo"].Value.ToString();
                MailMessage msg = new MailMessage();
                msg.To.Add(new MailAddress("bbb"));
                msg.From = new MailAddress("ccc");
                msg.Body = "Process is completed successfully.
                               1) Sum of Salary is 1234 
                               2)Sum of Bonus is 1234
                               3) Count of distinct Accounts is 123";//This is the requirement
                msg.Subject = "XYZ PROCESS";
                msg.IsBodyHtml = true;
                DataTable dtResults = new DataTable();
                OleDbConnection dbConnection = new OleDbConnection("xxx");
                SmtpClient client = new SmtpClient();
                client.UseDefaultCredentials = false;
                client.Credentials = new System.Net.NetworkCredential("xxx");
                client.Port = 587; 
                client.Host = "smtp.office365.com";
                client.DeliveryMethod = SmtpDeliveryMethod.Network;
                client.EnableSsl = true;
                try
                {
                    dbConnection.Open();

                    if (dbConnection.State == ConnectionState.Open)
                    {
                        OleDbCommand dbCommand = dbConnection.CreateCommand();
                        dbCommand.CommandType = CommandType.Text;
                        dbCommand.CommandText = "SELECT SUM([Salary]),Sum([Bonus]) FROM table";
                        OleDbDataReader dbReader = dbCommand.ExecuteReader();

                        if (dbReader.HasRows)
                            dtResults.Load(dbReader);

                        string theSum = dtResults.Rows[0]["TOTAL"].ToString();
                        dbReader.Close();
                        dbConnection.Close();
                        client.Send(msg);
                        MessageBox.Show("Email was Successfully Sent ");

                    }
                }



                //try
                //{
                //    client.Send(msg);
                //    MessageBox.Show("Email was Successfully Sent ");
                //}
                catch (Exception ex)
                {
                    throw new Exception("Unable to execute query as requested.", ex);
                    MessageBox.Show(ex.ToString());
                }

                //{
                //    MessageBox.Show(ex.ToString());
                //}
            }

            #region ScriptResults declaration
            /// <summary>
            /// This enum provides a convenient shorthand within the scope of this class for setting the
            /// result of the script.
            /// 
            /// This code was generated automatically.
            /// </summary>
            enum ScriptResults
            {
                Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
                Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
            };
            #endregion

        }
    }

我不是编写C脚本的专家,非常感谢您的帮助

我猜您在这一行的代码中出现了错误,因为您的查询中没有TOTAL列:

string theSum = dtResults.Rows[0]["TOTAL"].ToString();
修改您的SQL查询,它可能会起作用。您可能希望为我刚才为奖励而添加的两个总和添加一个总数:

dbCommand.CommandText = "SELECT SUM([Salary]),Sum([Bonus]) as TOTAL FROM table";

此外,正如billinkc所提到的,您从未对电子邮件中的SUM做过任何处理。

您需要给出SUM列的名称。就像Rick说的,你引用了TOTAL列,但是没有TOTAL列。您正在查询2个合计/总数,因此它们都需要名称,您需要在代码中获取这两个名称,并在电子邮件中按您的意愿格式化它们

dbCommand.CommandText = "SELECT SUM([Salary]) As SalaryTotal, Sum([Bonus]) As BonusTotal FROM table";

string theSum1 = dtResults.Rows[0]["BonusTotal"].ToString();
string theSum2 = dtResults.Rows[0]["SalaryTotal"].ToString();
public string BuildMessageBody()
{
    // Create a message template that will 
    string template = @"Process is completed successfully.
                   1) Sum of Salary is {0}
                   2) Sum of Bonus is {1}
                   3) Count of distinct Accounts is {2}";
    string query = @"SELECT SUM(T.[Salary]) AS TotalSalary, Sum(T.[Bonus]) AS TotalBonus, COUNT(DISTINCT T.AccountNumber) AS UniqueAccounts FROM table AS T";

    string totalSalary = string.Empty;
    string totalBonus = string.Empty;
    string uniqueAccounts = string.Empty;
    string body = string.Empty;

    using(OleDbConnection dbConnection = new OleDbConnection("xxx"))
    {
        dbConnection.Open();
        using (OleDbCommand cmd = new OleDbCommand(query, dbConnection))
        {
            cmd.CommandType = System.Data.CommandType.Text;
            using (OleDbDataReader  reader = cmd.ExecuteReader())
            {
                // This should only ever yield one row due to aggregation in source query
                // But this implementation will result in the last row (arbitrary source sorting)
                // being preserved
                while (reader.Read())
                {
                    // Access by ordinal position
                    totalSalary = reader[0].ToString();
                    totalBonus = reader[1].ToString();
                    uniqueAccounts = reader[2].ToString();
                }
            }
        }

        // At this point, we should have results
        body = string.Format(template, totalSalary, totalBonus, uniqueAccounts);
    }

    return body;
}

像往常一样,把你的问题分解成更小的单元,直到你有了可以解决的问题

我将创建一个名为BuildMessageBody的方法。这将运行查询并切掉所需的元素,然后使用string.Format方法按顺序位置将所需的值替换到消息中

dbCommand.CommandText = "SELECT SUM([Salary]) As SalaryTotal, Sum([Bonus]) As BonusTotal FROM table";

string theSum1 = dtResults.Rows[0]["BonusTotal"].ToString();
string theSum2 = dtResults.Rows[0]["SalaryTotal"].ToString();
public string BuildMessageBody()
{
    // Create a message template that will 
    string template = @"Process is completed successfully.
                   1) Sum of Salary is {0}
                   2) Sum of Bonus is {1}
                   3) Count of distinct Accounts is {2}";
    string query = @"SELECT SUM(T.[Salary]) AS TotalSalary, Sum(T.[Bonus]) AS TotalBonus, COUNT(DISTINCT T.AccountNumber) AS UniqueAccounts FROM table AS T";

    string totalSalary = string.Empty;
    string totalBonus = string.Empty;
    string uniqueAccounts = string.Empty;
    string body = string.Empty;

    using(OleDbConnection dbConnection = new OleDbConnection("xxx"))
    {
        dbConnection.Open();
        using (OleDbCommand cmd = new OleDbCommand(query, dbConnection))
        {
            cmd.CommandType = System.Data.CommandType.Text;
            using (OleDbDataReader  reader = cmd.ExecuteReader())
            {
                // This should only ever yield one row due to aggregation in source query
                // But this implementation will result in the last row (arbitrary source sorting)
                // being preserved
                while (reader.Read())
                {
                    // Access by ordinal position
                    totalSalary = reader[0].ToString();
                    totalBonus = reader[1].ToString();
                    uniqueAccounts = reader[2].ToString();
                }
            }
        }

        // At this point, we should have results
        body = string.Format(template, totalSalary, totalBonus, uniqueAccounts);
    }

    return body;
}
然后,您的原始代码将替换msg.Body的赋值


然后,您可以在try块中删除ScriptMain中的所有数据访问代码,但保留client.Sendmsg;或者您将永远不会发送电子邮件。

错误是?在执行脚本任务时没有错误。但是我不知道如何执行sql查询SELECT SUM[SALLAY],SUM[BOUNS]FROM table捕获输出并将输出附加到msg.body中。我在下面回答,但是为什么不在SSIS之外运行此代码并调试它呢?然后您将知道错误在哪里。此外,在SSIS中运行时,您也不希望显示MessageBox。您正在使用我假设您将使用查询中的值填充的内容构建msg。但是,在赋值之后,您永远不会使用sum的值。您的查询也不会计算帐户数。那么如何编写msg.body?由于我的msg.body需要类似于此流程的内容,因此成功完成后,工资总额为123,奖金总额为234,上述代码大致正确。徒手操作现有代码以适应问题的具体情况