Форматирование результатов SQL-запросов в консольное приложение C # EMail Body (SMTP) - PullRequest
0 голосов
/ 29 мая 2018

Доброе утро, переполнение стека, я пытаюсь выяснить, как отформатировать результаты SQL-запроса в теле письма.Однако есть несколько ловушек - я использую строки подключения App.config и, хотя я ссылаюсь только на один сервер, мне нужно сослаться на 7 разных баз данных.Чтобы еще больше запутать ситуацию, я буду выполнять один и тот же запрос на всех 7 БД и хотел бы объединить результаты в симпатичную небольшую таблицу в теле письма.Я использую библиотеку классов для отправки электронных писем, так что я почти все понял, кроме как запросить все 7 БД и объединить данные в одну таблицу.

Я использую SMTP, и это консольное приложение.

Обратите внимание, что это мой первый вопрос, который я когда-либо публиковал в стеке, и я тщательно его изучил.Я знаю, что он сказал, чтобы опубликовать код, но у меня пока нет кода, написанного для него.Мне просто нужно место, чтобы начать!Я гораздо более опытен в SQL, чем в C #, поэтому, если это основная проблема, я прошу прощения.Если вам нужна дополнительная информация по моему вопросу, пожалуйста, дайте мне знать!

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Я предположил, что вы будете запрашивать все 7 баз данных с вашего SQL Server, и, поскольку вы сильны в SQL, я создал фиктивную хранимую процедуру, из которой все 7 запросов будут объединены / объединены:

CREATE PROCEDURE QueryAllDatabases 
    -- Add the parameters for the stored procedure here
    -- Added some dummy parameters here for future use in your queries.
    @active bit,
    @birthdate date
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    -- QUERY DATABASE-1
    SELECT
        'Hulk Hogan' Name,
        'hh@email.com' Email
    --FROM
        -- DATABASE1.dbo.YourTable
    WHERE
        @active = 1 AND  -- "1" passed from console app.
        @birthdate > '2018-01-01'  -- "2018-05-29" passed from console app.

    UNION ALL

    -- QUERY DATABASE-2
    SELECT
        'Chum Lee' Name,
        'chum@email.com' Email
    --FROM
        -- DATABASE2.dbo.YourTable
    WHERE
        @active = 1 AND
        @birthdate > '2018-01-01'
END
GO

Теперь перейдем к части консольного приложения C #, где он будет получать все 7 запросов к базе данных из одного вызова хранимой процедуры:

