我有一个存储过程,它根据该记录中包含的信息和其他表中的一些信息计算给定记录的特殊值。我想编写一个查询,返回包含每个记录的常规信息的结果表,并在新列中添加每个记录的计算值。例如,我想要这样的东西:
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,shape和color,但“Code”是使用存储过程计算的。在SQL Server 2008 R2中执行此操作的最佳方法是什么?
答案 0 :(得分: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 generating UDF,而不是标量UDF。
答案 1 :(得分:1)
您需要创建一个与您的过程完全相同的函数,然后在查询中使用CROSS APPLY。
答案 2 :(得分: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
关键字来提高计算列示例的性能。 这可能就是我会这样做。持久化值将在插入时计算一次,在行更新时自动更新,但从其持久位置拉出以用于select语句。