用C#创buildSQL CLR UDF

我已经被赋予能够将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中作为一个程序集引用的包。 我期望在这里实现的两个主要function是将SQL查询和文件名(作为variables)传递给SQL UDF,SQL UDF将此信息传递给此包并运行查询并创build文件。

我想知道,1.如果这是可能的。 2.如果有什么快速的例子,你可以给我如何去做这件事。

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

亲切的问候和提前感谢,

约翰尼

如你所说 –

我想知道,1.如果这是可能的。 2.如果有什么快速的例子,你可以给我如何去做这件事。

对的,这是可能的。

好吧,为此你必须首先在Visual Studio中创buildSQL Server项目

  • 在Visual Studio中>>单击新build项目>>selectVisual C#>>数据库>> SQL Server项目。
  • 然后给你现有的数据库连接作为参考。
  • 然后右键点击解决scheme资源pipe理器>>点击添加>>存储过程
  • 现在把你的代码放在文件中。

这是您的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(); } } 

现在为了部署它,遵循这个代码项目文章

希望它可以帮助你…

好了,经过大量的尝试将其部署到我的数据库之后,我发现EPPlus库正在使用SQL Server无法支持的其他程序集。

我没有试图将其创build为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(); } } } 

显然这可以通过命令行调用。 这个想法是将查询和文件path作为命令行parameter passing给main()。 一旦你build立了这个解决scheme,你可以用SQL Server中的XP_CMDSHELL调用控制台应用程序。 我甚至添加了额外的参数来捕获服务器名称和当前数据库。

此外,我还添加了一些error handling和控制台签名来返回应用程序的每个阶段进行debugging。 这使最终用户能够正确识别他们需要做些什么才能使其工作。

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

希望这有助于任何未来寻找类似解决scheme的人。

谢谢!