wake-up-neo.net

Inkompatibler Objekttyp beim Erstellen und Ändern einer Tabellenwertfunktion in SQL

Ich erhalte den untenstehenden Fehler für die angegebene Funktion.

Msg 2010, Ebene 16, Status 1, Prozedur GetTableFromDelimitedValues, Zeile 2 Änderung für 'dbo.GetTableFromDelimitedValues' kann nicht ausgeführt werden, da es sich um einen inkompatiblen Objekttyp handelt.

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

Kann mir bitte jemand helfen, den kompatiblen Typ zu erhalten, indem die Funktion repariert wird?

12
ary

Sie müssenDROPunddie Funktion in diesem speziellen Kontext erstellen 

Da der Rückgabetyp der Funktion geändert wird, müssen wir die Funktion löschen und dann neu erstellen.

Es gibt drei Arten von Funktionen:

  • Scalar
  • Inline-Tabelle bewertet und
  • Multi Statement

Mit ALTER kann der Funktionstyp nicht geändert werden.

26
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

in OBJECT_ID function müssen Sie nur den Funktionsnamen und nicht das Schema übergeben. und warum sollte es zuerst erstellt werden und dann Alter. Überprüfen Sie einfach die Existenz 1. Wenn es existiert, dann lassen Sie die Funktion fallen und erstellen Sie Ihre Funktion wie oben gezeigt. 

Fügen Sie bei der Überprüfung der Existenz nicht die Variable Type in die where-Klausel ein. Wenn es sich um ein anderes Objekt handelt, nicht um eine Funktion, sondern um ein anderes Objekt mit demselben Namen, wird es nicht in Ihre select-Anweisung aufgenommen, und Sie erstellen am Ende eine Funktion mit benennen, dass ein Objekt bereits existiert (dies wird einen Fehler auslösen) 

WENN Sie es so machen möchten, wie Sie es tun würden 

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

Ich muss Sie auf einen Fehler in Bezug auf Ihren Code hinweisen:
Der Fehler besagt Cannot perform alter on 'dbo.GetTableFromDelimitedValues' because it is an incompatible object type
Das heißt, Sie müssen in Ihren Zeilen nach dem ALTER....
Und ja, es gibt:
@input varchar(max)
Der SQL Server 2008 R2 akzeptiert keine Objekte varchar(MAX), aber das ist nur, wenn Sie eine gespeicherte Prozedur ausführen
Denn wenn Sie eine Tabelle von Hand erstellen, wird diese vollständig akzeptiert.
Wenn Sie eine große Zelle möchten, geben Sie varchar(1024) oder varchar(2048) ein. Beide werden akzeptiert. Ich stehe vor diesem Problem vor ein paar Tagen ...
Das ist meine bescheidene Meinung

WEITERE ÄNDERUNGEN
Benutze das

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


.... Achten Sie auf den Wechsel von "zu"

** WEITERE ÄNDERUNGEN **

Ich benutze die folgenden, die auch gut funktioniert ... ohne Probleme ...

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

In meinem Fall geschah dies, wenn ich einen Tabellennamen genau wie proc name habe. Wenn Sie also den Proc-Namen oder eine Tabelle ändern, auf die im Proc verwiesen wird, sollte diese Fehlermeldung ebenfalls behoben werden.

0
Senay

Ich bestätige, dass der folgende Code funktioniert. Anscheinend war das Problem irgendwie eine Skalarwertfunktion, die während meiner Entwicklung mit demselben Namen erstellt wurde, und erhielt einen Fehler, da die Änderungsfunktion für mehrteilige Tabellenwerte des Skripts damit kompatibel ist. 

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