Несовместимый тип объекта при создании и изменении функции табличного значения в 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
Может кто-нибудь, пожалуйста, помогите мне получить совместимый тип, исправив функцию?
6 ответов
Вам нужно СОЗДАТЬ и СОЗДАТЬ функцию в этом конкретном контексте
Поскольку в возвращаемом типе функции есть изменения, мы должны удалить, а затем воссоздать функцию.
Есть три типа функций,
- скаляр
- Встроенная таблица оценена и
- Мульти заявление
ALTER нельзя использовать для изменения типа функции.
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 при проверке существования, если есть другой объект, не функция, а какой-либо другой объект с тем же именем, он не подхватит его в вашем операторе 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
В моем случае это произошло, когда у меня имя таблицы совпадает с именем процедуры. поэтому изменение имени процедуры или таблицы, указанной в процедуре, также должно исправить это сообщение об ошибке.
У меня есть что сообщить о вашей ошибке, связанной с вашим кодом:
Ошибка говорит 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
Я подтверждаю, что приведенный ниже код работает. Кажется, проблема была в том, что во время моей разработки была создана функция скалярного значения с тем же именем, и в ней произошла ошибка, так как функция выражения alter для таблицы значений из нескольких частей скрипта совместима с ней.
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
введите описание изображения здесь
- ошибка в том, что функция создана, а возврат данных не определяется полем, просто измените его после возврата из таблицы (добавить поле).
- ошибка исправления решения:
- удаленная функция просто
- редактировать ключевую работу "Alter" => "Create"
- F5 - функция создания - успех