2015-05-27 59 views
3

既然C#支持可选参数,是否有办法编写SQL CLR存储过程,以便Visual Studio中的发布将使用可选参数在SQL Server中创建存储过程,在C#中定义?SQLCLR具有可选参数/默认值的存储过程

做到这一点,在过去的唯一办法是通过手工编写包装函数:
Default parameter values/optional parameters for .NET stored procedures in SQL Server 2005

我宁愿避免这种情况,因为它需要编写两次接口,以及维持两个接口情况发生变化。

实施例:

[Microsoft.SqlServer.Server.SqlProcedure] 
public static void help(string FunctionName = "") 
{ 
    SqlPipe pipe = SqlContext.Pipe; 
    pipe.Send("help> " + FunctionName + "<"); 
} 

从VS2013收率出版(在生成的发布脚本):

CREATE PROCEDURE [dbo].[help] @FunctionName [nvarchar](MAX) 
AS EXTERNAL NAME [YOURDB].[StoredProcedures].[help]; 

运行它:

exec help 
Procedure or function 'help' expects parameter '@FunctionName', which was not supplied. 

但是,如果手动编写的程序创造如此:

drop procedure [help] 
CREATE PROCEDURE [dbo].[help] 
(@FunctionName nvarchar(100) = null) 
AS EXTERNAL NAME [YOURDB].[StoredProcedures].[help]; 

exec help 
help> < 

....它现在按预期运行。

Visual Studio将所有需要的参数发布为可选参数,因为C#支持它们,所以无论我做错了什么,或者他们只是没有更新发布实现来识别可选参数。

回答

4

目前无法向SSDT(SQL Server数据工具)发布过程默认值参数。是的,这是令人沮丧的,因为它确实需要额外的步骤来解析和“修复”生成的脚本,或添加一个后期部署脚本来执行ALTER {object}语句以添加缺少的详细信息(其中包括其他内容作为用于标量函数的WITH RETURNS NULL ON NULL INPUT选项,其为很方便地)。

我创建了一个连接建议来解决这方面的不足:SSDT - Support T-SQL parameter defaults for SQLCLR objects via the SqlFacet attribute when generating the publish and create SQL scripts

两个关系到指定参数的默认值的可能性笔记:

  • 他们并不适用于LOB的T-SQL参数类型 - NVARCHAR(MAX),VARBINARY(MAX)XML - 因为这些数据类型不支持SQLCLR对象中的默认值。这是另一个沮丧,我已经记录了以下连接建议以解决此缺陷:Support default parameter values for NVARCHAR(MAX), VARBINARY(MAX), and XML types in SQLCLR objects
  • 他们将(应该)作为SqlFacet属性的附加属性来处理。他们应该而不是的原因是从C#方法param派生的,默认值是参数defaults在C#和T-SQL之间的工作方式不一样。不仅是上面提到的LOB类型限制,而且在T-SQL中,任何具有默认值的参数的位置都不相关,并且具有默认值的参数后面可以跟随所需的参数(即没有指定默认值)。相反,在C#中,可选参数必须位于参数列表的末尾,并且不能跟随必需的参数。正如它在MSDN页面中对Named and Optional Arguments所述:

    可选参数在参数列表末尾定义,位于任何所需参数之后。如果调用者为任何一个可选参数连续提供参数,则它必须为所有前面的可选参数提供参数。

  • 我目前的工作并指出这些默认值,还有,希望的CREATE PROCEDURECREATE FUNCTION(即EXECUTE ASRETURNS NULL ON NULL INPUT等),其他缺少的属性的一种手段,但它是一个有点棘手得到它的工作尽可能在SSDT发布过程中尽可能无缝地完成,因此在完成时没有ETA。一旦完成,我将用下载链接更新这个答案。

UPDATE:
最后,它可能比较容易手工处理的T-SQL包装对象的创建。你可以拥有的Visual Studio这样做产生的议会和任何必要的DB设置语句,但随后做CREATE PROCEDURECREATE FUNCTION,等自己:

  1. 项目属性 - >项目设置检查创建脚本( .sql文件)复选框。
  2. 项目属性 - > SQLCLR取消选中生成DDL复选框。
  3. 添加新项目 - > SQL Server - >用户脚本 - >部署后脚本并在您的脚本中添加您的CREATE语句。
+0

像往常一样彻底的答案,谢谢。由于这种情况以及其他各种疯狂,我不知道该如何解决,所以我将SQLCLR代码放在一个完全独立的VS项目中,并完全手动部署(手写的函数定义) - 这是一种痛苦,但是,你可以做。如果这些缺点在官方文档中有说明,那将是很好的,所以一个人从一开始就知道它不会像预期的那样工作(并且*不可能*变通)。 – tbone

+0

@tbone是的,这实际上是我为生产级别的东西做的。我只依靠Visual Studio部署进行测试。我添加了关于它的答案的更新。有点烦人写我自己,但签名很少改变,所以它不是真的那么糟糕。 –

相关问题