Program.cs (Это решение C # Console)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApp_C_Sharp
{
    class Program
    {
        static void Main(string[] args)
        {
            ProcessData();
        }

        /// <summary>
        /// Query the database.
        /// </summary>
        /// <returns></returns>
        static DataSet QueryDatabase() 
        {
            // Credentials to your database.
            SqlConnection connection = new SqlConnection(@"Data Source=SERVER-NAME;Initial Catalog=DatabaseName;User ID=user;Password=yourpassword");

            // Name of the stored procedure to be excecuted and connection to database.
            SqlCommand command = new SqlCommand("QueryAllDatabases", connection);

            // DataSet to store the query results.
            DataSet result = new DataSet();

            // To excecute and fill the dataset.
            SqlDataAdapter da = new SqlDataAdapter(command);

            // Set the sqlcommand to "Stored Procedure".
            command.CommandType = CommandType.StoredProcedure;

            // Pass some parameters to your database's Stored Procedure if you need to.
            // We're sending some quick dummy params here.
            command.Parameters.AddWithValue("active", "1");
            command.Parameters.AddWithValue("birthdate", "2018-05-29");

            // Open connection to database.
            connection.Open();
            // Execute the stored procedure and fill the dataset.
            da.Fill(result);
            // Close the connection.
            connection.Close();

            // Object disposal.
            da.Dispose();
            command.Dispose();
            connection.Dispose();

            // Return the query results.
            return result;
        }

        /// <summary>
        /// Construct the message body and send it by smpt mail.
        /// </summary>
        static void ProcessData()
        {
            // Store the query results.
            DataSet ds = new DataSet();
            // StringBuilder to construct your HTML table.
            StringBuilder table = new StringBuilder();

            // Get data from database;
            ds = QueryDatabase();

            // If records available:
            if( ds.Tables.Count > 0 )
            {
                // Start table's header construct.
                table.Append("<table><thead><tr>");

                // Iterate through each column to insert the column name in the custom table.
                foreach (DataColumn col in ds.Tables[0].Columns)
                {
                    table.Append("<td>" + col.ColumnName + "</td>");                    
                }

                // End header construct.
                table.Append("</tr></thead>");
            }

            // Now, iterate the database records.
            foreach (DataRow row in ds.Tables[0].Rows )
            {
                // Insert one TR per row.
                table.Append("<tr>");
                foreach(DataColumn dc in ds.Tables[0].Columns)
                {
                    // Insert each data column into a TD cell.
                    table.Append("<td>");
                    table.Append(row[dc.ColumnName]);
                    table.Append("</td>");
                }
                // Close the table row and goto next record if available or exit loop.
                table.Append("</tr>");
            }

            // All records inserted. Close the table.
            table.Append("</table>");

            // Dsiplay the table in console.
            Console.WriteLine(table.ToString());
            Console.ReadKey();

            /*
             * 
             * From here you could send "table.ToString()" as the "Body" parameter to your SMTP mail library.
             * 
             * */
        }
    }
}

В конце вы получите table.ToString(), где хранится ваша пользовательская таблица со всеми 7 объединенными запросами к базе данных и форматированием HTML.Таким образом, вы можете отправить эту строку в качестве параметра в свою почтовую библиотеку SMTP.

Некоторые снимки экрана, чтобы увидеть результаты:

Console HTML code copied-pasted from Console to text editor, and manually formated to make it legible. HTML result viewed in browser

ОБНОВЛЕНИЕ:

Для границы вы должны применить некоторые стили непосредственно к элементам таблицы, я ненашел способ включить файл CSS при создании писем:

<table style="border: 1px solid black">
  <thead>
    <tr style="background-color: lavender">
      <td style="border: 1px solid blue">Name<td>
    </tr>
  </thead>
  <tr>
    <td style="border: 1px solid blue">Name<td>
  </tr>
  ...
</table>

Ссылка: https://www.w3schools.com/tags/att_style.asp

Что касается даты, вы можете отформатировать ее из сценария SQL:

SELECT
    CAST(myDate as DATE)
FROM
  ...

или непосредственно в коде C #:

Date.Parse(yourDateField).ToString("yyyy-MM-dd");
0 голосов
/ 29 мая 2018

Вы смешиваете несколько вещей в одну.

Для начала: SMTP - это транспортный протокол, который не имеет значения для вашей задачи.Важен формат содержимого ваших электронных писем.Прочитайте https://en.wikipedia.org/wiki/MIME#Content-Type

После этого: Вы можете отправлять составные сообщения?Можете ли вы создавать вложения в электронные письма?Или вы ограничены текстовыми (html) сообщениями?

, поэтому у меня почти все разобрались, кроме как запросить все 7 дб

Может быть, вам не нужнозапрограммируйте что-нибудь для этой задачи.

Но это зависит от того, какую операционную систему вы используете и какие базы данных вам нужно запросить.

Case 1 : файл Excel с 7 строками подключения и7 списков (я сделал это около 10 лет назад)

Случай 2 : у вас есть (можно получить) доступ к системе BI, и многие из них имеют функцию планирования отчетов (это слишкомcase

Case 3 : пользователям отчетов не требуется богатая графика BI и они ждут только csv-файлы, а после этого они могут сами обрабатывать данные. Вам нужно найти утилиту dump-dbи напишите сценарий bash / cmd для его автоматизации и отправки нескольких частей с вложениями.

Case 4 : все как в случае 3, но вы можете сохранить результаты в сетевой папке / ftp / sftp / googleдокументы / другие и отправлять только http-ссылки.

Уточнитьтребования и искать инструменты, доступные для вас.Попробуйте что-то с ними сделать.

Если вы столкнулись с новой проблемой - вернитесь в SO с новыми вопросами.

Удачи!

...