C# Program to Execute SQL Scripts and Save Results to Excel

Answered using ChatGPT 4o by ChatGPT4o

Question:

В папке лежат файлы со скриптами .sql. Есть другая папка, куда нужно складывать файлы excel. Мне нужно написать программу на C#. Программа соединяется с базой данных. Это может быть Oracle, Postgresql, sql server. Программа по очереди берет файлы sql, выполняет запрос из файла и результат записывает в файл excel и кладет в соответствующую папку. Внутри файла excel типы данных должны сответствовать типам в базе данных: число, строка, дата, интервал. Программа по ходу выполнения пишет лог о своей работе и также выводит на консоль. После выполнения всех запросов программа архивирует все excel файлы и лог в архив. В названии архива должна быть дата и время создания архива. Напиши код. Используй epplus. Не используй Dapper. Не используй асинхронное программирование. Пути к папкам, СУБД, строку соединения получи из appsettings.json. Используй dynamic Параметры в json должны быть на одном уровне. Используй Newtonsoft.Json. Используй рекомендуемые практики программирования.

Answer:

Конечно! Вот пример программы ��а C#, которая выполняет описанные вами задачи. Программ�� использу��т библиотеку EPPlus для работы с Excel и Newtonsoft.Json для чтения конфигурации из файла appsettings.json.

Для работы с базой данных будем использовать стандартные библиотеки ADO.NET.

appsettings.json

{
  "SqlScriptsFolder": "path/to/sql/scripts",
  "ExcelOutputFolder": "path/to/excel/output",
  "DatabaseType": "Postgresql", // or "Oracle", "SqlServer"
  "ConnectionString": "your_connection_string"
}

Program.cs

using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.IO.Compression;
using Newtonsoft.Json;
using Npgsql;
using Oracle.ManagedDataAccess.Client;
using OfficeOpenXml;

class Program
{
    static void Main(string[] args)
    {
        var config = LoadConfiguration();
        var logFilePath = Path.Combine(config.ExcelOutputFolder, "log.txt");

        using (var logWriter = new StreamWriter(logFilePath))
        {
            try
            {
                var sqlFiles = Directory.GetFiles(config.SqlScriptsFolder, "*.sql");
                foreach (var sqlFile in sqlFiles)
                {
                    var sqlQuery = File.ReadAllText(sqlFile);
                    var dataTable = ExecuteQuery(config, sqlQuery);
                    var excelFilePath = Path.Combine(config.ExcelOutputFolder, Path.GetFileNameWithoutExtension(sqlFile) + ".xlsx");
                    SaveToExcel(dataTable, excelFilePath);
                    logWriter.WriteLine($"Processed {sqlFile} and saved to {excelFilePath}");
                    Console.WriteLine($"Processed {sqlFile} and saved to {excelFilePath}");
                }

                var archiveFilePath = Path.Combine(config.ExcelOutputFolder, $"Archive_{DateTime.Now:yyyyMMdd_HHmmss}.zip");
                ZipFiles(config.ExcelOutputFolder, archiveFilePath);
                logWriter.WriteLine($"Archived files to {archiveFilePath}");
                Console.WriteLine($"Archived files to {archiveFilePath}");
            }
            catch (Exception ex)
            {
                logWriter.WriteLine($"Error: {ex.Message}");
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
    }

    static dynamic LoadConfiguration()
    {
        var configJson = File.ReadAllText("appsettings.json");
        return JsonConvert.DeserializeObject<dynamic>(configJson);
    }

    static DataTable ExecuteQuery(dynamic config, string query)
    {
        using (IDbConnection connection = CreateConnection(config))
        {
            connection.Open();
            using (var command = connection.CreateCommand())
            {
                command.CommandText = query;
                using (var reader = command.ExecuteReader())
                {
                    var dataTable = new DataTable();
                    dataTable.Load(reader);
                    return dataTable;
                }
            }
        }
    }

    static IDbConnection CreateConnection(dynamic config)
    {
        string dbType = config.DatabaseType.ToString();
        string connectionString = config.ConnectionString.ToString();

        return dbType switch
        {
            "Postgresql" => new NpgsqlConnection(connectionString),
            "Oracle" => new OracleConnection(connectionString),
            "SqlServer" => new SqlConnection(connectionString),
            _ => throw new NotSupportedException($"Database type {dbType} is not supported")
        };
    }

    static void SaveToExcel(DataTable dataTable, string filePath)
    {
        using (var package = new ExcelPackage())
        {
            var worksheet = package.Workbook.Worksheets.Add("Sheet1");
            worksheet.Cells["A1"].LoadFromDataTable(dataTable, true);
            package.SaveAs(new FileInfo(filePath));
        }
    }

    static void ZipFiles(string folderPath, string zipFilePath)
    {
        if (File.Exists(zipFilePath))
        {
            File.Delete(zipFilePath);
        }

        ZipFile.CreateFromDirectory(folderPath, zipFilePath);
    }
}

Пояснения:

  1. Загрузка конфигурации: Конфигурация загружается из файла appsettings.json с помощью Newtonsoft.Json.
  2. Выполнение SQL-запросов: В зависимости от типа базы данных создается соответствующее соединение (Postgresql, Oracle, SqlServer) и выполняется SQL-запрос.
  3. Сохранение в Excel: Результаты запрос�� сохраняются в файл Excel с помощью EPPlus.
  4. Логирование: Логи записываю��ся в файл и выводятся на кон��оль.
  5. Архивирование: Все файлы Excel и лог-файл архивируются в zip-архив с текущей датой и временем в названии.

Зависимости:

  • EPPlus: Для работы с Excel.
  • Newtonsoft.Json: Для работы с JSON.
  • Npgsql: Для работы с PostgreSQL.
  • Oracle.ManagedDataAccess: Для работы с Oracle.
  • System.Data.SqlClient: Для работы с SQL Server.

Установка ��ависимост��й:

dotnet add package EPPlus
dotnet add package Newtonsoft.Json
dotnet add package Npgsql
dotnet add package Oracle.ManagedDataAccess
dotnet add package System.Data.SqlClient

Этот пример должен помочь вам начать работ��. Вы можете адаптировать его под свои нужды и расширить функциональность по мере