我的偏好是始终使用 %ROWTYPE,或者更好的游标 FOR 循环来声明变量。回到过去(tm),我们过去常常担心内存使用,因此如果它为我们节省了几个字节,那么声明单个字段可能是有意义的。但是现在,IMO,当我们拥有以千兆字节为单位的内存空间时,更大的代码复杂性超过了节省几个字节的价值。就执行速度而言 - 哦,拜托。我们所处的世界是一些最常见的语言在虚拟机下运行。我花了几个小时手动优化汇编程序,以摆脱紧循环的最后一个怪异循环。Java让我发笑。如果我们在 VM 下运行软件,我们会说“我们有太多的周期要烧!”。
要解决每个问题:
我更喜欢使用游标 FOR 循环来处理几乎所有事情。这是不断尝试回答 Cunningham 的问题的一部分 - “什么是可能起作用的最简单的事情?”。IMO 使用行类型变量是最简单的事情。使用它们消除了显式处理 NO_DATA_FOUND 和 TOO_MANY_ROWS 异常的需要 - 所以我会赞成
FOR aRow IN (SELECT col1, col2, col3
FROM myTable
WHERE some_col = some_value)
LOOP
NULL; -- do something useful here
END LOOP;
超过
DECLARE
var1 myTable.COL1%TYPE;
var2 myTable.COL2%TYPE;
var3 myTable.COL3%TYPE;
BEGIN
SELECT col1, col2, col3
INTO var1, var2, var3
FROM myTable
WHERE some_col = some_value;
NULL; -- do something useful here
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL; -- do something appropriate here
WHEN TOO_MANY_ROWS THEN
NULL; -- do something appropriate here
END;
即使我知道那some_col
是独一无二的——很大程度上是因为我工作的地方今天独一无二的东西明天可能会在我什至不知道存在的某个团队中的一些开发人员的心血来潮下变得不独特。它被称为“防御性编程”,如果它能让我在凌晨 2:00 不被叫到,我是一个快乐的露营者。
有人会抱怨这样做需要在非绝对必要时打开游标的开销。在多年的编程中,我从来没有遇到过这样的情况:这样做会大大降低程序速度,以至于必须重写代码才能使用独立的单例 SELECT。我想在数字丛林黑暗深处的某个地方,在荒野中,时钟速度仍然以个位数兆赫为单位,内存以千字节为单位,这些字节只有 7 位,而贪婪的 Bugblatter Beast of Traal等待未打扫的人这可能不适用 - 但我所处的位置(相信我,它不是最先进的)这是一个足够好的策略。
我很少创建独立变量来保存 SELECT 或游标的结果,这主要是因为上面的规则 #1。
为了正确引用 Obi-Wan,“使用光标 FOR 循环,Luke!”。(说真的 - 这就是他真正所说的。所有“强制”的东西都只是一些听障电影导演梦寐以求的一堆垃圾。Feh!)。写类似的东西
FOR aRow IN (SELECT *
FROM table1 t1
INNER JOIN table2 t2 on (t2.fieldx = t1.fieldx)
INNER JOIN table3 t3 on (t3.fieldy = t2.fieldy))
LOOP
NULL; -- whatever
END LOOP;
再一次,可能是最简单的事情。越简单越好。
:-)
分享和享受。