2

背景:

Visual Studio 无法部署数据库项目。它试图删除已经引用的函数(例如在检查约束中),而不是仅仅添加新函数并更新现有函数,因此部署总是失败。

因此,我正在编写自己的代码来更新程序集并添加/更新任何功能。

我假设编译器/部署器使用反射和 SqlFunction 属性的属性,所以我也使用反射来收集具有 SqlFunction 属性的静态方法的 MethodInfo 列表。

问题/任务:

我需要知道如何将 SqlFunctionAttribute 的属性(例如 IsDeterministic、DataAccess、Name、IsPrecise 等)和函数的方法签名转换为适当的 T-SQL“CREATE FUNCTION”语句。

我已经发现没有帮助的现有信息:

“创建函数”的文档令人困惑且不完整。在底部,它最后提到了一些 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' ;
4

1 回答 1

2

在意识到拥有程序集本身的 SQL Server 可以访问 SqlFunctionAttribute 的属性值之后,我最终解决了这个问题。在这种情况下,无需(也没有语法)在“CREATE FUNCTION”T-SQL 语句中指定此类属性。

我构建了一个实用程序来自动枚举和部署函数和检查约束,其工作原理如下:

  1. 它通过使用反射搜索具有 SqlFunction 属性的函数来枚举我指定的类中的所有可部署静态方法。它还运行一个查询来枚举所有已部署的现有标量和表值汇编函数。然后它将这些列表合并到一个列表中,其中每个函数要么存在,要么不存在。有一个更新程序集的按钮,以及一个切换每个功能存在的按钮,使添加/删除/更新功能变得轻而易举。

  2. 此外,我在界面中添加了第二个选项卡来创建/启用/检查/禁用检查约束。我创建了一个名为 SqlFunctionCheck 的新属性,它可以多次应用于一个函数。该属性具有“表”属性和“字段”属性,可帮助实用程序构建检查约束。它按表聚合所有检查,为每个名为“CK_”+ table_name 的表创建一个检查,并创建一个约束表达式,通过“and”将所有方法调用与该表的关联字段名称传递给函数。如果约束已经存在,它会显示生成的约束表达式以及从 sql server 查询的约束表达式。

IMO,这是使用 SQL CLR 集成来强制管理工作室中的数据类型约束、代码中的 SQL 查询以及整个代码本身使用的来自集中数据(约束)类的数据的最终解决方案。

界面截图和相关函数头

于 2009-05-01T22:47:33.647 回答