zoukankan      html  css  js  c++  java
  • PL/SQL的一些问题

    1. Rownum
        PL/SQL User's Guid and Reference中的描述:
        ROWNUM returns a number indicating the order in which a row was selected from a table. The first row selected has a ROWNUM of 1, the second row has a ROWNUM of 2, and so on. If a SELECT statement includes an ORDER BY clause, ROWNUMs are assigned to the retrieved rows before the sort is done; use a subselect to get the first n sorted rows. The value of ROWNUM increases only when a row is retrieved, so the only meaningful uses of ROWNUM in a WHERE clause are:
        ... WHERE ROWNUM < constant;
        ... WHERE ROWNUM <= constant;
        就是说Rownum是在读取记录时赋值,是在Order By操作之前,所以如果要排序,然后取一定位置的记录集,必须使用子查询。WHERE ROWNUM < constant1 AND ROWNUM>constant2;,如果constant2大于1,这个语句永远返回不了任何记录,必须使用子查询解决。

    2. 关于排序的几个问题
    DISTINCT
    Select Distinct A From(
      Select * From ATEST Order By B
    )t2
        上面语句子查询里面的Order By是没有作用的,因为外层查询的Distinct操作将重新排序。

    HASH JOIN
        跟Distinct一样,如果在子查询里面使用了Order By,外层查询有Hash Join出现,则子查询里面的Order By也无效,因为Hash算法会导致返回的结果集重新排序(Distinct操作也应当是使用Hash算法实现的)。Hash算法结果的排序应当依赖于从probe input读取记录的顺序,但算法本身的实现方式也可能造成影响,另外Hash的两个输入可能经过优化器的动态选择,所以结果的排序具有不确定性。

        例如下面的写法:
    Select ...
    From(
        Select t1.*,Rownum As RowIndex
        From (Select * From A Where ... Order By ...)t1
        Where t1.RowIndex>:startIndex And t1.RowIndex<=:endIndex
    )t2
    Left Join B On ...
        出发点是好的:先从A中按照条件和排序规则取出指定页数的记录集,然后再和B关联,降低关联算法的数据运算量。大部分情况下结果会是正确的,因为Oracle将优先采用Nested Loop方式进行关联,这种算法不会影响排序(Merge也不会影响排序),但如果子查询返回的记录集太大、B表上没有用于关联的索引、或索引没有维护等,就可能采用Hash算法,这时返回结果的排序就不一定正确了。

        上面的问题在需要分页的语句中容易发生的。SQL Server对子查询中使用Order By有限制,所以情况好一点,Oracle的PL/SQL没有这方面限制,所以开发的时候很容易被忽视,而发布之后被最终用户发现。

    3. 关键字冲突问题

    相比Oracle,SQL Server对关键字冲突的处理要宽松很多,Oracle则要求严格

    例如Create Table A( Id Number(8), "Level" Number(2));可以创建表,但select id,"Level" from a则会报错"Level"标识符无效

    ORM处理方法参考:

    首先,表名、字段名不能与Oracle关键字冲突,ORM需要处理的,是避免对象名、属性名(考虑对象、属性与表名、字段名不同的情况)、参数名的冲突问题

    NHibernate对查询中的表、字段、参数都重新命名,例如生成的SQL类似如下

    select t_0.OrgCode as t_0_0,t_0.ItemNo as t_0_1
        ,t_1.ItemName 
    as t_1_0,t_1.ItemUOM as t_1_1
    from dbo.TblOrgItem t_0
    inner join dbo.TblItem t_1 on t_0.ItemID=t_1.oid
    where t_0.OrgCode=@p_0 and t_1.ItemName like @p_1

    在NHibernate内部新的名称和原对象的对应关系是清晰的, t_1_0这个字段会设置到dob.TblItem对应对象的相应属性上

    4. 语法细节差异

    4.1 select a.* from TableA as a,这个语句SQL Server正常,而Oracle会报错,因为Oracle指定Table的别名不能使用AS关键字

  • 相关阅读:
    03Qt信号与槽(2)
    01Qt中的隐式共享
    10GNU C语言函数调用
    09GNU C语言程序编译
    第一本C语言笔记(下)
    07控制器和控制卡(3)
    06控制器和控制卡(2)
    集合
    linux指令(目录类操作指令)
    面向对象三大特征
  • 原文地址:https://www.cnblogs.com/RicCC/p/1042147.html
Copyright © 2011-2022 走看看