0
  1. 如果我有一个myTable包含大约 15 列的表,并且我想选择大约 5 列,那么值得拥有一个rec myTable%ROWTYPE(根本不会使用 10 个列)还是只创建一个TYPE rec...并手动创建(col1 myTable.col1%TYPE...)所有 5 列的字段?

  2. 我们通常在多大程度上创建手动类型与行类型?

  3. 如何为带有连接的 SELECT 查询声明行类型?例如rec tableA%ROWTYPE+ 可能是另一个字段或 2 个字段,tableB但都在 1 个记录类型中?我要手动创建吗?(如果只有 PLSQL 有类似“扩展”或记录继承的东西。

对不起,很长的问题,我希望我有意义。提前致谢。

4

2 回答 2

2

我的偏好是始终使用 %ROWTYPE,或者更好的游标 FOR 循环来声明变量。回到过去(tm),我们过去常常担心内存使用,因此如果它为我们节省了几个字节,那么声明单个字段可能是有意义的。但是现在,IMO,当我们拥有以千兆字节为单位的内存空间时,更大的代码复杂性超过了节省几个字节的价值。就执行速度而言 - 哦,拜托。我们所处的世界是一些最常见的语言在虚拟机下运行。我花了几个小时手动优化汇编程序,以摆脱紧循环的最后一个怪异循环。Java让我发笑。如果我们在 VM 下运行软件,我们会说“我们有太多的周期要烧!”。

要解决每个问题:

  1. 我更喜欢使用游标 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等待未打扫的人这可能不适用 - 但我所处的位置(相信我,它不是最先进的)这是一个足够好的策略。

  2. 我很少创建独立变量来保存 SELECT 或游标的结果,这主要是因为上面的规则 #1。

  3. 为了正确引用 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;
    

    再一次,可能是最简单的事情。越简单越好。

:-)

分享和享受。

于 2013-07-16T17:05:53.787 回答
0

好的起点是文档:

http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/overview.htm#sthref159

(Oracle 数据库 PL/SQL 用户指南和参考)

不如用 Steven Feuerstein 写的一篇文章来改进它:

http://www.oracle.com/technetwork/issue-archive/2012/12-may/o32plsql-1578019.html

于 2013-07-16T14:22:26.527 回答