7

我收到給定函數的以下錯誤。在SQL中創建和更改表值函數時不兼容對象類型

Msg 2010,Level 16,State 1,Procedure GetTableFromDelimitedValues,Line 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 

有人可以通過修復函數來幫助我獲得兼容類型嗎?

回答

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 

in OBJECT_ID函數你只需要傳遞函數名稱而不是模式。爲什麼會先創建它,然後是Alter呢。只要檢查是否存在1st,如果它存在然後拖放函數並創建您的函數,如上所示。

也不要在where子句中添加Type檢查是否存在,如果有另一個對象不是函數,而是任何其他對象具有相同的名稱,它將不會在您的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 
+0

謝謝您的回覆。 最初我以與你所建議的方式(Drop | Create)相同的方式處理了這個問題,但它沒有經過DROP的問題,可能有時執行用戶可能沒有權限在產品環境中刪除,因此更安全的一面應該與ALTER一起。 – ary

+0

@ary現在看看我已經更新了我的答案,以解決您在實際查詢中遇到的問題。 –

+0

感謝您的持續幫助。 對不起,它沒有工作,並繼續顯示相同的錯誤。 無法對'dbo.GetTableFromDelimitedValues'執行更改,因爲它是不兼容的對象類型。 – ary

0

我有事要通知你的錯誤與您的代碼:
錯誤說Cannot perform alter on 'dbo.GetTableFromDelimitedValues' because it is an incompatible object type
這意味着你要看看你的行ALTER....
後是有t爲:
@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 
+0

謝謝你的幫助。 對不起,它沒有工作,並繼續顯示刪除最大與1024後相同的錯誤。 – ary

+0

嘗試查看'@delimiter char(1)=',')'語法是否正確...在任何情況下問題來自這個領域。 –

+0

爲我工作得很好...'IF NOT EXISTS(SELECT 1 FROM sys.objects中 WHERE OBJECT_ID = OBJECT_ID( '[GetTableFromDelimitedValues]')) BEGIN 執行(「CREATE FUNCTION [DBO]。[GetTableFromDelimitedValues]( @input varchar(max),@delimiter char(1)=「,」) RETURNS @Result TABLE( Value nvarchar(4000))AS BEGIN RETURN END') END GO' ....注意從'''更改爲''' –

0

我確認下面的代碼工作。似乎問題是在我的開發過程中以某種方式使用相同名稱創建的標量值函數,並且由於腳本的多部分表值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 
16

您需要DROPCREATE功能在這個特定背景下

由於在函數返回類型的變化,我們必須先刪除然後重新創建函數。

有三種類型的功能,

  • 標量
  • 內嵌表值
  • 多聲明

ALTER不能用來改變功能類型。

相關問題