如何在SQL函数中重写SQL游标



我必须支持一个现有的sql函数,该函数根据几个表中的项计算学生活动。这个函数被不断调用!它被用于日历显示、输出时间表,当学生参加活动时,他们被签到到由函数确定的活动中。(我用的是VB。Net,也有ASP.net。)当然,这个函数有4个游标,所以性能很差,我做了一个sql分析器。出于测试目的,我注释掉了函数部分,并使用# temp表和while循环进行了重写。现在尝试将其作为函数进行安装和测试,我得到了可怕的错误消息"无法从函数内部访问临时表"。哦,还有更多的好消息:这个函数是18个打印页面,它是巨大的。(这不是我对函数的定义。)我现在真的不能重写整个东西,所以我有什么选择?

如果不知道函数试图解决的问题的任何细节以及问题背后的模式,就很难给出答案。一般来说,假设底层模型相对健全,在SQL中使用游标、while -循环和条件逻辑(if-then-else)是一种代码气味,表明作者未能以基于集合的方式构建问题;相反,她是按照程序来处理的。

通常,当有人从命令式编程(C/c++, Cobol, VB等)的背景中学习SQL时,你会看到这一点。它们用于处理集合(集合),每次处理一个项。

在这个函数的某个地方,几乎可以肯定是一个[可能是复杂的]select语句,其中包含连接、虚拟表和嵌套的子选择,但是在不知道实际细节的情况下,不可能给出任何明确的指导。

fww,我发现有必要使用while循环或游标的唯一一次是,如果我需要手动生成键值或对结果集中的每一行单独执行存储过程。而这通常是由于系统设计或实现中的其他一些失败。

SQL的关键是集合论和关系代数。SQL本质上是一种描述性语言,它以数学为基础,使您可以根据集合操作来描述所需的内容。试图将过程语义硬塞到上面(正如您已经注意到的)会导致性能低下和不必要的复杂性。

这里有两种方法:

  1. 尝试将问题重述为使用四表连接的简单SQL。你可能需要一些"CASE"语句来实现"Function"中的一些逻辑。
  2. 检查函数并查找可以在更新时计算和存储的数据元素。例如,将一些计算负担转移到UPDATE/INSERT进程,并存储结果,使查询进程更容易。

最新更新