4

我正在尝试创建一组要写入文件的数据,它本质上是一个由许多不同表中的各种字段组成的报告,有些列需要对它们进行一些处理,有些可以刚刚被选中。

不同的用户可能希望对某些列执行不同的处理,并且在未来,我可能需要为计算列添加额外的函数。

我正在考虑最简洁/最灵活的方法来存储和使用这些计算列可能需要的所有不同功能,我脑子里有两个想法,但我希望可能有更多我缺少明显的解决方案。

举一个简单但有点奇怪的例子,一个 Staff 表:

Employee |    DOB           |   VacationDays
Frank    |    01/01/1970    |   25
Mike     |    03/03/1975    |   24
Dave     |    05/02/1980    |   30

我想我要么最终得到一个像这样的查询

SELECT NameFunction(Employee, optionID),
       DOBFunction(DOB, optionID),
       VacationFunction(VacationDays, optionID),
from Employee

对于用户定义的函数,optionID 将在函数内部的 case 语句中用于决定要执行的处理。

或者我想使用其他函数的查找表来定制返回数据的方式:

ID  |    Name                  |   Description
1   |    ShortName             |   Obtains 3 letter abbreviation of employee name
2   |    LongDOB               |   Returns DOB in format ~ 1st January 1970
3   |    TimeStampDOB          |   Returns Timestamp for DOB
4   |    VacationSeconds       |   Returns Seconds of vaction time
5   |    VacationBusinessHours |   Returns number of business hours of vacation

哪个看起来更整洁,但我不确定如何制定查询,大概是使用动态 SQL?有明智的选择吗?

这些函数将用于几千行。

我找到的最接近的答案是在这个线程中: Call dynamic function name in SQL

我不是动态 SQL 的忠实粉丝,尽管在这种情况下,我认为这可能是获得我想要的结果的最佳方式?

任何答复表示赞赏,谢谢,克里斯

4

3 回答 3

1

我会选择第二种解决方案。您甚至可以在查找表中使用真实存储的过程名称。

create proc ShortName (
    @param varchar(50)
)as
begin
    select 'ShortName: ' + @param
end
go

declare @proc sysname = 'ShortName'

exec @proc 'David'

如上例所示,exec的第一个参数(即过程名)可以是参数。这说明了所有关于动态 sql 的常见警告......

于 2012-05-30T10:39:25.323 回答
1

最后,你应该选择更快的那个,所以你应该尝试两种方式(以及任何其他人可能想出的方式)然后再决定。

我更喜欢第一个选项,只要您的函数没有对表格的额外选择。如果不打算在不同的报表中重用它们,您甚至可能不需要用户定义的函数。

我更喜欢仅使用 Dynamic SQL 来提高查询的性能,例如添加动态排序或添加/删除复杂的 WHERE 条件。

但这些都是主观意见,最好的办法是尝试、比较和决定。

于 2012-05-30T11:21:34.157 回答
1

实际上,这不是什么更快的问题。这是一个让代码更简洁的问题,特别是对于添加新功能(新列、新列格式、重新排序)。

不要将您的第二种方法视为“使用动态 SQL”,因为这往往具有负面含义。相反,将其视为一种数据驱动的方法。您想要构建一个表来描述用户可以获得的列和格式。这很棒!然后,用户可以提供列列表,您将拥有一个神奇的存储过程,它将来自用户的信息与元数据表中的信息结合起来,并产生所需的结果。

我是数据驱动方法的忠实拥护者,而动态 SQL 是迄今为止我发现的用于实现它们的最佳 SQL 工具。

于 2012-05-30T13:19:18.853 回答