16

对于给定的函数,我收到以下错误。

消息 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

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

4

6 回答 6

33

您需要在此特定上下文中DROPCREATE函数

由于函数返回类型发生了变化,我们必须删除然后重新创建函数。

共有三种功能,

  • 标量
  • 内联表值
  • 多语句

ALTER 不能用于更改函数类型。

于 2014-07-08T08:36:19.237 回答
4
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函数中,您只需要传递函数名而不是模式。以及为什么要先创建它然后再创建Alter它。只需检查是否存在 1st 如果它存在然后删除函数并创建你的函数,如我上面所示。

检查是否存在时也不要添加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
于 2014-01-28T23:18:16.887 回答
3

就我而言,这发生在我有一个与 proc 名称完全相同的表名时。因此更改 proc 名称或 proc 中引用的表也应该修复此错误消息。

于 2019-09-24T19:26:52.883 回答
0

我确认以下代码有效。似乎问题是在我的开发过程中以某种方式创建了一个同名的标量值函数,并且由于脚本的多部分表值更改语句函数与其兼容而出现错误。

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
于 2014-01-29T19:28:11.943 回答
0

关于与您的代码相关的错误,我有一些事情要通知:
错误说Cannot perform alter on 'dbo.GetTableFromDelimitedValues' because it is an incompatible object type
这意味着您必须在ALTER....
And yes there t is:
@input varchar(max)
The SQL server 2008 r2 not accept objects之后查看您的行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
于 2014-01-29T00:05:57.387 回答
0

在此处输入图像描述

  • 错误确实创建了函数并且数据返回不是字段定义,只是在表(添加字段)返回后更改。
  • 解决方案修复错误:
  • 刚刚删除的功能
  • 编辑关键词“Alter”=>“Create”
  • F5 创建函数成功
于 2021-10-23T17:02:13.227 回答