问题出在 SSDT(SQL Server Data Tools)而不是 SQLCLR。是的,SQLCLR 确实支持DATETIME2
via DateTime?
/ Nullable<DateTime>
。不幸的是,SSDT(我正在使用 VS2013 和 SSDT v 12.0.50512.0)尚不(我在这里很乐观,我知道)支持DATETIME2
从DateTime
or 或DateTime?
. 但是,像以前一样使用它也不会出错DateTime?
。尽管如此,要么 要么DateTime
将在生成的 SQL 中DateTime?
显示为常规。DATETIME
我不确定告诉 SSDT 数据类型应该是什么的任何真正“适当”的方法。实际上有相当多的选项是不受支持的,包括通用的 UDF 选项WITH RETURNS NULL ON NULL INPUT
和参数选项,例如默认值。这是可悲和令人沮丧的,是的。
到目前为止,我想出的最好的方法(我仍在寻找其他选项)是ALTER
使用所需选项将部署后脚本添加到函数的定义中:
- 在PROJECT菜单中,选择Add New Item...(VS2013 中的Control+ Shift+ )A
- 转到SQL Server ->用户脚本
- 选择部署后脚本
- 给它一个名称(名称本身并不能确定它是预部署、部署后还是两者都不是;它只需要以.sql结尾)并单击Add
- 您将被置于(大部分)空 SQL 脚本中
输入一个或多个ALTER
语句,类似于以下内容:
-- declare once
DECLARE @ObjectName sysname; -- keep lower-case to work in case-sensitive collations
SET @ObjectName = N'Test';
IF (EXISTS(
SELECT *
FROM sys.assembly_modules sam
WHERE sam.[object_id] = OBJECT_ID(@ObjectName)
)
)
BEGIN
PRINT 'Checking custom properties for [' + @ObjectName + N']...';
IF (EXISTS(
SELECT *
FROM sys.parameters sp
INNER JOIN sys.types st
ON st.system_type_id = sp.system_type_id
WHERE sp.[object_id] = OBJECT_ID(@ObjectName)
AND st.[name] <> N'datetime2' -- keep lower-case to work in
-- case-sensitive collations
)
)
BEGIN
PRINT 'Setting custom properties for [' + @ObjectName + N']...';
BEGIN TRY
EXEC('
ALTER FUNCTION [dbo].[Test](@d [datetime2])
RETURNS [datetime2] WITH EXECUTE AS CALLER
AS EXTERNAL NAME [Test].[Test.UserDefinedFunctions].[Test];
');
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
SET @ErrorMessage = ERROR_MESSAGE();
RAISERROR(@ErrorMessage, 16, 1);
RETURN;
END CATCH;
END;
END;
ELSE
BEGIN
RAISERROR(N'Oops. [%s] was renamed or no longer exists!', 16, 1, @ObjectName);
RETURN;
END;
---
SET @ObjectName = N'NextObjectToFix';
-- copy the rest from above
此部署后脚本将始终包含在_Create
发布/增量构建脚本的末尾。因此需要额外的逻辑来查看更改是否已经存在。确实,始终运行 .通常并没有什么坏处ALTER
,但在极少数情况下,该对象是其他对象的依赖项,例如 Check Constraint 或 Computed Column,除非需要更改,否则最好不要理会它.
您可以从脚本(只需将 更改为)或在 SSMS 中获得正确的ALTER
定义,如果您右键单击对象并选择Modify。在这两种情况下,更改数据类型和任何其他选项(显然 ;-)。\bin\Configuration\*_Create.sql
CREATE
ALTER
另一个有点相关的想法是不依赖于 T-SQL 包装对象CREATE
语句的 Visual Studio / SSDT 发布过程,而仅使用它来管理程序集。在此设置中,您将取消选中Project Properties的SQLCLR选项卡上的Generate DDL选项。然后,您将添加一个部署后脚本(如上面的建议中所述)并放入您自己的,等语句。CREATE FUNCTION ...
CREATE PROCEDURE ...
对于初始开发来说,引入新对象并不像使用 SSDT 生成 DDL 那样快速和容易,但考虑到新对象的创建并不频繁,而且它们的签名更改频率要低得多,因此真正自己管理这个 DDL还不错(事实上,它与我用于包含 250 多个对象的SQL#库的过程非常相似。务实地说,一旦您拥有每个对象类型CREATE
语句之一,您就可以复制和粘贴它们用于新对象并更改名称和参数等。这种方法需要的最多工作是在创建新 TVF 时,如果它返回一堆字段,但这并不是真正的工作,因为您必须输入同入TableDefinition
财产SqlFunction
如果您使用 SSDT 来管理 DDL 创建,则无论如何都要属性。