【问题标题】:Use a SQL Server Table-valued function like a view像视图一样使用 SQL Server 表值函数
【发布时间】:2016-09-08 22:43:54
【问题描述】:

我在 SQL Server 2012 中构建了一个表值函数,它返回表中每个唯一车辆在用户定义的日期和时间之前的最后一个已知位置:

CREATE FUNCTION [dbo].[LAST_AVL_LOC] (@dateIn datetime2(7))
RETURNS TABLE 
AS
RETURN
WITH summary AS (
    SELECT p.title, 
           p.local_Time,
           p.vgroup,
           p.speed,
           p.heading,
           p.latitude, 
           p.longitude,
           p.shape,
           ROW_NUMBER() OVER(PARTITION BY p.title ORDER BY p.local_Time desc) AS rk
           FROM ac.AVL_POINTS p where  p.local_Time < @dateIn)
SELECT s.*
  FROM summary s
WHERE s.rk = 1

这段代码运行良好,可以在 SQL 中这样调用:

select * from [dbo].[LAST_AVL_LOC]('09/05/2016')

这将返回表格中每辆独特车辆的表格,其中包含 2016 年 9 月 5 日之前的最后已知位置和其他信息。

我的问题是此功能需要由 SQL 之外的 GIS 包使用,并且该软件唯一暴露和“可调用”的 SQL 结构是表和视图。我想将这个表值函数包装在一个视图中,以便可以以这样的方式调用它并仍然返回同一个表:

select * from VIEW_LAST_AVL_LOC where last_date = '09/05/2016'

这样的壮举可能吗?

【问题讨论】:

  • 视图就是……视图。无法接收参数。
  • 你能重写这个函数来做类似 GROUP BY p.local_Time 的事情吗?您正在使用按日期查询的位置,我认为这不会是巨大的结果集。另一个想法 - MSSQL2012 可以创建内存优化表,您可以将数据预加载到该表中
  • 写一个几乎相同但没有p.local_Time &lt; @dateIn的视图,并使用select * from view where local_time &lt; '09/05/2016'调用它

标签: sql sql-server


【解决方案1】:

创建不带 where 条件的 VIEW (where p.local_Time )。因此它将包含所有数据,您可以使用以下查询:

从 VIEW_LAST_AVL_LOC 中选择 *,其中 last_date = '09/05/2016'

注意:我们不能在视图中使用参数。

【讨论】:

  • 删除 where 子句并将其转换为视图的行为不正确。该函数返回日期之前的最后一个位置。如果您输入“2016-09-13 15:00”,您将获得该时间之前每辆独特汽车的最后位置,无论是两分钟前还是两天前。在视图中,输入 where last_date = '2016-09-13 15:00' 不起作用,因为它只返回那个确切时间的位置。输入 last_date
【解决方案2】:

绝对可以实现。

我们为我正在处理的合约的 Data Vault 实现了一组类似的非规范化函数。

如果我们想查看特定日期的记录状态,我们只需传递日期,例如:(2015/05/01),它会返回当时的所有记录及其状态。

对于基于数据仓库的系统,我强烈推荐这种方法。

我们如何设置去规范化函数的示例

CREATE FUNCTION [dbo].[fn_Customer_Contacts_AsAt] (@date datetime(7))
RETURNS TABLE 
AS
    SELECT 
        h.hk_Customer_Contact
        h.Number
        s.CustomerID
        s.CustomerName
        s.Job_ID
        s.Title
        s.Description
        s.Loaction
        s.Submit_Date
        s.Fulfill_Date
    FROM
            dvr.hub_Customer_Contacts h
    join    dvr.sat_Customer_Contacts s     on h.hk_Customer_Contact = s.hk_Customer_Contact
    WHERE
        s.Load_Date > @date
    and s.Load_EndDate < @date

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 2022-01-16
    相关资源
    最近更新 更多