Je reçois l'erreur ci-dessous pour la fonction donnée.
Msg 2010, niveau 16, état 1, procédure GetTableFromDelimitedValues, ligne 2 Impossible d'effectuer une modification sur 'dbo.GetTableFromDelimitedValues' car il s'agit d'un type d'objet incompatible.
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
Quelqu'un peut-il m'aider s'il vous plaît à obtenir le type compatible en corrigeant la fonction?
Vous devezD&EACUTE;POSERetCR&EACUTE;ERla fonction dans ce contexte particulier
Puisqu'il y a un changement de type de retour de fonction, nous devons abandonner puis recréer la fonction.
Il existe trois types de fonctions,
ALTER ne peut pas être utilisé pour changer le type de fonction.
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
dans la fonction OBJECT_ID
, vous ne devez transmettre que le nom de la fonction, pas le schéma. et pourquoi le créerait le 1 er, puis le Alter
. Il suffit de vérifier l'existence tout d'abord si elle existe, puis supprimez une fonction et créez votre fonction comme je l'ai montré ci-dessus.
De même, n’ajoutez pas Type
dans la clause where lors de la vérification de l’existence, s’il existe un autre objet, non pas une fonction, mais un autre objet du même nom, il ne le prendra pas dans votre instruction select et vous finirez par créer une fonction avec nommer un objet existe déjà (cela jettera une erreur).
SI vous voulez le faire à votre façon, voici comment vous vous y prendrez
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
J'ai quelque chose à signaler à votre erreur liée à votre code:
L'erreur dit Cannot perform alter on 'dbo.GetTableFromDelimitedValues' because it is an incompatible object type
Ce qui signifie que vous devez regarder sur vos lignes après le ALTER....
Et oui, il y a: @input varchar(max)
SQL Server 2008 R2 n'accepte pas les objets varchar(MAX)
, mais uniquement si vous exécutez une procédure stockée.
Parce que si vous créez une table à la main, vous l'acceptez entièrement.
Si vous voulez une grande cellule, tapez varchar(1024)
ou varchar(2048)
, les deux sont acceptés. Je fais face à ce problème il y a quelques jours ...
C'est mon humble avis
MODIFICATIONS COMPLEMENTAIRES
Utilisez ceci
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
.... Faites attention au passage de "à"
** MODIFICATIONS SUPPLÉMENTAIRES **
J'utilise ce qui suit qui fonctionne aussi très bien ... sans aucun problème ...
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
Je confirme que le code ci-dessous fonctionne. On dirait que le problème était en quelque sorte une fonction de valeur scalaire créée avec le même nom au cours de mon développement et a eu une erreur en raison de la compatibilité de la fonction de déclaration de valeur de table à plusieurs pièces du script.
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