web-dev-qa-db-ja.com

「FunctionName」は互換性のないオブジェクトタイプであるため、変更を実行できません

同じ質問が以前に尋ねられた はわかっていますが、状況は少し異なります。(AFAIK)戻り値の型が同じである場合、私のコンテキストで失敗する理由について詳しく説明したいと思います。

これまで私のデータベースでは、CLRベースのテーブル値関数を使用して、カンマ区切りの値を整数列を含むテーブルに分割していました。

SQL2016は STRING_SPLIT を導入しているため、この関数のCLR部分を交換し、ネイティブのTSQL関数に置き換える必要があります(この関数に依存する数百のストアドプロシージャがあるため)。

SSMSでこの機能を変更すると、次のようになります。

ALTER FUNCTION [dbo].[e4fn_CreateIdTable](
     @Ids [nvarchar](max), 
     @separator [nchar](1))
RETURNS TABLE (
    [IdVal] [int] NULL
) WITH EXECUTE AS CALLER
AS 
EXTERNAL NAME [ValueSplitter].[MyCompany.ValueSplitter].[SplitToIntegers]

私はそれを次のように変更できることを望みました:

ALTER FUNCTION [dbo].[e4fn_CreateIdTable] (
    @Ids [nvarchar](max), 
    @separator [nchar](1)
)
RETURNS TABLE 
AS RETURN
(
    SELECT
        CAST(NULLIF(LTRIM(RTRIM(value)), '') AS int) AS IdVal
    FROM
        STRING_SPLIT(@Ids, @separator)
)
GO

これはエラーを返しました:

「dbo.e4fn_CreateIdTable」は互換性のないオブジェクトタイプであるため、変更を実行できません。

これは、出力パラメーターのテーブル定義が明示的に定義されていなかったためだと思いました。だから、私はこのように再試行しました:

ALTER FUNCTION [dbo].[e4fn_CreateIdTable] (
    @Ids [nvarchar](max), 
    @separator [nchar](1)
)
RETURNS @tbl TABLE  (
    IdVal int
)
AS 
BEGIN
    INSERT INTO @tbl (
        Idval
    )
    SELECT
        CAST(NULLIF(LTRIM(RTRIM(value)), '') AS int)
    FROM
        STRING_SPLIT(@Ids, @separator);

    RETURN;
END
GO

再び、同じエラーが表示されます。

  1. 戻り値の型が同じであるように見えるのに、なぜエラーが表示されるのですか?
  2. 関数を削除または再作成した場合、すべてのストアドプロシージャを再コンパイルする必要がありますか?
3
EvilDr

CLR TVFはSQL TVFとは根本的に異なるデータベースオブジェクトタイプであるため、ALTERではなく 'DROP/CREATE'を使用して定義を変更する必要があります。

CLR TVFの sys.objects のタイプは「FT」ですが、SQL TVF(インラインではない)は「TF」です。

7
Dan Guzman