使用C#创建SQL CLR UDF

时间:2014-05-28 09:16:47

标签: c# excel clr epplus

我被赋予了将SQL查询结果集推送到Excel文件的任务。目前我有一个C#控制台应用程序(下面)接受查询,并使用EPPlus库将结果转储到指定的xlsx文件中。

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using OfficeOpenXml;
using OfficeOpenXml.Style;

namespace ExcelExport
{
    class Program
    {
        static void Main(string[] args)
        {

            //Create a connection to the database
            SqlConnection conn = new SqlConnection("user id=username;" +
                                                   "password=password;server=SQL-04;" +
                                                   "Trusted_Connection=yes;" +
                                                   "database=JOHN; " +
                                                   "connection timeout=30");
            conn.Open();
            //Set up the SQL query
            string query = "SELECT TOP 10 FORENAME, SURNAME, POSTCODE FROM JOHN.DBO.TEST ORDER BY POSTCODE ASC";
            SqlCommand cmd = new SqlCommand(query, conn);

            //Fill a C# dataset with query results
            DataTable t1 = new DataTable();
            using (SqlDataAdapter a = new SqlDataAdapter(cmd))
            {
                a.Fill(t1);
            }

            //Assign filename to a variable
            string filePath = @"C:\Misc\test.xlsx";

            var file = new FileInfo(filePath);

            //Load the data table into the excel file and save
            using (ExcelPackage pck = new ExcelPackage(file))
            {
                ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Data");
                ws.Cells["A1"].LoadFromDataTable(t1, true);
                pck.Save();
            }

            //Close the existing connection to clean up
            conn.Close();
        }
    }
}

这很好用,但下一步是将它转换为一个可以作为SQL Server中的程序集引用的包。我希望在这里实现的两个主要功能是能够将SQL查询和文件名(作为变量)传递给SQL UDF,后者将此信息传递给此包并运行查询并创建文件。

我想知道,1。如果可行的话。 2.如果有任何快速的例子,你可以告诉我如何做到这一点。

请原谅我对C#主题的无知,我昨天才开始使用它:/

亲切的问候并提前致谢,

约翰尼

2 个答案:

答案 0 :(得分:4)

正如你所说 -

  

我想知道,1。如果可行的话。 2.如果有的话   你可以告诉我如何解决这个问题的简单例子。

是的,有可能。

好的,您必须首先在visual studio中创建 SQL Server Project

  • 在Visual Studio中>>点击新建项目>>选择Visual C#>>数据库>> SQL Server项目。
  • 然后将现有数据库连接作为参考。
  • 然后右键单击Solution Explorer>>点击添加>>存储 过程
  • 现在将您的代码放入文件中。

这是您的CLR存储过程代码。

[SqlProcedure()]
    public static void GetMyTestData(
        SqlString sqlQuery, SqlString fileName)
    {
        using (SqlConnection conn = new SqlConnection("context connection=true"))
        {
            SqlCommand cmd = new SqlCommand(sqlQuery, conn);

            //Fill a C# dataset with query results
            DataTable t1 = new DataTable();
            using (SqlDataAdapter a = new SqlDataAdapter(cmd))
            {
                a.Fill(t1);
            }

            //Assign filename to a variable

            var file = new FileInfo(fileName);

            //Load the data table into the excel file and save
            using (ExcelPackage pck = new ExcelPackage(file))
            {
                ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Data");
                ws.Cells["A1"].LoadFromDataTable(t1, true);
                pck.Save();
            }

            conn.Close();
        }
    }

现在要按照此code project article

进行部署

希望它可以帮到你...

答案 1 :(得分:0)

好的,所以在经过多次考虑将其部署到我的数据库之后,我发现EPPlus库正在使用SQL Server无法支持的其他程序集。

我没有尝试将其创建为CLR函数,而是坚持使用控制台应用程序方法:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using OfficeOpenXml;
using OfficeOpenXml.Style;

namespace ExcelExport
{
    class Program
    {
        static void Main(string[] args)
        {

            //Create a connection to the database
            SqlConnection conn = new SqlConnection("user id=username;" +
                                                   "password=password;server=SQL-04;" +
                                                   "Trusted_Connection=yes;" +
                                                   "database=JOHN; " +
                                                   "connection timeout=30");
            conn.Open();
            //Set up the SQL query
            string query = args[0];
            SqlCommand cmd = new SqlCommand(query, conn);

            //Fill a C# dataset with query results
            DataTable t1 = new DataTable();
            using (SqlDataAdapter a = new SqlDataAdapter(cmd))
            {
                a.Fill(t1);
            }

            //Assign filename to a variable
            string filePath = args[1];

            var file = new FileInfo(filePath);

            //Load the data table into the excel file and save
            using (ExcelPackage pck = new ExcelPackage(file))
            {
                ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Data");
                ws.Cells["A1"].LoadFromDataTable(t1, true);
                pck.Save();
            }

            //Close the existing connection to clean up
            conn.Close();
        }
    }
}

显然,这可以通过命令行调用。我们的想法是将查询和文件路径作为命令行参数传递,这些参数被读入main()。构建此解决方案后,您可以使用SQL Server中的XP_CMDSHELL调用控制台应用程序。我甚至添加了额外的参数来捕获服务器名称和当前数据库。

此外,我还添加了一些错误处理和控制台writelines来返回应用程序的每个阶段以进行调试。这允许最终用户正确识别他们需要做什么才能使其发挥作用。

最后一个音符。如果你想用参数测试控制台应用程序,你可以通过右键单击解决方案资源管理器中的项目,转到属性然后调试选项卡来传递一些参数,然后在那里,应该有一个选项来输入一些参数。确保它们被空格隔开。如果没有这个,你只会得到错误,说args []数组中没有指定参数。

希望这有助于将来寻找类似解决方案的任何人。

谢谢!