有时在处理数据时,过程性编程是绝对不可避免的。
我目前正在优化一些遗留代码。它使用一个游标,63对IF
/ELSE
语句和BEGIN
/END
语句等。我曾希望对光标进行逆向工程,使其成为一个程序化的过程。现在我在解码算法的最后,我意识到…糟糕……有是程序性的,因为对一条记录所做的每一个选择都依赖于对前面所有记录的处理结果。
所以现在我很纠结…在SQL Server处理(CLR sp, UDF等)中混合过程代码还有其他选择。我坚信使用正确的工具来完成工作,所以我倾向于为此制作一个。net CLR SP。但是简化光标会更快更简单,但仍然保持光标。
你们觉得怎么样?现在我们已经可以从SQL Server中访问。net模块了,那么使用游标是否合适呢(在我看来,这是一开始的拼凑/工作)?
至少对于SQL server,它同时具有会话和全局临时表以及表变量,我无法想象我会选择使用服务器端游标的场景。并不是所有的代码都可以基于集合,就像你在你的遗留应用程序中发现的那样(你确定没有其他选择吗?),但即使你必须按程序遍历记录,游标也是最糟糕的选择。
使用表变量,例如:(对于非常大的表集,这种方法的性能开始下降)
Declare @Pks Table (pk integer primary key not null)
Insert @pks(pk)
Select pkcolName from table where ... [here put logic to
extract id values for rows you need to iterate over
-- then put procedural code here ...
Declare @pk Integer
While Exists (Select * From @pks) Begin
Select @pk = Max(pk) From @pks -- assuming you need to work
-- on pk values from highest to lowest
// Here do work on one record at a time, using value in @pk
Delete @pks Where pk = @pk
End
我会在客户端/应用程序服务器上运行c#循环,根据需要调用存储过程。一般来说,c#的开发和单元测试要快得多,也容易得多,而且即使使用CLR,它也比在数据库中执行所有操作的存储过程运行得更快。