精华内容
下载资源
问答
  • ORACLE 递归删除数据

    千次阅读 2009-12-01 09:52:00
    删除 节点ID为1的存储过程 create or replace procedure sp_advertise_category_del (  v_cate_id in number )  is  begin  delete from advertise_category where category_id in  (select category_id ...

    数据库设计:

    CREATE  TABLE  ADVERTISE_CATEGORY
    (
           CATEGORY_ID       NUMBER PRIMARY KEY,  --节点ID 
           CATEGORY_NAME     VARCHAR2(500),       --节点名字 
           PARENT_ID         NUMBER                          --父节点ID
    )

    表数据

    删除 节点ID为1的存储过程

    create or replace procedure sp_advertise_category_del
    (
           v_cate_id  in number
    )
     is
     begin
           delete from advertise_category where category_id in
            (select category_id from advertise_category  start with category_id=v_cate_id connect by prior category_id = parent_id);
     end;

    展开全文
  • 原标题:简单几招捕获Oracle递归SQL调用源头作者介绍蒋健,云趣网络科技联合创始人,11g OCM,多年Oracle设计、管理及实施经验,精通数据库优化,Oracle CBO及并行原理,曾为多个行业的客户的 Oracle 系统实施小型机...

    原标题:简单几招捕获Oracle递归SQL调用源头

    作者介绍

    蒋健,云趣网络科技联合创始人,11g OCM,多年Oracle设计、管理及实施经验,精通数据库优化,Oracle CBO及并行原理,曾为多个行业的客户的 Oracle 系统实施小型机到 X86跨平台迁移和数据库优化服务。云趣鹰眼监控核心设计和开发者,资深Python Web开发者。

    一、概述

    通常,DBA 确定通过 Oracle 的顶级活动会话图确定 Top SQL,有了 SQL 的执行会话信息和 SQL 文本,可以和开发人员确定 Top SQL 来自哪些应用模块的。有时候,Oracle DBA 需要自己确认 SQL 的来源,本文将演示如何使用 Oracle 提供丰富的跟踪功能,来确认递归 SQL 的调用者来源。

    二、问题描述

    通过顶级会话页面,DBA 发现一个异常的 Top SQL,SQL ID 为c7452agj0s0t6,消耗了9%的数据库时间。

    396acaf8500862bb4a5d7d796b8245c1.png

    通过 SQL 详情页面,可以确定 SQL c7452agj0s0t6 的用户名和模块,但是没有确定 SQL c7452agj0s0t6 是哪个客户机器造成的。

    09fb2f6799bbe637e74e42c6050dc36a.png

    从 SQL 的文本中,这是一个针对系统视图 V$ACTIVE_SESSION_HISTORY 的查询。

    SELECT GROUP_TYPE, BUCKET_START, BUCKET_END, TM_GROUP_TYPE, TM_BUCKET_START,

    TM_BUCKET_END, SUM(TM_CPU_FIRST_BUCKET_VALUE) TM_CPU_FIRST_BUCKET_VALUE,

    SUM(TM_CPU_MIDDLE_BUCKETS_VALUE) TM_CPU_MIDDLE_BUCKETS_VALUE,

    ... 省略大量 SQL 文本

    FROM TABLE(SYS.GV$(CURSOR(

    ... 省略大量 SQL 文本

    SELECT ASH0.*

    FROM V$ACTIVE_SESSION_HISTORY ASH0

    ... 省略大量 SQL 文本

    通过 SQL 的活动会话信息,可以确定执行该 SQL 的进程为后台 PZ 进程,这些会话的 QC(query coordinator)不为空,也就是这是针对视图 V$ACTIVE_SESSION_HISTORY 的并行查询造成的。因为执行时间很短,并且执行此 SQL 的会话为短连接,无法查询到 QC 会话的来源。

    b53318038bea5179ec563fe919ba2e19.png

    三、SQL ID 级别的跟踪分析

    为了确定 SQL c7452agj0s0t6 的来源,我们使用 Oracle 11g 中的新功能,对单个 SQL ID 打开10046事件跟踪,命令如下:

    alter system set events 'sql_trace [sql:c7452agj0s0t6] wait=true,bind=true,plan_stat=all_executions,level=12';

    通过以下查询确定 trace 文件的产生目录:

    select value from v$diag_info where name='Default Trace File';

    对最新生成的 PRDDB_oraxxx.trc 执行 grep c7452agj0s0t6,找到跟踪文件如下,可以确定该的客户端为 testapp。通过 dep=2,知道 SQL c7452agj0s0t6 为深度二级的递归 SQL,并不是用户直接提交的 SQL。我们依然不知道这个递归 SQL 具体由什么 SQL 调用的。

    *** 2016-10-14 09:34:13.921

    *** SESSION ID:(329.41269) 2016-10-14 09:34:13.921

    *** CLIENT ID:() 2016-10-14 09:34:13.921

    *** SERVICE NAME:(PRDDB) 2016-10-14 09:34:13.921

    *** MODULE NAME:(python@testapp (TNS V1-V3)) 2016-10-14 09:34:13.921

    *** ACTION NAME:() 2016-10-14 09:34:13.921

    ... 省略大量文本

    =====================

    PARSING IN CURSOR #139987897061528 len=11079 dep=2 uid=87 oct=3 lid=87 tim=1476408854404253 hv=3792438054 ad='21b01ba960' sqlid='c7452agj0s0t6'

    关闭 SQL ID 跟踪的命令如下:

    alter system set events 'sql_trace [sql:c7452agj0s0t6] off';

    四、会话级别的跟踪分析

    为了确认什么 SQL 调用了 c7452agj0s0t6,我们需要在会话级别打开10046跟踪,因为执行 SQL c7452agj0s0t6 的会话是短连接,我们创建一个针对用户 APPUSER 的 logon 触发器,下次这个用户登录时会启动10046跟踪。

    create or replace trigger sys.set_trace

    after logon on database

    when (user in ('APPUSER'))

    declare

    begin

    execute immediate 'alter session set statistics_level=all';

    execute immediate 'alter session set max_dump_file_size=unlimited';

    execute immediate 'alter session set events ''10046 trace name context forever, level 12''';

    end set_trace;

    /

    接着,在跟踪文件目录中找到最新生成的跟踪文件 PRDDB1_ora_10452.trc 包含 SQL ID c7452agj0s0t6。接着我们使用 orasrp 这个工具分析10046跟踪文件. orasrp 为 Oracle Session Resource Profiler,出自一位俄罗斯 DBA 的强大的10046分析工具,网址为:http://oracledba.ru/orasrp/

    orasrp PRDDB1_ora_10452.trc PRDDB1_ora_10452.html

    orasrp相对于 Oracle 自带的 tkprof,功能更加强大,其中一大优势是会生成会话的递归调用树。递归调用树(Session Call Graph)部分如下图,SQL hash value=3792438054 为 SQL c7452agj0s0t6,深度为2,顶级的 SQL hash value = 2036392974。

    892837070edb8c0e77864c1ce7cef286.png

    顶级 SQL 文本如下,原来 SQL c7452agj0s0t6 是由 dbms_sqltune.report_sql_monitor 这个生成 SQL Monitor 报告的函数递归调用的。确定是前几天新部署的监控 job,在后台定时抓取和保存新生成的 SQL monitor 报告,但是执行过于频繁。解决的方法为降低后台 job 的执行频率,对每次抓取 SQL monitor 的执行时间提高限制。

    select dbms_sqltune.report_sql_monitor(type=>:1, sql_id=>:2, sql_exec_id=>:3, report_level=>'ALL') monitor_report from dual;

    确定问题来源之后,删除 logon 触发器,避免过多的跟踪文件产生:

    drop trigger sys.set_trace;

    五、总结

    本文演示了如果在 Oracle 中分别使用 SQL ID 和会话级别的10046跟踪,以确定递归 SQL 的调用源头来自 PL/SQL 函数 dbms_sqltune.report_sql_monitor。现实工作中,使用类似的方法,可以对 PL/SQL 代码性能,Oracle 解析时间过长等疑难杂症进行分析。对于 DBA 来说,使用 orasrp 对10046跟踪文件生成的递归调用树,也是研究应用负载特征的一个好手段。

    相关专题:

    精选专题(官网:dbaplus.cn)

    ◆近期热文 ◆

    ◆MVP专栏 ◆

    丨丨丨丨

    责任编辑:

    展开全文
  • 总结:Oracle 递归查询

    2020-08-27 11:31:53
    我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。 但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢? 于是,就有了这篇文章。 文章主要知识点: ...

    前言

    最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。

    但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢?

    于是,就有了这篇文章。

    文章主要知识点:

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

    • find_in_set 函数

    • concat,concat_ws,group_concat 函数

    • MySQL 自定义函数

    • 手动实现 MySQL 递归查询

    Oracle 递归查询

    在 Oracle 中是通过 start with connect by prior 语法来实现递归查询的。

    按照 prior 关键字在子节点端还是父节点端,以及是否包含当前查询的节点,共分为四种情况。

    prior 在子节点端(向下递归)

    第一种情况:start with 子节点id = ' 查询节点 ' connect by prior 子节点id = 父节点id

    select * from dept start with id='1001' connet by prior id=pid;
    

    这里,按照条件 id='1001' 对当前节点以及它的子节点递归查询。查询结果包含自己及所有子节点。

    第二种情况:start with 父节点id= ' 查询节点 '  connect by prior 子节点id = 父节点 id

    select * from dept start with pid='1001' connect by prior id=pid;
    

    这里,按照条件 pid='1001' 对当前节点的所有子节点递归查询。查询结果只包含它的所有子节点,不包含自己

    其实想一想也对,因为开始条件是以父节点为根节点,且向下递归,自然不包含当前节点。

    prior 在父节点端(向上递归)

    第三种情况:start with 子节点id= ' 查询节点 ' connect by prior 父节点id = 子节点id

    select * from dept start with id='1001' connect by prior pid=id;
    

    这里按照条件 id='1001' ,对当前节点及其父节点递归查询。查询结果包括自己及其所有父节点。

    第四种情况:start with 父节点id= ' 查询节点 ' connect by prior 父节点id = 子节点id

    select * from dept start with pid='1001' connect by prior pid=id;
    

    这里按照条件 pid='1001',对当前节点的第一代子节点以及它的父节点递归查询。查询结果包括自己的第一代子节点以及所有父节点。(包括自己

    其实这种情况也好理解,因为查询开始条件是以 父节点为根节点,且向上递归,自然需要把当前父节点的第一层子节点包括在内。

    以上四种情况初看可能会让人迷惑,容易记混乱,其实不然。

    我们只需要记住 prior 的位置在子节点端,就向下递归,在父节点端就向上递归。

    • 开始条件若是子节点的话,自然包括它本身的节点。

    • 开始条件若是父节点的话,则向下递归时,自然不包括当前节点。而向上递归,需要包括当前节点及其第一代子节点。

    MySQL 递归查询

    可以看到,Oracle 实现递归查询非常的方便。但是,在 MySQL 中并没有帮我们处理,因此需要我们自己手动实现递归查询。

    为了方便,我们创建一个部门表,并插入几条可以形成递归关系的数据。

    DROP TABLE IF EXISTS `dept`;
    CREATE TABLE `dept`  (
      `id` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
      `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `pid` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
    
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1000', '总公司', NULL);
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1001', '北京分公司', '1000');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1002', '上海分公司', '1000');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1003', '北京研发部', '1001');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1004', '北京财务部', '1001');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1005', '北京市场部', '1001');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1006', '北京研发一部', '1003');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1007', '北京研发二部', '1003');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1008', '北京研发一部一小组', '1006');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1009', '北京研发一部二小组', '1006');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1010', '北京研发二部一小组', '1007');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1011', '北京研发二部二小组', '1007');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1012', '北京市场一部', '1005');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1013', '上海研发部', '1002');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1014', '上海研发一部', '1013');
    INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1015', '上海研发二部', '1013');
    
    

    没错,刚才 Oracle 递归,就是用的这张表。

    图1

    另外,在这之前,我们需要复习一下几个 MYSQL中的函数,后续会用到。

    find_in_set 函数

    函数语法:find_in_set(str,strlist)

    str 代表要查询的字符串 , strlist 是一个以逗号分隔的字符串,如 ('a,b,c')。

    此函数用于查找 str 字符串在字符串 strlist 中的位置,返回结果为 1 ~ n 。若没有找到,则返回0。

    举个栗子:

    select FIND_IN_SET('b','a,b,c,d'); 
    

    结果返回 2 。因为 b 所在位置为第二个子串位置。

    此外,在对表数据进行查询时,它还有一种用法,如下:

    select * from dept where FIND_IN_SET(id,'1000,1001,1002'); 
    

    结果返回所有 id 在 strlist 中的记录,即 id = '1000' ,id = '1001' ,id = '1002' 三条记录。

    看到这,对于我们要解决的递归查询,不知道你有什么启发没。

    以向下递归查询所有子节点为例。我想,是不是可以找到一个包含当前节点和所有子节点的以逗号拼接的字符串 strlist,传进 find_in_set 函数。就可以查询出所有需要的递归数据了。

    那么,现在问题就转化为怎样构造这样的一个字符串 strlist 。

    这就需要用到以下字符串拼接函数了。

    concat,concat_ws,group_concat 函数

    一、字符串拼接函数中,最基本的就是 concat 了。它用于连接N个字符串,如,

    select CONCAT('M','Y','S','Q','L') from dual; 
    

    结果为 'MYSQL' 字符串。

    二、concat 是以逗号为默认的分隔符,而 concat_ws  则可以指定分隔符,第一个参数传入分隔符,如以下划线分隔。

    三、group_concat 函数更强大,可以分组的同时,把字段以特定分隔符拼接成字符串。

    用法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )

    可以看到有可选参数,可以对将要拼接的字段值去重,也可以排序,指定分隔符。若没有指定,默认以逗号分隔。

    对于 dept 表,我们可以把表中的所有 id 以逗号拼接。(这里没有用到 group by 分组字段,则可以认为只有一组)

    MySQL 自定义函数,实现递归查询

    可以发现以上已经把字符串拼接的问题也解决了。那么,问题就变成怎样构造有递归关系的字符串了。

    我们可以自定义一个函数,通过传入根节点id,找到它的所有子节点。

    以向下递归为例。 (讲解自定义函数写法的同时,讲解递归逻辑)

    delimiter $$ 
    drop function if exists get_child_list$$ 
    create function get_child_list(in_id varchar(10)) returns varchar(1000) 
    begin 
     declare ids varchar(1000) default ''; 
     declare tempids varchar(1000); 
     
     set tempids = in_id; 
     while tempids is not null do 
      set ids = CONCAT_WS(',',ids,tempids); 
      select GROUP_CONCAT(id) into tempids from dept where FIND_IN_SET(pid,tempids)>0;  
     end while; 
     return ids; 
    end  
    $$ 
    delimiter ; 
    

     

     

    (1) delimiter $$ ,用于定义结束符。我们知道 MySQL 默认的结束符为分号,表明指令结束并执行。但是在函数体中,有时我们希望遇到分号不结束,因此需要暂时把结束符改为一个随意的其他值。我这里设置为 $$,意思是遇到 $$ 才结束,并执行当前语句。

     

    (2)drop function if exists get_child_list$$ 。若函数 get_child_list 已经存在了,则先删除它。注意这里需要用 当前自定义的结束符 $$ 来结束并执行语句。因为,这里需要数和下边的函体单独区分开来执行。

    (3)create function get_child_list 创建函数。并且参数传入一个根节点的子节点id,需要注意一定要注明参数的类型和长度,如这里是 varchar(10)。returns varchar(1000) 用来定义返回值参数类型。

    (4)begin 和 end 中间包围的就是函数体。用来写具体的逻辑。

    (5)declare 用来声明变量,并且可以用 default 设置默认值。

    这里定义的 ids 即作为整个函数的返回值,是用来拼接成最终我们需要的以逗号分隔的递归串的。

    而 tempids 是为了记录下边 while 循环中临时生成的所有子节点以逗号拼接成的字符串。

    (6) set 用来给变量赋值。此处把传进来的根节点赋值给 tempids 。

    (7) while do ... end while;  循环语句,循环逻辑包含在内。注意,end while 末尾需要加上分号。

    循环体内,先用 CONCAT_WS 函数把最终结果 ids 和 临时生成的 tempids 用逗号拼接起来。

    然后以 FIND_IN_SET(pid,tempids)>0 为条件,遍历在 tempids 中的所有 pid ,寻找以此为父节点的所有子节点 id ,并且通过 GROUP_CONCAT(id) into tempids 把这些子节点 id 都用逗号拼接起来,并覆盖更新 tempids 。

    等下次循环进来时,就会再次拼接 ids ,并再次查找所有子节点的所有子节点。循环往复,一层一层的向下递归遍历子节点。直到判断 tempids 为空,说明所有子节点都已经遍历完了,就结束整个循环。

    这里,用 '1000' 来举例,即是:(参看图1的表数据关系)

    第一次循环:
      tempids=1000 ids=1000 tempids=1001,1002 (1000的所有子节点)
    第二次循环:
      tempids=1001,1002  ids=1000,1001,1002  tempids=1003,1004,1005,1013 (1001和1002的所有子节点)
    第三次循环:
      tempids=1003,1004,1005,1013 
      ids=1000,1001,1002,1003,1004,1005,1013 
      tempids=1003和1004和1005及1013的所有子节点
    ...
    最后一次循环,因找不到子节点,tempids=null,就结束循环。
    

    (8)return ids; 用于把 ids 作为函数返回值返回。

    (9)函数体结束以后,记得用结束符 $$ 来结束整个逻辑,并执行。

    (10)最后别忘了,把结束符重新设置为默认的结束符分号 。

    自定义函数做好之后,我们就可以用它来递归查询我们需要的数据了。如,我查询北京研发部的所有子节点。

    以上是向下递归查询所有子节点的,并且包括了当前节点,也可以修改逻辑为不包含当前节点,我就不演示了。

    手动实现递归查询(向上递归)

    相对于向下递归来说,向上递归比较简单。

    因为向下递归时,每一层递归一个父节点都对应多个子节点。

    而向上递归时,每一层递归一个子节点只对应一个父节点,关系比较单一。

    同样的,我们可以定义一个函数 get_parent_list 来获取根节点的所有父节点。

    delimiter $$ 
    drop function if exists get_parent_list$$ 
    create function get_parent_list(in_id varchar(10)) returns varchar(1000) 
    begin 
     declare ids varchar(1000); 
     declare tempid varchar(10); 
      
     set tempid = in_id; 
     while tempid is not null do 
      set ids = CONCAT_WS(',',ids,tempid); 
      select pid into tempid from dept where id=tempid; 
     end while; 
     return ids; 
    end 
    $$ 
    delimiter ; 
     
    

    查找北京研发二部一小组,以及它的递归父节点,如下:

    注意事项

    我们用到了 group_concat 函数来拼接字符串。但是,需要注意它是有长度限制的,默认为 1024 字节。可以通过 show variables like "group_concat_max_len"; 来查看。

    注意,单位是字节,不是字符。在 MySQL 中,单个字母占1个字节,而我们平时用的 utf-8下,一个汉字占3个字节。

    这个对于递归查询还是非常致命的。因为一般递归的话,关系层级都比较深,很有可能超过最大长度。(尽管一般拼接的都是数字字符串,即单字节)

    所以,我们有两种方法解决这个问题:

    1. 修改 MySQL 配置文件 my.cnf ,增加 group_concat_max_len = 102400 #你要的最大长度 。

    2. 执行以下任意一个语句。SET GLOBAL group_concat_max_len=102400; 或者 SET SESSION group_concat_max_len=102400;

      他们的区别在于,global是全局的,任意打开一个新的会话都会生效,但是注意,已经打开的当前会话并不会生效。而 session 是只会在当前会话生效,其他会话不生效。

      共同点是,它们都会在 MySQL 重启之后失效,以配置文件中的配置为准。所以,建议直接修改配置文件。102400 的长度一般也够用了。假设一个id的长度为10个字节,也能拼上一万个id了。

    除此之外,使用 group_concat 函数还有一个限制,就是不能同时使用 limit 。如,

    本来只想查5条数据来拼接,现在不生效了。

    不过,如果需要的话,可以通过子查询来实现,

    展开全文
  • 数据库中常要处理父子关系的记录,在oracle中可以用查询语句一次把所有的子记录全部取出来。例如下: t1  t11  t111  t1111  t12  t121  t1211   db数据字段如下: task_id task_name parent_...

    数据库中常要处理父子关系的记录,在oracle中可以用查询语句一次把所有的子记录全部取出来。例如下:
    t1
     t11
         t111
            t1111
     t12
         t121
            t1211
     
    db数据字段如下:
    task_id           task_name         parent_task_id
    000001            t1                      ***             
    000002            t11                    000001
    000005            t12                    000001
    000003            t111                   000002
    000004            t1111                  000003
    000006            t121                   000005
    000007            t1211                  000006

    查询语句:
    select t.task_id ,t.task_name ,t.parent_task_id
    from t_task t
    start with task_id='000001'
    connect by prior task_id = parent_task_id;
    结果显示:
    task_id               task_name          t.parent_task_id
    000001                t1          
    000002                t11                     000001
    000003                t111                    000002
    000004                t1111                   000003
    000005                t12                     000001
    000006                t121                    000005
    000007                t1211                   000006

    strat with 指定层次开始的条件,即是说满足这个条件的行即可以做为层次树的最顶层
     
    connect by prior指层之间的关联条件,即什么样的行是上层行的子行(自连接条件)
     
    select level,id,name,parentid from temptable2
      connect by prior id(子层的列)=parentid(属于顶层的列)  start with id =1

    修改父子关系记录:

     update t_task  t set t.task_name = "haha" where t.task_id in (
                     select tt.task_id from t_task tt start with tt.task_id = '000001' connect by prior tt.task_id = tt.parent_task_id
              )


    删除父子关系记录:

    delete from t_task where task_id in (select task_id from t_task connect by prior task_id=parentid start with task_id='000001');

    展开全文
  • oracle 递归 level

    千次阅读 2011-06-08 09:15:00
    删除指定的节点 select   level ,lpad( '   ' , 2 * level - 1 ) || part_cname || '   ' || part_ename   as   partName   from   automobiles where   part_cname     ' 底盘 ' start   with   part_...
  • 索引生效oracle递归

    2019-08-30 18:23:16
    explainselectsurname,first_nameforma,bwherea.id=b.id table:显示这一行的数据是关于哪张表的 type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和...
  • SQL递归查询(SqlServer/ORACLE递归查询)[语法差异分析]在 SQLSERVER2005以后,mssql开始有了递归查询的方法了。比较起最开始写存储过程或者写function的方式。这样的方式更加简便灵活的。而oracle也有自带的树形...
  • oracle 递归层次查询

    千次阅读 2016-08-18 17:02:58
    在9i中只能将发生死循环的不加入到树中或删除,在10g中可以用nocycle关键字加在connect by之后,避免循环的参加查询操作。并且通过connect_by_iscycle得到哪个节点发生循环。0表示未发生循环,1表示发生了循环。 ...
  • 摘要: 作者介绍 蒋健,云趣网络科技联合创始人,11g OCM,多年Oracle设计、管理及实施经验,精通数据库优化,Oracle CBO及并行原理,曾为多个行业的客户的 Oracle 系统实施小型机到 X86跨平台迁移和数据库优化服务...
  • sql oracle 递归查询(转)

    千次阅读 2012-05-22 17:08:49
    ☆ 获取数据库所有表名,表的所有列名  select name from sysobjects where xtype='u'  select name from syscolumns where id=(select max(id) from sysobjects where xtype='u' and name='表名...☆ 递归查询数据
  • oracle递归、合并、遍历查询实例

    千次阅读 2016-11-10 09:51:32
    递归删除:  delete from APP_PKG_CLASSIFY t1 where id in  ( select id from APP_PKG_CLASSIFY t start with t.ID = #{id,jdbcType=DECIMAL} connect by prior t.ID = t.PARENT_ID)   ...
  • 之前写过oracle和mysql的递归查询和删除,这次再补上一个mysql的递归实现。 1、实现原理 (1)删除临时表 (2)创建临时表并清空 (3)利用临时表用来存放递归遍历出来的id列表 (4)从临时表中查询id列表 2、...
  • 遇到问题: 表空间无法删除。 用户也无法删除,提示: SQL> drop user user_test ...ORA-00604: 递归 SQL 级别 1 出现错误 ORA-00942: 表或视图不存在 ORA-06512: 在 line 7 通过select user
  • oracle常用知识总结
  • 关于:删除树的父节点及父节点,很多人想要获取父节点下的子节点然后传到后台再处理,其实没有这么麻烦 1.我没只需要获取这个节点的ID就可以了,然后传到后台 --适用oracle delete from rightTree where id in( ...
  • sqlserver实现oracle递归函数的例子(start with.....connect by prior.....)通过将查询遍历到的数据插入临时表方式实现此函数应该在考虑下这个临时表的删除文件 以及创建时再判断表结构是否已经存在,相信这个应该很...
  • 建立存储过程p_create_emp,用于判断表employee是否存在,若是存在则删除该表。 createorreplaceprocedurep_create_emp is v_countnumber; begin selectcount(*)intov_countfromuser_tableswheretable_name='...
  • sqlserver实现oracle递归函数的例子(start with.....connect by prior.....) 通过将查询遍历到的数据插入临时表方式实现 此函数应该在考虑下这个临时表的删除文件 以及创建时再判断表结构是否已经存在,相信这个...
  • Oracle Sql递归Tree查询

    2010-12-23 18:29:21
    在数据库中删除树结构的表... oracle提供了专门的语句支持这种树的递归查询。 select t.id from datadict t start with t.id=1 CONNECT by PRIOR t.id=t.fid   将获取所有从该节点开始的以及其节点的id,根据id...
  • Oracle树形表和递归查询

    万次阅读 多人点赞 2017-07-22 20:04:54
    关于Oracle 递归查询和树形表详细的实验和讲解。
  • MySql和Oracle递归查询

    千次阅读 2018-07-17 17:13:15
    当数据库中的表格属于自关联表的时候,当根据parent_id去查询他所有的子集的时候(并且不知道树结构都多少层),就需要递归查询了.         ...
  • 本章为大家详细的整理了,在linux系统中批量删除文件和空文件删除的命令,请大家“对症下药”linux下面删除文件或者目录命令rm(remove)功能说明:删除文件或目录。语 法:rm [-dfirv][--help][--version][文件或...
  • 写代码时碰到要弄清楚Oracle的role之间的传递关系,就是有role A的话,可以通过grant A to B,把A赋予给B,又通过grant B to C .那我想知道所有role中,有哪些role具有A的权限.上网一查发现有个递归查询,不过都...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,749
精华内容 6,699
关键字:

oracle递归删除