16

I'm getting the below error for the given function.

メッセージ 2010、レベル 16、状態 1、プロシージャ GetTableFromDelimitedValues、行 2 「dbo.GetTableFromDelimitedValues」は互換性のないオブジェクト タイプであるため、変更を実行できません。

IF NOT EXISTS(SELECT 1 FROM sys.objects 
              WHERE object_id = OBJECT_ID('[GetTableFromDelimitedValues]'))
BEGIN
   EXECUTE('CREATE FUNCTION [dbo].[GetTableFromDelimitedValues](@input varchar(max),
       @delimiter char(1) = ",")) RETURNS @Result TABLE (
       Value nvarchar(4000)) AS BEGIN RETURN END')
END
GO


ALTER FUNCTION [dbo].[GetTableFromDelimitedValues](
       @input varchar(max),
       @delimiter char(1) = ',')
RETURNS @Result TABLE
(
       Value nvarchar(4000)
)
AS
BEGIN
    DECLARE @position int;
    DECLARE @column nvarchar(4000);

    WHILE LEN(@input) > 0
    BEGIN
        SET @position = CHARINDEX(@delimiter, @input);
        IF (@position < 0) OR (@position IS NULL)
        BEGIN
            SET @position = 0;
        END

        IF @position > 0 
        BEGIN
            SET @column = SUBSTRING(@input, 1, @position - 1);
            SET @input = SUBSTRING(@input, @position + 1, LEN(@input) - @position)
        END
        ELSE
        BEGIN
            SET @column = @input;
            SET @input = '';
        END 

        INSERT @Result (Value) 
        SELECT @column;
    END;

    RETURN;                
END
GO

関数を修正して互換性のあるタイプを取得するのを手伝ってもらえますか?

4

6 に答える 6

33

この特定のコンテキストで関数削除して作成する必要があります

関数の戻り値の型が変更されているため、関数を削除してから再作成する必要があります。

3種類の機能があり、

  • スカラー
  • インライン テーブルの値
  • マルチステートメント

ALTER を使用して関数タイプを変更することはできません。

于 2014-07-08T08:36:19.237 に答える
4
IF  EXISTS (SELECT [name] FROM sys.objects 
            WHERE object_id = OBJECT_ID('GetTableFromDelimitedValues'))
BEGIN
   DROP FUNCTION [GetTableFromDelimitedValues];
END
GO

/*  Now create function */
CREATE FUNCTION [dbo].[GetTableFromDelimitedValues](
       @input varchar(max),
       @delimiter char(1) = ',')
RETURNS @Result TABLE (
       Value nvarchar(4000)
)
AS
BEGIN
..
..
..
RETURN;
END

関数でOBJECT_IDは、スキーマではなく関数名のみを渡す必要があります。そして、なぜ最初にそれを作成し、次にAlterそれを作成するのでしょうか。最初に存在するかどうかを確認してから、関数をドロップして、上に示したように関数を作成します。

また、存在を確認するときに where 句を追加Typeしないでください。関数ではなく同じ名前の別のオブジェクトがある場合、select ステートメントでそれを選択せず​​、名前を持つ関数を作成することになりますオブジェクトが既に存在します (エラーがスローされます)。

自分のやり方でやりたいのなら、こうすればいい

IF NOT EXISTS(SELECT 1 FROM sys.objects 
              WHERE object_id = OBJECT_ID('[GetTableFromDelimitedValues]'))
BEGIN
   EXECUTE('CREATE FUNCTION [dbo].[GetTableFromDelimitedValues]() RETURNS @Result TABLE (
       Value nvarchar(4000)) AS BEGIN RETURN END')
END
GO
于 2014-01-28T23:18:16.887 に答える
0

以下のコードが動作することを確認しました。問題は、開発中に同じ名前で作成されたスカラー値関数であり、スクリプトのマルチパートテーブル値の変更ステートメント関数が互換性があるため、エラーが発生したようです。

IF NOT EXISTS(SELECT 1 FROM sys.objects 
              WHERE object_id = OBJECT_ID('[GetTableFromDelimitedValues]'))
BEGIN
   EXEC sp_executesql 
    @statement = N'CREATE FUNCTION dbo.[GetTableFromDelimitedValues] () RETURNS @Result 
    TABLE(Value nvarchar(4000))
    AS 
    BEGIN 
      RETURN 
    END' ;
END
GO

ALTER FUNCTION [dbo].[GetTableFromDelimitedValues](
    @input varchar(max),
    @delimiter char(1) = ',')
RETURNS @Result TABLE
(
    Value nvarchar(4000)
)
AS
BEGIN
    DECLARE @position int;
    DECLARE @column nvarchar(4000);

    WHILE LEN(@input) > 0
    BEGIN
        SET @position = CHARINDEX(@delimiter, @input);
        IF (@position < 0) OR (@position IS NULL)
        BEGIN
            SET @position = 0;
        END

        IF @position > 0 
        BEGIN
            SET @column = SUBSTRING(@input, 1, @position - 1);
            SET @input = SUBSTRING(@input, @position + 1, LEN(@input) - @position)
        END
        ELSE
        BEGIN
            SET @column = @input;
            SET @input = '';
        END 

        INSERT @Result (Value) 
        SELECT @column;
    END;

    RETURN;                
END
GO
于 2014-01-29T19:28:11.943 に答える