web-dev-qa-db-ja.com

SQLでテーブル値関数を作成および変更するときの互換性のないオブジェクトタイプ

指定された関数に対して以下のエラーが発生します。

メッセージ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

誰かが関数を修正して互換タイプを取得するのを手伝ってくれませんか?

12
ary

[〜#〜] drop [〜#〜]および[〜#〜] create [〜#〜]この特定のコンテキストでの関数が必要です

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

関数には3つのタイプがあります。

  • スカラー
  • インラインテーブル値および
  • マルチステートメント

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

27
SharK
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 itとします。最初に存在するかどうかを確認し、存在する場合は関数を削除して、上で示したように関数を作成します。

また、存在を確認するときに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
3
M.Ali

私の場合、これは、proc名とまったく同じテーブル名を持っているときに発生しました。したがって、プロシージャ名またはプロシージャで参照されるテーブルを変更すると、このエラーメッセージも修正されます。

1
sesy

コードに関連するエラーについて通知するものがあります。
エラーは_Cannot perform alter on 'dbo.GetTableFromDelimitedValues' because it is an incompatible object type_を示しています
これは、_ALTER...._の後の行を調べる必要があることを意味します
そしてそうです。
@input varchar(max)
SQLサーバー2008 r2はオブジェクトvarchar(MAX)を受け入れませんが、これはストアドプロシージャを実行する場合のみです
手動でテーブルを作成すると、完全に受け入れられます。
大きなセルが必要な場合は、varchar(1024)またはvarchar(2048)と入力します。どちらも使用できます。数日前にこの問題に直面しました...
それは私の謙虚な意見です

追加の変更
これを使って

_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
_


.... 'から "への変更に注意してください

**追加の変更**

私は以下も使用していますが、問題なく動作します...問題はありません...

_IF  EXISTS (SELECT [name] FROM sys.objects 
            WHERE object_id = OBJECT_ID('GetTableFromDelimitedValues'))
BEGIN
   DROP FUNCTION [GetTableFromDelimitedValues];
END
BEGIN
   execute('CREATE FUNCTION [dbo].[GetTableFromDelimitedValues]() 
    RETURNS 
    @Result TABLE (
    Value nvarchar(4000)) 
    AS 
    BEGIN 
    RETURN 
    END')
    execute('ALTER FUNCTION [dbo].[GetTableFromDelimitedValues](
       @input varchar(max),
       @delimiter char(1) = ",")
       RETURNS @Result TABLE (
       Value nvarchar(4000))
       AS 
    BEGIN 
    RETURN 
    END')
END
GO
_
0
Lefteris Gkinis

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

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
0
ary