从表值函数中选择?

Posted

技术标签:

【中文标题】从表值函数中选择?【英文标题】:Select from table valued function? 【发布时间】:2019-12-10 23:38:31 【问题描述】:

视图是否可以从表值函数中选择列?

CREATE FUNCTION fnGetLatestOrderStatus(@OrderId int)
RETURNS TABLE
AS
RETURN 
    SELECT TOP (1) Status, TimestampUtc    
    FROM OrderStatusHistory
    ORDER BY TimestampUtc DESC
GO

CREATE VIEW MyView AS
SELECT  
    OrderId,
    CustomerId,
    fnGetLatestOrderStatus(OrderId).Status AS OrderStatus,
    fnGetLatestOrderStatus(OrderId).TimestampUtc AS OrderStatusTimestamp
FROM Orders
GO

SSMS 不喜欢这个错误

找不到列“fnGetLatestOrderStatus”或用户定义的函数或聚合“fnGetLatestOrderStatus”,或者名称不明确。

【问题讨论】:

【参考方案1】:

这是你想做的吗?

SELECT o.OrderId, o.CustomerId, flos.*
FROM Orders o CROSS APPLY
     dbo.fnGetLatestOrderStatus(o.OrderId int) flos;

您需要在FROM 子句中调用表值函数。

【讨论】:

【参考方案2】:

如果你的语法正确,它是可能的。注意:

    函数必须是完全限定的,包括架构名称(我假设它是 dbo)。 您可以按照任何常规查询从函数中进行选择,而不是像您一样使用对象引用表示法。
    CREATE VIEW MyView
    AS
    SELECT  
      OrderId
      , CustomerId
      , (select Status from dbo.fnGetLatestOrderStatus(OrderId)) AS OrderStatus
      , (select TimestampUtc from dbo.fnGetLatestOrderStatus(OrderId)) AS OrderStatusTimestamp
    FROM Orders
    GO

注意:Gordon 的解决方案可能更适合您的问题,但我认为值得指出 2 个错误供您参考

【讨论】:

您是否说@GordonLinoff 解决方案更好,因为两次调用该函数打开了底层数据更新的大门?换句话说,视图行不可能但有可能将先前的OrderStatusHistory.Status 与新的OrderStatusHistory.TimestampUtc 配对? @BaltoStar 不,没有任何接收无效数据的危险,只是由于两次调用该函数而导致性能略有下降。 Gordon 展示的方式是如何充分利用内联表值函数。

以上是关于从表值函数中选择?的主要内容,如果未能解决你的问题,请参考以下文章

从表值函数返回表并在临时表中设置该值

选择与表值函数连接中的 Oracle 标量函数

sql server 2012 - 无法授予对多语句表值函数的选择

为使用表值函数的选择查询更正参数类型

SQL 2005 - 表值函数编译正常,但选择时在 .. 附近抛出不正确的语法

使用 select 语句在表值函数中传递参数