`

Oracle中两种树表现形式数据互相转换的存储过程

阅读更多

  作者:wallimn(http://wallimn.iteye.com) 时间:2010-10-22
  本人原创,欢迎转载,转载请保留本人信息。

  数据库中表现层次关系(树型结构)有两种方式:一种是使用每级定长的代码,一种是使用父子节点关系。表中的数据如下图所示:



  今天写了一个两种表现形式代码互相转换的存储过程。发布一下,希望对类似需求的朋友有所帮助。
--包头
CREATE OR REPLACE PACKAGE tree
AS
   --两种树层次关系表现形式转换
   --by wallimn, 2010-10-22
   
   --层次码转父子节点表示法
   --p_len:层次码每级的长度
   PROCEDURE code2id (p_len IN NUMBER);

   --由父节点ID、当前节点ID表现的层关系生成单一的层次代码
   --p_startNodeId:树的起点
   --层次码的长度
   PROCEDURE id2code (p_startnodeid IN NUMBER, p_len IN NUMBER);
END tree;
/
--包体
CREATE OR REPLACE PACKAGE BODY tree
AS
/*
--数据处理表,用于存放待处理的数据及处理结果。
create table t_wp_t_tree
(
  nodeid   number,
  nodepid  number,
  code     varchar2(255 byte),
  name     varchar2(255 byte)
);
comment on table t_wp_t_tree is '树两种表示形式转换的临时表';
alter table t_wp_t_tree add (
  unique (code),
  unique (nodeid));
*/
--层次码转父子节点表示法
--p_len:层次码每级的长度
   PROCEDURE code2id (p_len IN NUMBER)
   IS
      TYPE nodeid_table_type IS TABLE OF t_wp_t_tree.nodeid%TYPE
         INDEX BY BINARY_INTEGER;

      TYPE code_table_type IS TABLE OF t_wp_t_tree.code%TYPE
         INDEX BY BINARY_INTEGER;

      nodeid_table   nodeid_table_type;
      code_table     code_table_type;
   BEGIN
      --使用批量操作的方式来处理,效率比较好。
      SELECT ROW_NUMBER () OVER (ORDER BY code) * 10 nodeid, code
      BULK COLLECT INTO nodeid_table, code_table
        FROM t_wp_t_tree;

      --去除可能的干扰
      UPDATE t_wp_t_tree
         SET nodeid = NULL,
             nodepid = NULL;

      --批量更新当前节点的ID
      FORALL i IN 1 .. code_table.COUNT
         UPDATE t_wp_t_tree
            SET nodeid = nodeid_table (i)
          WHERE code = code_table (i);

      --再查找更新父节点的ID
      UPDATE t_wp_t_tree t
         SET nodepid =
                  (SELECT x.nodeid
                     FROM t_wp_t_tree x
                    WHERE x.code = SUBSTR (t.code, 1, LENGTH (t.code) - p_len));
   EXCEPTION
      WHEN OTHERS
      THEN
         RAISE;
   END;

--由父节点ID、当前节点ID表现的层关系生成单一的层次代码
--p_startNodeId:树的起点
--层次码的长度
   PROCEDURE id2code (p_startnodeid IN NUMBER, p_len IN NUMBER)
   IS
      tmpvar         NUMBER;
      v_level        NUMBER;
      v_num          NUMBER;
      v_parentcode   t_wp_t_tree.code%TYPE;
   BEGIN
      v_level := 0;

      FOR rec_item IN (SELECT     nodeid, nodepid, LEVEL
                             FROM t_wp_t_tree
                       START WITH nodeid = p_startnodeid
                       CONNECT BY PRIOR nodeid = nodepid
                         ORDER BY LEVEL, nodeid)
      LOOP
         IF (v_level <> rec_item.LEVEL)
         THEN
            v_num := POWER (10, p_len - 1);
            v_level := rec_item.LEVEL;
         END IF;

         --第一个节点没有父节点。会引发异常
         BEGIN
            SELECT code
              INTO v_parentcode
              FROM t_wp_t_tree t
             WHERE t.nodeid = rec_item.nodepid;
         EXCEPTION
            WHEN NO_DATA_FOUND
            THEN
               v_parentcode := NULL;
            WHEN OTHERS
            THEN
               RAISE;
         END;

         UPDATE t_wp_t_tree
            SET code = v_parentcode || v_num
          WHERE nodeid = rec_item.nodeid;

         v_num := v_num + 1;
      END LOOP;
   END;
END tree;
/
  • 大小: 3.1 KB
分享到:
评论

相关推荐

    Delphi中调用oracle的存储过程返回数据集

    在 Delphi 中调用 Oracle 的存储过程返回数据集有两种方式,一种是使用 Oracle 提供的 OLE DB 提供程序,另一种是使用 Oracle 的 OCI(Oracle Call Interface)提供程序。这里我们主要介绍使用 OLE DB 提供程序的...

    oracle存储过程学习经典入门

    Oracle 存储过程是 Oracle 数据库中的一种程序单元,能够完成复杂的业务逻辑和数据操作。Oracle 存储过程的基础知识包括了解 Oracle 存储过程的基本语法、数据类型、变量声明、控制语句、循环语句、异常处理等方面的...

    oracle 批量插入数据存储过程

    oracle 批量插入数据存储过程。亲测好用。支持 plsql ,toad,等数据库分析软件。主要包括变量的定义,循环及游标的使用等, 亲测好用

    oracle 定时任务,使用存储过程更新数据

    5. **文件名称列表**:`oracle定时任务`和`存储过程`这两个文件名可能是指包含有关如何在实际环境中设置和使用这些功能的文档或脚本。在学习和实践中,可以参考这些文件以获取更具体的步骤和示例。 综上所述,...

    Oracle定时执行存储过程

    存储过程是 oracle 中的一种程序单元,可以执行某些操作。在这里,我们创建一个存储过程,名为 Proc_addTestdate,用于向 testdate 表中插入数据: ```sql create procedure Proc_addTestdate as begin insert ...

    oracle存储过程解锁

    在Oracle数据库中,存储过程是一种预先编译并存储在数据库中的SQL代码块,用于执行复杂的业务逻辑或数据处理任务。然而,在多用户并发访问的环境下,存储过程可能会因为某些操作而被锁定,导致其他进程无法访问或...

    oracle到sqlserver存储过程语法转换

    本文旨在提供一份详细的指南,帮助开发者更好地理解这两种数据库系统在存储过程方面的语法差异,并指导如何进行有效的转换。 #### 一、基本语法差异 **1. 变量声明** - **Oracle**: 变量命名自由度较高,不需要...

    C#中调用oracle存储过程返回数据集

    在C#中调用Oracle存储过程来返回数据集是一个常见的任务,这涉及到ADO.NET库的使用,特别是OracleClient组件。Oracle存储过程是数据库中的预编译SQL代码块,可以接收输入参数,执行复杂的业务逻辑,并返回结果。在C#...

    oracle 事务 回滚 存储过程

    在Oracle数据库环境中,事务管理与存储过程的结合是实现数据一致性、事务回滚以及错误处理的关键技术之一。本文将深入探讨“Oracle事务回滚存储过程”这一主题,旨在理解其核心概念、工作原理以及实际应用。 ### ...

    oracle存储过程unwrap解密工具.zip

    Oracle存储过程unwrap解密工具主要用于处理Oracle数据库中的加密存储过程。在Oracle数据库系统中,为了保护敏感代码或数据,开发人员有时会选择对存储过程进行加密。然而,当需要查看、调试或恢复这些加密的存储过程...

    oracle 存储过程导出excel

    oracle 存储过程导出excel oracle 存储过程导出excel oracle 存储过程导出excel oracle 存储过程导出excel oracle 存储过程导出excel

    oracle通过存储过程POST方式访问接口

    在Oracle数据库中,有时我们需要与外部系统交互,例如发送数据到Web服务或API。"Oracle通过存储过程POST方式访问接口"的主题就是关于如何利用Oracle的存储过程来实现HTTP POST请求,将数据提交到指定的接口。这个...

    oracle 存储过程批量提交

    在Oracle数据库中,存储过程是一种重要的数据库对象,它可以包含一系列SQL语句和控制流语句,用于实现复杂的业务逻辑处理。存储过程不仅可以提高应用程序性能,还可以确保数据的一致性和安全性。批量提交是存储过程...

    VFP调用ORACLE存储过程数据库接口程序.pdf

    掌握如何在VFP中调用Oracle存储过程并实现数据自动转换,对于数据密集型企业的数据处理工作具有重要的实际意义。在企业生产环境当中,这样的数据库接口程序可以大大降低数据转换和处理的复杂度,提高工作效率。

    SQLServer存储过程转为oracle存储过程的工具

    可以将SQL Server存储过程转为oracle存储过程的工具

    pb中执行oracle存储过程脚本

    标题中的“pb中执行oracle存储过程脚本”指的是在PowerBuilder(简称PB)环境中调用Oracle数据库的存储过程。PowerBuilder是一种可视化的开发工具,常用于构建数据驱动的应用程序。Oracle存储过程则是在Oracle数据库...

    Oracle存储过程中使用临时表

    在Oracle数据库中,存储过程是预编译的SQL和PL/SQL代码集合,它们可以用于执行复杂的业务逻辑或数据操作。在某些情况下,特别是在处理大量数据时,使用临时表可以帮助提高性能并简化代码结构。本篇文章将深入探讨...

    C# 传入自定义列表List 到Oracle存储过程

    在.NET开发中,C#与Oracle数据库的交互是常见的任务,特别是当需要处理大量数据时,存储过程可以提供更高的性能和灵活性。本文将详细讲解如何在C#中使用自定义列表(List)作为参数调用Oracle存储过程,以及实现这一...

    oracle存储过程编译

    Oracle 存储过程编译是指在 Oracle 数据库中编译存储过程的过程。存储过程是一种预编译的 SQL 语句集合,用于实现特定的业务逻辑。编译存储过程是将其转换为机器代码,以提高执行速度和效率。 在本例中,我们将讨论...

    oracle存储过程常用技巧

    在 Oracle 存储过程中,游标是一种特殊的数据类型,它可以用来存储查询结果。游标可以用来实现复杂的业务逻辑,并提高数据库的性能。 四、异常处理 在 Oracle 存储过程中,异常处理是非常重要的。异常处理可以帮助...

Global site tag (gtag.js) - Google Analytics