`

oracle使用descode和START WITH . . . CONNECT BY

阅读更多

decode (expression, search_1, result_1)
decode (expression, search_1, result_1, search_2, result_2)
decode (expression, search_1, result_1, search_2, result_2, ...., search_n, result_n)

decode (expression, search_1, result_1, default)
decode (expression, search_1, result_1, search_2, result_2, default)
decode (expression, search_1, result_1, search_2, result_2, ...., search_n, result_n, default)


decode函数比较表达式和搜索字,如果匹配,返回结果;如果不匹配,返回default值;如果未定义default值,则返回空值。
以下是一个简单测试,用于说明Decode函数的用法:SQL> create table t as select username,default_tablespace,lock_date from dba_users;

Table created.

SQL> select * from t;

USERNAME                       DEFAULT_TABLESPACE             LOCK_DATE
------------------------------ ------------------------------ ---------
SYS                            SYSTEM
SYSTEM                         SYSTEM
OUTLN                          SYSTEM
CSMIG                          SYSTEM
SCOTT                          SYSTEM
EYGLE                          USERS
DBSNMP                         SYSTEM
WMSYS                          SYSTEM                         20-OCT-04

8 rows selected.


SQL> select username,decode(lock_date,null,'unlocked','locked') status from t;

USERNAME                       STATUS
------------------------------ --------
SYS                            unlocked
SYSTEM                         unlocked
OUTLN                          unlocked
CSMIG                          unlocked
SCOTT                          unlocked
EYGLE                          unlocked
DBSNMP                         unlocked
WMSYS                          locked

8 rows selected.

SQL> select username,decode(lock_date,null,'unlocked') status from t;

USERNAME                       STATUS
------------------------------ --------
SYS                            unlocked
SYSTEM                         unlocked
OUTLN                          unlocked
CSMIG                          unlocked
SCOTT                          unlocked
EYGLE                          unlocked
DBSNMP                         unlocked
WMSYS

8 rows selected.

 

通过START WITH . . . CONNECT BY . . .子句来实现SQL的层次查询.
自从Oracle 9i开始,可以通过 SYS_CONNECT_BY_PATH 函数实现将父节点到当前行内容以“path”或者层次元素列表的形式显示出来。

自从Oracle 10g 中,还有其他更多关于层次查询的新特性 。例如,有的时候用户更关心的是每个层次分支中等级最低的内容。
那么你就可以利用伪列函数CONNECT_BY_ISLEAF来判断当前行是不是叶子。如果是叶子就会在伪列中显示“1”,
如果不是叶子而是一个分支(例如当前内容是其他行的父亲)就显示“0”。

在Oracle 10g 之前的版本中,如果在你的树中出现了环状循环(如一个孩子节点引用一个父亲节点),
Oracle 就会报出一个错误提示:“ ORA-01436: CONNECT BY loop in user data”。如果不删掉对父亲的引用就无法执行查询操作。
而在 Oracle 10g 中,只要指定“NOCYCLE”就可以进行任意的查询操作。与这个关键字相关的还有一个伪列——CONNECT_BY_ISCYCLE,
如果在当前行中引用了某个父亲节点的内容并在树中出现了循环,那么该行的伪列中就会显示“1”,否则就显示“0”。

The start with .. connect by clause can be used to select data that has a hierarchical relationship
(usually some sort of parent->child, boss->employee or thing->parts).
It is also being used when an sql execution plan is explained.

syntax:
select ... [start with initial-condition] connect by [nocycle] recurse-condition

level
With level it is possible to show the level in the hierarchical relation of all the data.

--oracle 9i
sys_connect_by_path
With sys_connect_by_path it is possible to show the entire path from the top level down to the 'actual' child.

--oracle 10g
connect_by_root
connect_by_root is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.  
connect_by_is_leaf
connect_by_isleaf is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.
connect_by_iscycle
connect_by_is_cycle is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.

--start with ... connect by ... 的处理机制
How must a start with ... connect by select statement be read and interpreted?
If Oracle encounters such an SQL statement, it proceeds as described in the following pseude code.

for rec in (select * from some_table) loop
  if FULLFILLS_START_WITH_CONDITION(rec) then
    RECURSE(rec, rec.child);
  end if;
end loop;

procedure RECURSE (rec in MATCHES_SELECT_STMT, new_parent IN field_type) is
  begin
  APPEND_RESULT_LIST(rec);     
  for rec_recurse in (select * from some_table) loop
    if FULLFILLS_CONNECT_BY_CONDITION(rec_recurse.child, new_parent) then
      RECURSE(rec_recurse,rec_recurse.child);
    end if;
  end loop;
end procedure RECURSE;

created by zhouwf0726 2006.

*******************************************************************************/

--创建测试表,增加测试数据

create table test(superid varchar2(20),id varchar2(20));

insert into test values('0','1');
insert into test values('0','2');

insert into test values('1','11');
insert into test values('1','12');

insert into test values('2','21');
insert into test values('2','22');

insert into test values('11','111');
insert into test values('11','112');

insert into test values('12','121');
insert into test values('12','122');

insert into test values('21','211');
insert into test values('21','212');

insert into test values('22','221');
insert into test values('22','222');

commit;

--层次查询示例
select level||'层',lpad(' ',level*5)||id id
from test
start with superid = '0' connect by prior id=superid;

select level||'层',connect_by_isleaf,lpad(' ',level*5)||id id
from test
start with superid = '0' connect by prior id=superid;

--给出两个以前在"数据库字符串分组相加之四"中的例子来理解start with ... connect by ...
--功能:实现按照superid分组,把id用";"连接起来
--实现:以下两个例子都是通过构造2个伪列来实现connect by连接的。

/*------method one------*/
select superid,ltrim(max(sys_connect_by_path(id,';')),';') from(
select superid,id,row_number() over(partition by superid order by superid) id1,
row_number() over(order by superid) + dense_rank() over(order by superid) id2
from test
)
start with id1=1 connect by prior id2 = id2 -1
group by superid order by superid;

/*------method two------*/
select distinct superid,ltrim(first_value(id) over(partition by superid order by l desc),';')
from(
select superid,level l,sys_connect_by_path(id,';') id
from(
select superid,id,superid||rownum parent_rn,superid||to_char(rownum-1) rn
from test
)
connect by prior parent_rn = rn
);

--下面的例子实现把一个整数的各个位上的数字相加,通过这个例子我们再次理解connect by.

create or replace function f_digit_add(innum integer) return number
is
outnum integer;
begin
        if innum<0 then
                return 0;
        end if;
        select sum(nm) into outnum from(
                select substr(innum,rownum,1) nm from dual connect by rownum<length(innum)
        );
        return outnum;
end f_digit_add;
/

select f_digit_add(123456) from dual;

分享到:
评论

相关推荐

    Oracle中connect by...start with...的使用

    本文章详细介绍了Oracle中connect by...start with...的用法。

    树状数据库表:Oracle中start with...connect by prior子句用法

    总结来说,`START WITH...CONNECT BY PRIOR`子句是Oracle SQL处理树形数据的关键工具,通过它可以有效地查询和展示层次关系的数据。理解并熟练运用这个子句,能够帮助你在处理具有层级结构的业务场景时更加游刃有余...

    Oracle start with.connect by prior子句实现递归查询

    ### Oracle Start With.Connect By Prior 子句实现递归查询 #### 概述 在Oracle数据库中,`Start With.Connect By Prior`子句是执行递归查询的一种强大工具,主要用于处理层次结构数据。这类数据通常存在于组织...

    ORACLE查询树型关系(connect_by_prior_start_with)

    Oracle 查询树型关系是指使用 START WITH 和 CONNECT BY 子句来实现 SQL 的层次查询。从 Oracle 9i 开始,可以通过 SYS_CONNECT_BY_PATH 函数实现将父节点到当前行内容以“path”或者层次元素列表的形式显示出来。 ...

    oracle数据库startwith用法

    通过本文,我们详细介绍了Oracle数据库中 `START WITH` 和 `CONNECT BY` 的使用方法以及应用场景。这两个关键字对于处理具有层级结构的数据非常有用。此外,我们还讨论了如何利用 `LEVEL` 关键字来显示节点所在的...

    ODP.NET 方式链接oracle数据库的Oracle.ManagedDataAccess.dll文件取代Oracle.DataAccess.dll

    使用了,ODP.NET 方式链接数据库,只要把...win7 64位ODBC不能使用连接oracle,oracle推出了解决方案,不再划分32位和64位,使用Oracle.ManagedDataAccess.dll连接oracle,可以免安装oracle客户端进行oracle全托管操作

    Oracle递归查询start with connect by prior的用法

    connect by:connect by是必须的,start with有些情况是可以省略的,或者直接start with 1=1不加限制 prior:prior关键字可以放在等号的前面,也可以放在等号的后面,表示的意义是不一样的,比如 prior id = pid,...

    Oracle.ManagedDataAccess.dll.rar

    以上就是关于Oracle.ManagedDataAccess.dll在VS2010和C#环境下使用的基本介绍和示例。开发人员可以根据项目需求选择合适的版本,并结合上述信息进行数据库操作。在实际应用中,还应注意版本兼容性、性能优化以及安全...

    Oracle.ManagedDataAccess 最新版(4.122.21.1)

    oracle.ManagedDataAccess.dll(oracle.ManagedDataAccess.Client)全托管驱动。 此驱动对32位和64位oracle数据库具有很好的连接兼容性。 可采用无客户端远程连接oracle,或在本机使用连接。 使用此驱动可以完全替换...

    oracle.jdbc.driver.oracledriver Oracle JDBC驱动包 ojdbc6

    Oracle JDBC驱动包是Oracle数据库与Java应用程序之间进行通信的关键组件,它使得Java程序员能够通过编写Java代码来...了解和掌握其使用方法和最佳实践,对于提升Java应用与Oracle数据库交互的效率和稳定性至关重要。

    Oracle的Connect By使用示例

    Oracle数据库通过提供`START WITH...CONNECT BY`语句来简化这类查询操作。此功能最早出现在Oracle 8.1.6版本,并一直沿用至今,成为处理递归查询的强大工具之一。 #### 二、Connect By与Start With详解 1. **...

    oracleasm-2.6.18-194.32.1.el5-2.0.5-1.el5.x86_64.rpm

    oracleasm-2.6.18-194.32.1.el5-2.0.5-1.el5.x86_64.rpm

    oracleasm-2.6.18-194.el5xen-2.0.5-1.el5.x86_64.rpm

    oracleasm-2.6.18-194.el5xen-2.0.5-1.el5.x86_64.rpm

    oracleasm oracle rac rpm包

    oracleasm-2.6.18-128.el5-2.0.5-1.el5.i686.rpm oracleasmlib-2.0.4-1.el5.i386.rpm oracleasm-support-2.1.1-1.el4.i386.rpm X64: oracleasm-support-2.1.8-1.el5.x86_64.rpm oracleasmlib-2.0.4-1.el5.x86_64....

    C# winform连接Oracle数据库(直接引用Oracle.ManagedDataAccess.dll使用)

    using Oracle.ManagedDataAccess.Client; public static string ConnectOracle() { try { string connString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=130.147.246.144)(PORT=1521))...

    Oracle_start_with_connect_by_prior_用法[文].pdf

    Oracle 连接查询是指使用 START WITH 和 CONNECT BY 语句来实现递归查询的方法,这种方法可以生成树形结构的数据。在 Oracle 中,START WITH 语句用于指定递归查询的开始记录,而 CONNECT BY 语句用于指定递归查询的...

    oracle.dataaccess.dll

    1. “Oracle.DataAccess.Client.OracleException: ORA-12154: TNS:could not resolve the connect identifier specified”:检查TNS_ADMIN环境变量和tnsnames.ora配置是否正确。 2. “Could not load file or ...

    Oracle.DataAccess.Client_dll

    在C#中使用Oracle.DataAccess.Client.dll,开发者需要首先安装Oracle的数据提供程序,通常通过NuGet包管理器来添加引用。然后,通过`using Oracle.DataAccess.Client;`导入必要的命名空间,就可以在代码中使用这些类...

    基于C#连接Oracle数据库Oracle.ManagedDataAccess

    本篇将详细讲解如何使用C#通过Oracle.ManagedDataAccess库实现与Oracle数据库的连接,无需在本地安装完整的Oracle数据库。 首先,Oracle.ManagedDataAccess是Oracle公司提供的一个纯.NET框架的客户端驱动,它允许...

    cx_Oracle-5.1.3-11g.win-amd64-py2.7.exe

    cx_Oracle-5.1.3-11g.win-amd64-py2.7.exe Python 2.7 lib for Oracle 11g.

Global site tag (gtag.js) - Google Analytics