该名称在函数中不是有效的标识符错误

时间:2014-02-25 08:47:08

标签: sql-server-2008

     Create FUNCTION [dbo].[fngetname]        
    (         
       @OrganisationID int=null,        
       @UserID int=null,        
       @ClientTypeID int        

    )        
    RETURNS  varchar(500)        
    BEGIN        
    DECLARE @Name VARCHAR(500)        

     DECLARE @dbName VARCHAR(500)            
    set @dbName=(select ClientDataBase from dbo.ClientType where ClientTypeID=@ClientTypeID)       

    begin        

   set @Name='select UserName from ['+ @dbName+'].dbo.Users where UserID='+convert(varchar,@UserID)  
    exec @Name   
    end        

       return @Name                
    end 

2 个答案:

答案 0 :(得分:3)

这里有两个问题,首先如果你想执行动态sql,你需要将你的语句变量封装在括号中

您需要在函数声明中为exec @Name添加括号。 函数被写入但无法在exec

处执行

exec @Name替换为exec (@Name)

只需尝试两个简单的行就可以轻松地重现此错误(ofc将表和db-name替换为您拥有的东西;)):

DECLARE @statement VARCHAR(MAX) = 'SELECT * FROM [nana].dbo.Fruits'
exec @statement

这应该抛出完全相同的错误。 然后在()周围添加@statement即可。

第二个问题是,你不能在函数中使用动态SQL ,因为它们必须是确定性的(look here)。

要解决此问题,请将该函数行为重写为存储过程,然后它应该可以工作;)。

将函数重写为过程的一种方法可能如下所示(未经测试,因为我没有设置数据库结构):

CREATE PROCEDURE spGetName @OrganisationID INT = NULL, @UserID INT = NULL, @ClientTypeID INT
AS
BEGIN
    DECLARE @Name VARCHAR(500)        
    DECLARE @dbName VARCHAR(500)            
    SET @dbName = (SELECT ClientDataBase FROM dbo.ClientType WHERE ClientTypeID = @ClientTypeID)

    SET @Name = 'select UserName from [' + @dbName + '].dbo.Users where UserID=' + CONVERT(VARCHAR, @UserID)  
    exec(@Name)
END
GO

答案 1 :(得分:0)

尝试使用

exec sp_executesql @statement