問題は SSDT (SQL Server Data Tools) にあり、SQLCLR にはありません。はい、SQLCLR は実際に/DATETIME2
経由でサポートしています。残念ながら、SSDT (私は VS2013 と SSDT v 12.0.50512.0 を使用しています) はまだ(私はここで楽観的です、私は知っています)またはからの推論をサポートしていません。しかし、以前のように使用してもエラーにはなりません。それでも、生成された SQL ではorが通常として表示されます。DateTime?
Nullable<DateTime>
DATETIME2
DateTime
DateTime?
DateTime?
DateTime
DateTime?
DATETIME
SSDTにデータ型がどうあるべきかを伝える真の「適切な」手段はわかりません。WITH RETURNS NULL ON NULL INPUT
などの一般的な UDF オプションや、デフォルト値などのパラメーター オプションなど、実際にはサポートされていないオプションがかなりあります。悲しくてもどかしいです、はい。
私がこれまでに思いついた最善の方法は (そして私はまだ他のオプションを検討しています) ALTER
、目的のオプションを使用して関数の定義に配置後スクリプトを追加することです。
- プロジェクトメニューで、新しいアイテムの追加... ( VS2013 ではControl+ Shift+ ) を選択します。A
- SQL Server ->ユーザー スクリプトに移動します。
- 配置後スクリプトの選択
- 名前を付けて (名前自体は、デプロイ前、デプロイ後、またはそのどちらでもないかを判断しません。単に.sqlで終わる必要があります) をクリックします。Add
- (ほとんど) 空の SQL スクリプトに配置されます
ALTER
次のようなステートメントを 1 つ以上入力します。
-- 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
が、まれに、このオブジェクトがチェック制約や計算列などの他のものに依存している場合は、変更する必要がない限り、そのままにしておくのがおそらく最善です。 .
オブジェクトを右クリックして [変更] を選択すると、スクリプト ( を に変更するだけ)または SSMSから適切なALTER
定義を取得できます。どちらの場合も、データ型とその他のオプションを変更します (明らかに ;-)。\bin\Configuration\*_Create.sql
CREATE
ALTER
CREATE
多少関連するもう 1 つのアイデアは、T-SQL ラッパー オブジェクトステートメントの Visual Studio / SSDT パブリッシュ プロセスに依存せず、アセンブリの管理にのみ使用するというものです。この設定では、 Project PropertiesのSQLCLRタブにあるGenerate DDLオプションのチェックを外します。次に、Post Deployment スクリプトを追加し (上記の提案で説明したように)、独自の, などのステートメントを挿入します。CREATE FUNCTION ...
CREATE PROCEDURE ...
最初の開発では、SSDT を使用して DDL を生成するよりも、新しいオブジェクトを導入するのが迅速かつ簡単ではありませんが、新しいオブジェクトが頻繁に作成されるわけではなく、署名が変更される頻度がはるかに低いことを考えると、この DDL を実際に自分で管理する必要があります。それほど悪くはありません (実際、 250 以上のオブジェクトを持つSQL#ライブラリに使用するプロセスと非常によく似ています。実用的に言えば、各オブジェクト タイプのCREATE
ステートメントを 1 つ取得したら、コピーして貼り付けるだけです。それらを新しいオブジェクト用に変更し、名前やパラメータなどを変更します。このアプローチが必要とする最も多くの作業は、一連のフィールドを返す場合に新しい TVF を作成するときですが、それを入力する必要があることを考えると、実際にはそれほど多くの作業ではありません。のTableDefinition
プロパティに同じSqlFunction
SSDT を使用して DDL の作成を管理していた場合は、とにかく属性を変更します。