Несовместимый тип объекта при создании и изменении функции значения таблицы в SQL
Я получаю следующую ошибку для данной функции.
Msg 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
Может ли кто-нибудь помочь мне получить совместимый тип, установив функцию?
Ответы
Ответ 1
Вам нужно DROP и СОЗДАТЬ функцию в этом конкретном контексте
Так как есть изменение в возвращаемом типе функции, мы должны затем воссоздать функцию.
Существует три типа функций,
- Скалярное
- Встроенная таблица с оценкой и
- Multi Statement
ALTER не может использоваться для изменения типа функции.
Ответ 2
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
вам нужно передать только имя функции, а не схему. и зачем создавать его 1-го, а затем Alter
его. Просто проверьте наличие 1-го, если он существует, а затем отмените функцию и создайте свою функцию, как я показал выше.
Также не добавляйте Type
в where where при проверке существования, если есть другой объект, а не функция, но любой другой объект с тем же именем, он не будет забирать его в вашем заявлении 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
В моем случае это произошло, когда у меня имя таблицы точно такое же, как и имя процесса. поэтому изменение имени proc или таблицы, указанной в proc, также должно исправить это сообщение об ошибке.
Ответ 4
У меня есть что сообщить о вашей ошибке, связанной с вашим кодом:
Ошибка говорит Cannot perform alter on 'dbo.GetTableFromDelimitedValues' because it is an incompatible object type
Это означает, что вам нужно смотреть на свои строки после ALTER....
И да, есть:
@input varchar(max)
SQL Server 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
Ответ 5
Я подтверждаю, что приведенные ниже работы кода. Кажется, проблема была как-то скалярной функцией значения, созданной с тем же именем во время моей разработки, и получила ошибку, так как с ней совместима функция выражения walter.
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