如何在数据库项目中使用 SqlFunctionAttribute 生成 SQL 以自行部署函数?视觉工作室失败
Posted
技术标签:
【中文标题】如何在数据库项目中使用 SqlFunctionAttribute 生成 SQL 以自行部署函数?视觉工作室失败【英文标题】:How can I use the SqlFunctionAttribute in a database project to generate the SQL to deploy the functions myself? Visual studio fails 【发布时间】:2009-04-20 17:30:46 【问题描述】:背景:
Visual Studio 无法部署数据库项目。它会尝试删除已经引用的函数(例如在检查约束中),而不是仅仅添加新函数并更新现有函数,因此部署总是失败。
因此,我正在编写自己的代码来更新程序集并添加/更新任何函数。
我假设编译器/部署器使用反射和 SqlFunction 属性的属性,所以我也使用反射来收集具有 SqlFunction 属性的静态方法的 MethodInfo 列表。
问题/任务:
我需要知道如何将 SqlFunctionAttribute 的属性(例如 IsDeterministic、DataAccess、Name、IsPrecise 等)和函数的方法签名转换为适当的 T-SQL“CREATE FUNCTION”语句。
我已发现无用的现有信息:
“创建函数”的documentation 令人困惑且不完整。在底部,它最后提到了一些 SqlFunction 属性,例如 IsDeterministic,但它谈论它们时就像是 C# 属性,而不是 T-SQL 参数,所以我不知道如何在创建函数语句中使用它们。
//CLR Functions
CREATE FUNCTION [ schema_name. ] function_name
( @parameter_name [AS] [ type_schema_name. ] parameter_data_type
[ = default ]
[ ,...n ]
)
RETURNS return_data_type | TABLE <clr_table_type_definition>
[ WITH <clr_function_option> [ ,...n ] ]
[ AS ] EXTERNAL NAME <method_specifier>
[ ; ]
我希望 clr_function_option
参数能够处理诸如 IsDeterministic 之类的事情,但它没有被列为选项。
同时,在 IBM DB2 的文档中,我看到类似以下的语句,而 MSDN 文档中没有任何类似的语句:
CREATE FUNCTION countUp(INTEGER)
RETURNS INTEGER
LANGUAGE CLR
PARAMETER STYLE SQL
SCRATCHPAD 10
FINAL CALL
NO SQL
FENCED
THREADSAFE
NOT DETERMINISTIC
EXECUTION CONTORL SAFE
EXTERNAL NAME 'gwenUDF.dll:bizLogic.empOps!CountUp' ;
【问题讨论】:
您需要将程序集复制到您的 SQL 服务器,然后使用适当的 T-SQL。几个小时后,当我回到我的电脑时,我可以显示完整的 SQL。 获取程序集并对其进行更新相当容易。一旦它们已经被引用,它就可以获取并更新它们,这很困难。 Visual Studio 无法处理它,因为它试图删除函数并且不能因为它们在检查约束中使用。我真正需要的是像“string GetSQLForCreateFunction(MethodInfo m);”这样的函数的代码,其中该方法具有 SqlFunction 属性。 【参考方案1】:在意识到拥有程序集本身的 SQL Server 可以访问 SqlFunctionAttribute 的属性值之后,我最终解决了这个问题。在这种情况下,无需(也没有语法)在“CREATE FUNCTION”T-SQL 语句中指定此类属性。
我构建了一个实用程序来自动枚举和部署函数和检查约束,其工作原理如下:
它通过使用反射搜索具有 SqlFunction 属性的函数来枚举我指定的类中的所有可部署静态方法。它还运行一个查询来枚举所有已部署的现有标量和表值汇编函数。然后它将这些列表合并为一个列表,其中每个函数要么存在,要么不存在。有一个更新程序集的按钮,以及一个切换每个功能存在的按钮,使添加/删除/更新功能变得轻而易举。
此外,我在界面中添加了第二个选项卡来创建/启用/检查/禁用检查约束。我创建了一个名为 SqlFunctionCheck 的新属性,它可以多次应用于一个函数。该属性具有“表”属性和“字段”属性,可帮助实用程序构建检查约束。它按表聚合所有检查,为每个名为“CK_”+ table_name 的表创建一个检查,并创建一个约束表达式,通过“and”将所有方法调用与该表的关联字段名称传递给函数。如果约束已经存在,则显示生成的约束表达式以及从sql server查询的约束表达式。
IMO,这是使用 SQL CLR 集成来强制管理工作室中的数据类型约束、代码中的 SQL 查询以及在整个代码本身中使用的来自集中数据(约束)类的数据的终极解决方案。
【讨论】:
以上是关于如何在数据库项目中使用 SqlFunctionAttribute 生成 SQL 以自行部署函数?视觉工作室失败的主要内容,如果未能解决你的问题,请参考以下文章
如果不存在,如何在 Visual Studio 中使用数据库项目创建数据库?