我正在尝试创建一组我要写入文件的数据,它本质上是一个由来自多个不同表格,某些列的各个字段组成的报告需要对它们进行一些处理,有些可以选择。
不同的用户可能希望对某些列执行不同的处理,并且将来,我可能需要为计算列添加其他功能。
我考虑使用最干净/最灵活的方法来存储和使用这些计算列可能需要的所有不同功能,我脑子里有两个想法,但我和#39;我希望可能有一个更明显的解决方案,我错过了。
对于一个简单的,有点奇怪的例子,一个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的忠实粉丝,虽然在这种情况下我认为这可能是获得结果的最好方法吗?
任何回复都表示赞赏, 谢谢, 克里斯
答案 0 :(得分:1)
我会选择第二个解决方案。您甚至可以在查找表中使用真实存储的proc名称。
create proc ShortName (
@param varchar(50)
)as
begin
select 'ShortName: ' + @param
end
go
declare @proc sysname = 'ShortName'
exec @proc 'David'
正如您在上面的示例中所看到的,exec的第一个参数(即过程名称)可以是一个参数。这说明了关于动态sql的所有常见警告......
答案 1 :(得分:1)
最后,你应该选择哪个更快,所以你应该尝试两种方式(以及任何其他人可能提出的方式)并在此之后做出决定。
我更喜欢第一个选项,只要你的函数没有对表的额外选择。如果它们不会在不同的报告中重复使用,您可能甚至不需要用户定义的函数。
我更喜欢使用Dynamic SQL ony来提高查询的性能,例如添加动态排序或添加/删除复杂的WHERE条件。
但这些都是主观意见,最好的是尝试,比较和决定。
答案 2 :(得分:1)
实际上,这不是什么更快的问题。这是一个使代码更清晰的问题,特别是对于添加新功能(新列,新列格式,重新排序)。
不要将您的第二种方法视为“使用动态SQL”,因为这往往会产生负面含义。相反,将其视为数据驱动的方法。您希望构建一个表,描述用户可以获取的列以及格式。这很棒!然后,用户可以提供列列表,您将拥有一个神奇的存储过程,将来自用户的信息与元数据表中的信息相结合,并生成所需的结果。
我是数据驱动方法的忠实粉丝,动态SQL是迄今为止我发现的最好的SQL工具。