1

我有一个带有计算列的视图,上面有一个 TV 功能,(简化)如下:

create view     dbo.vwEvent_A   as
select  ea.idEvent, ea.dtEvent, ea.cSys, ..
    ,   sd.sSGJR + '-' + right('0' + cast(ea.tiBtn as varchar), 2) [sSGJRB] 
    from    tbEvent_A ea
    inner join  ..
    left outer join vwDevice sd on  sd.cSys = ea.cSys   ..

create function     dbo.fnEventA_GetTopByRoom
(
    @cSys       char( 1 )
,   @tiGID      tinyint
)
returns table
as
return
    select  top 1   *
        from    vwEvent_A
        where   bActive > 0 and cSys = @cSys
    order   by  siIdx desc, tElapsed

执行该函数时,我不仅减少了 1 列数据,而且列标题也向下滑动(跳过计算列)。 然而,最神奇的是,所有列的数据都保持不变!

从源数据中执行'select *',直接查看和从函数中查看 展开(和包装)部分,显示移动的列标题和数据

我可以接受计算列被“区分”并从结果集中推出的事实,但它只推出列标题,使用此函数搞乱一切,因为现在返回的列具有错误的数据类型。我找不到任何文档提及任何相关内容。

有谁知道怎么回事??

以及如何解决它的任何想法?我将用显式替换函数调用select * from vwEvent_A(添加必要条件),但这个函数存在的主要原因是代码重用.. [见下文]

编辑:打点是(对于稍后阅读此内容的人),
- View 确实被其他对象重用(至少到目前为止没有表现出任何类似的问题)。最近的修订版添加了作为罪魁祸首的计算列。
- 存在 func 以提供单个最高优先级行,然后OUTER APPLY在另一个存储过程中 -ed。我没有找到更好/更简单的方法来做到这一点。
- 刷新 func (by ALTER FUNC) 甚至重新创建它 (by DROP FUNC / CREATE FUNC) 没有任何效果(输出差异)。

4

1 回答 1

3

我怀疑自从创建函数以来,计算列已添加到视图中。

两部分解决方案:

  1. 运行sp_refreshsqlmodule以更新视图和函数的元数据,从视图开始:

     EXEC sp_refreshsqlmodule N'dbo.vwEvent_A';
     EXEC sp_refreshsqlmodule N'dbo.fnEventA_GetTopByRoom';
    
  2. 停止SELECT *在您的视图和功能中使用。这正是我们不这样做的原因之一。还建议创建这两个对象WITH SCHEMABINDING,以便架构更难不同步(您希望它很难与其他对象所依赖的对象的输出混淆)。

于 2013-03-28T23:09:01.770 回答