<table-valued function>不是一个被认可的内置函数名称。

14

我遇到了这个错误:

Msg 195,级别 15,状态 10,行 1
“fnParseName” 不是已知的内建函数名称。

这是相关查询语句:

SELECT  fnParseName(DOCTORFIRSTNAME+' ' +DOCTORLASTNAME) 
  FROM [PracticeandPhysician]

这是fnParseName函数的代码

create FUNCTION [dbo].[fnParseName]
               (@FullName NVARCHAR(128))
RETURNS @FullNameParts TABLE  (FirstName  NVARCHAR(128),
                               Middle     NVARCHAR(128),
                               LastName   NVARCHAR(128))
AS
  BEGIN
    ... function body that populates @FullNameParts ...
    RETURN
  END

为什么我会收到这个错误?


如果有帮助的话,它是一个表值函数。 - Alex Gordon
5个回答

20

这是一个返回表格的函数。所以你可能想要:

SELECT p.DOCTORFISTNAME, p.DOCTORLASTNAME, t.FirstName, t.Middle, t.LastName
  FROM dbo.[PracticeandPhysician] AS p
  CROSS APPLY dbo.fnParseName(p.DOCTORFIRSTNAME + ' ' + p.DOCTORLASTNAME);

请注意,您不能说:
SELECT dbo.TableValueFunction('foo');

任何多于你能说的话:

SELECT dbo.Table;
--or
SELECT dbo.View;

然而,你可以说:

SELECT * FROM dbo.fnParseName('foo bar');
--or
SELECT FirstName, Middle, LastName FROM dbo.fnParseName('foo bar');

我并没有验证你的函数是否做了你想要的事情,或者是否高效。

请像其他人建议的那样始终使用dbo.前缀


我不是在第一个示例中使用了CROSS APPLY展示了吗?它应该输出dbo.[PracticeandPhysician]中每个输入行的列。 - Aaron Bertrand
CROSS APPLY仅返回从表值函数产生结果集的外部表中的行。来自MSDN文档:http://msdn.microsoft.com/en-us/library/ms175156.aspx - Aaron Bertrand
始终使用dbo前缀加一。 - Hakan Fıstık

12

你必须在SQL函数调用前加上模式名称 dbo. 或该函数的模式名称(dbo是默认模式)。

SELECT dbo.fnParseName(--etc

Msg 4121,级别 16,状态 1,行 2 找不到列“dbo”或用户定义的函数或聚合“dbo.fnParseName”,或名称不明确。 - Alex Gordon
@MattGibson 如果这有帮助的话,它是一个表值函数。 - Alex Gordon
@PeterWishart 是的,我同意你的观点,但我确认我是在正确的数据库上创建它的。 - Alex Gordon
2
@Peter 这是一个表值函数。前缀很重要,但真正的问题是你不能像表达式一样引用表值函数(尽管你可以使用标量 UDF)。 - Aaron Bertrand
是的,@Aaron,我也在想这个问题。即使它能够工作,也无法确定会返回什么,因为语法不太清楚。 - Matt Gibson
显示剩余3条评论

1

UDFs/函数需要以模式名称(很可能是“dbo”)为前缀。将调用更改为

SELECT
    dbo.fnParseName(DOCTORFIRSTNAME + ' ' + DOCTORLASTNAME) 
FROM
    [PracticeandPhysician]

Msg 4121,级别 16,状态 1,行 2 找不到列“dbo”或用户定义的函数或聚合“dbo.fnParseName”,或名称不明确。 - Alex Gordon
模式前缀不是问题所在(虽然仍然需要,但存在更基本的语法问题)。 - Aaron Bertrand

1
如果你想将tfn返回的值分配给存储过程中的变量,可以按照以下方式进行:
select  @my_local_variable_in_procedure = column_name_returned_from_tfn from dbo.my_inline_tfn (@tfn_parameter)

1
你遇到的问题与我遇到的相似。标量函数和表内联函数在实现上有很大的不同。请参见下面的区别。
 Create function udfCountry
 (
@CountryName varchar(50)
 )
 returns varchar(2)
 as 
 BEGIN
 Declare @CountryID varchar(2),
    @Result varchar(2)

 Select @CountryID = Country from 
dbo.GeoIPCountryNames where CountryName = @CountryName

set @Result = isNull(@CountryID, 'NA')
if @Result = 'NA'
set @Result = 'SD'
return @Result
End

//实现

select dbo.[udfCountry]('Nigeria')

// 样例结果

NG

// 内联表函数示例

 Create FUNCTION  ConditionEvaluation
 (
  @CountrySearch varchar(50)
 )
 returns @CountryTable table 
(
Country varchar(2),
CountryName varchar(50)
 )
 as 

 Begin

 Insert into @CountryTable(Country, CountryName)
 Select Country, CountryName from GeoIPCountryNames
 where Country like '%'+@CountrySearch+'%'
 return 
 end

//实现示例

 Declare @CountrySearch varchar(50)
 set @CountrySearch='a'
 select * from  ConditionEvaluation(@CountrySearch)

实现标量的方式与内联表格有很大不同。希望这可以帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接