在SQL中创建和更改表值函数时不兼容的对象类型

ary*_*ary 12 sql sql-server sql-function create-function sql-server-2008

我得到了给定函数的以下错误.

Msg 2010,Level 16,State 1,Procedure GetTableFromDelimitedValues,Line 2无法对'dbo.GetTableFromDelimitedValues'执行alter,因为它是不兼容的对象类型.

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
Run Code Online (Sandbox Code Playgroud)

有人可以通过修复功能帮助我获得兼容类型吗?

Sha*_*arK 27

您需要在此特定上下文中DROP创建函数

由于函数返回类型有变化,我们必须删除然后重新创建函数.

有三种类型的功能,

  • 纯量
  • 内联表值
  • 多声明

ALTER不能用于更改功能类型.


M.A*_*Ali 5

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
Run Code Online (Sandbox Code Playgroud)

OBJECT_ID函数中,您只需要传递函数名称而不是模式。以及为什么要先创建它,然后再创建Alter它。只需首先检查是否存在(如果存在),然后删除函数并创建您的函数,如我上面所示。

检查是否存在时也不要添加Typewhere 子句,如果有另一个对象不是函数而是具有相同名称的任何其他对象,它不会在您的 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
Run Code Online (Sandbox Code Playgroud)