1

我有一个存储过程,它根据记录中包含的信息和其他表中的一些信息计算给定记录的特殊值。我想编写一个查询,该查询返回一个包含每条记录的常规信息的结果表,并在新列中添加每条记录的计算值。例如,我想要这样的东西:

SELECT
   [id]     as Name,
   [shape]  as Shape,
   [color]  as Color,
   EXEC FindCode
       @id = [id]
       @shape = [shape]
       @color = [color] 
   as Code
FROM Shapes

使用与上述“伪”代码等效的情况,我希望得到这样的结果集:

Name |  Shape  | Color | Code
-----+---------+-------+-----
AB   |  Circle | Blue  | 4276
BC   |  Square | Red   | 9825
CD   |  Rect   | Gray  | 3723

其中名称、形状和颜色已作为 id、形状和颜色包含在表中,但“代码”是使用存储过程计算的。在 SQL Server 2008 R2 中执行此操作的最佳方法是什么?

4

3 回答 3

1

如果计算代码的算法完全基于(依赖)同一行中的其他列,那么最好的选择是将计算列添加到表中

Alter Table MyTable Add Column
   Code as [Enter expression here that calculates the code]

例如,

  Alter Table MyTable Add Column
   Code as Case id 
           When 'AB' Then Case Shape
                             When 'Circle' Then 4176
                             When 'Square' Then 4177
                             When 'Rect'   Then 4178 End
           When 'BC Then  Case Shape
                             When 'Circle' Then 9825
                             When 'Square' Then 9826
                             When 'Rect'   Then 9827 End

           End

如果此算法依赖于其他行或其他表中的数据,则需要使用用户定义函数 [UDF]。如果可能,使其成为一个相关的InLine Table 生成 UDF,而不是一个标量 UDF。

于 2012-09-04T23:11:38.190 回答
1

您需要创建一个与您的过程执行相同操作的函数,然后在查询中使用 CROSS APPLY。

于 2012-09-04T23:12:12.550 回答
1

以下是使用此线程中的一些建议的查询可能看起来像的几个示例。

1.CROSS APPLY使用标量值用户定义函数

SELECT
     s.[id]     as Name
    ,s.[shape]  as Shape
    ,s.[color]  as Color
    ,c.[code]   as Code
FROM 
    [Shapes] s
CROSS APPLY
    fnFunctionThatCalculatesCodeAsAScalarValue(s.[id], s.[shape], s.[color]) c

2. 将表定义更改为具有计算列:

CREATE TABLE Shapes AS
(
    [id] int NOT NULL,
    [shape] varchar(40) NOT NULL,
    [color] varchar(40) NOT NULL,
    [code] AS fnFunctionThatCalculatesCodeAsAScalarValue ([id], [shape],[color])
)

3.JOIN使用表值用户定义函数:

SELECT
     s.[id]     as Name
    ,s.[shape]  as Shape
    ,s.[color]  as Color
    ,c.[code]   as Code
FROM 
    [Shapes] s
JOIN
    fnFunctionThatCalculatesCodesAsATable() c
    ON
    s.[id] = c.[id]
    AND
    s.[shape] = c.[shape]
    AND
    s.[color] = c.[color]

或者4.您可以预先填写一个不同的表格,将所有可能的颜色代码(如果可行)。

在示例 1 和示例 2 中按原样使用标量值函数将执行最差,尤其是在它必须跟踪其他表时,因为它将每行执行一次。

PERSISTED您可以通过在列定义之后添加关键字来提高计算列示例的性能。这可能是会做的。持久化的值将在插入时计算一次,在行更新时自动更新,但从其持久化位置提取以用于选择语句。

于 2012-09-04T23:28:11.430 回答