Sql server 2008 r2 TVF输出在其引用的视图中缺少计算列

Sql server 2008 r2 TVF输出在其引用的视图中缺少计算列,sql-server-2008-r2,user-defined-functions,calculated-columns,Sql Server 2008 R2,User Defined Functions,Calculated Columns,我有一个带有计算列的视图,其顶部有一个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 j

我有一个带有计算列的视图,其顶部有一个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列的数据,而且列标题向下滑动(跳过计算列)然而,最神奇的是,所有列的数据都保持不变

我可以接受这样一个事实,即计算列被“区分”并从resultset中推出,但它只推出列标题,使用此函数会搞乱所有内容,因为现在返回的列具有错误的数据类型。我找不到任何相关文件

有人知道发生了什么事吗???

有没有办法解决这个问题?我将用显式的
select*from vwEvent\u A
(添加必要的条件)替换函数调用,但该函数存在的主要原因是代码重用。。[见下文]

编辑:为i-s添加点(供稍后阅读此内容的人使用),
-视图确实被其他对象重用(至少到目前为止,这些对象没有表现出任何类似的问题)。罪魁祸首的计算列由最近的修订版添加。
-func的存在是为了提供一个最高优先级的行,然后在另一个存储过程中应用该行。我没有找到更好/更容易做到这一点的方法。

-刷新func(通过
ALTER func
)甚至重新创建func(通过
DROP func/CREATE func
)都没有任何效果(输出中的差异)。

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

两部分解决方案:

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

     EXEC sp_refreshsqlmodule N'dbo.vwEvent_A';
     EXEC sp_refreshsqlmodule N'dbo.fnEventA_GetTopByRoom';
    
  • 。这正是我们不这样做的原因之一。还建议使用SCHEMABINDING创建两个对象
    ,这样模式就很难不同步(您希望它很难与其他对象所依赖的对象的输出混淆)


  • 其他SQL客户端也会发生这种情况吗?我很困惑。一方面,您用一个简单的
    EXEC
    解决了OP的问题,但另一方面,您告诉他不要使用使解决方案如此简单的功能(
    SELECT*
    )。你有什么建议吗?@Gabe我不知道它们是相互排斥的。我建议首先不要使用
    SELECT*
    ,这样就不需要解决方案,因为问题不会发生。如果有人从树上跳下来摔断了腿,我会建议他们不要再从树上跳下去,但我会先叫救护车……好吧,如果你是OP,你会如何创建
    fnEventA\u GetTopByRoom
    函数以避免使用
    SELECT*
    ?@Gabe老实说,我可能不会费心使用这个函数。除了稍微缩短where子句之外,我不知道它到底增加了什么。如果我真的觉得重用很有吸引力(我不这么认为),我会使用schemabind创建函数和视图,并对列进行硬编码,而不是使用SELECT*。除非你知道一些关于模式的动态本质的东西,我不知道。更好的是,我会完全放弃视图,将逻辑移到函数中。