我们什么时候说“让我们使用%ROWTYPE”而不是%TYPE?

时间:2013-07-16 14:11:48

标签: oracle plsql

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

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

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

  4. 对不起,我希望自己有道理。 提前谢谢。

2 个答案:

答案 0 :(得分:2)

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

解决每个问题:

  1. 我更喜欢使用游标FOR循环来处理所有事情。这是不断尝试回答坎宁安问题的一部分 - “什么是可能有效的最简单的事情?”。使用rowtype变量的IMO是The Simplest Thing。使用它们消除了明确处理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点被叫到,我就是一个快乐的露营者。

    有人会抱怨这样做需要在不是绝对必要时打开游标的开销。在一大堆编程中,我有从不遇到这样一种情况,即这样做会使程序速度降低,以至于必须重写代码才能使用独立的单例SELECT。我认为在数字丛林深处的某个地方,在时钟速度仍以单位数兆赫测量的狂野中,内存以千字节为单位测量,这些字节只有七位,而贪婪的Bugblatter Beast of Traal等待未被吹嘘的这可能不适用 - 但是我所处的地方(相信我,最前沿不是)这是一个足够好的策略。

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

  3. 要正确引用Obi-Wan,“使用光标FOR循环,Luke!”。 (说真的 - 这就是他真正说过的。所有“力量”的东西都只是一些听力困难的电影导演梦寐以求的垃圾。恐惧!)。写点像

    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;
    

    再次是可能有效的最简单的事情。更简单的是gooder。

  4. : - )

    分享并享受。

答案 1 :(得分: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