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?
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:
Mit ALTER kann der Funktionstyp nicht geändert werden.
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
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
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.
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