oracle语句的级联问题,这个语句e.mgr=m.empno(+) 谁可以给我讲讲这个是啥意思还带有(+)详细解答哦!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle语句的级联问题,这个语句e.mgr=m.empno(+) 谁可以给我讲讲这个是啥意思还带有(+)详细解答哦!相关的知识,希望对你有一定的参考价值。

还有oracle数据库中的scott用户 emp、dept、还有两张表。表名称的中文名字是什么?

(+)是外连接,表示当前条件等号左侧的表为主表,如果等号条件成立,查询中如果有等号右侧表中的字段,按照关联条件查询出数据,如果右侧没有条件符合,那么查询中补空。
举个例子,假设emp和dept表数据如下:
emp: emp_id, emp_name, dept_id
001 张三 10
002 李四 10
003 王五 20
004 赵六 30
dept: dept_id dept_name
10 部门1
20 部门2

查询语句:select emp_id, emp_name, dept_name
from emp, dept
where emp.dept_id = dept.dept_id(+);
从上面两表能看出来,emp表中的最后一行数据,dept_id为30,在dept表没有对应的数据,使用直连(即不带加号)只能查询到前三行数据,可是使用外连,以emp为主表,那么emp表的数据就都可以查到。结果如下:
emp_id emp_name dept_name
001 张三 部门1
002 李四 部门1
003 王五 部门2
004 赵六 NULL(空,没有数据)
参考技术A 一楼完全误导啊。。(+)真是外连接的意思,你这么写就相当于是左外连接,也就是e.mgr这个表的内容将全部被查询
第二个问题这写表是数据库的实例表,没有中文名,emp代表employer也就是雇员表,而dept代表的department也就是部门表
参考技术B 这个(+)代表内连接的意思,举个例子 MGR字段对应的EMPNO字段如果没有数的话也显示结果。
例子:不使用(+)结果是:
mgr empno
cleck 7759
jobs 8792
cleck 8100
这样对显示2个字段都有值才显示。
如果加(+)
mgr empno
cleck 7759
jobs 8792
cleck 8100
linkes
-----linkes 对应的没有值但是也显示,+在那边那边就有无值.
参考技术C (+)是oracle的语法,相当于SQL99标准当中的LETF JOIN,RIGHT JOIN ,如果(+)出现在左连表示RIGHT JOIN ,出现在右连表示LEFT JOIN 。这种写法只限于oracle数据,如果迁移到其它数据库无法运行.
scott用户中有什么表建议用scott用户登录到数据库后执行以下语句:
SELECT object_name FROM user_objects WHERE object_type='TABLE'
参考技术D 左连接。 employee department

Oracle级联删除

【中文标题】Oracle级联删除【英文标题】:Oracle cascade delete 【发布时间】:2011-12-20 06:43:58 【问题描述】:

表上的级联删除是否比单个删除语句(在单个 plsql 块中执行)更有效?

【问题讨论】:

【参考方案1】:

cascade delete 所做的是发出单独的删除语句。

检查以下测试用例:

create table parent 
 (parent_id number, 
  parent_name varchar2(30), 
  constraint parent_pk primary key (parent_id) using index);

create table child 
 (child_id   number,
  parent_id  number,
  child_name varchar2(30),
  constraint child_pk primary key (parent_id, child_id) using index,
  constraint child_fk01 foreign key (parent_id) 
    references parent (parent_id) 
      on delete cascade;
 );


insert into parent
 (parent_id, parent_name)
select object_id, object_name from dba_objects where rownum <= 10000;

begin
  for i in 1..10
  loop
    insert into child
      (child_id, parent_id, child_name)
    select i, parent_id, parent_name
      from parent;
  end loop;
end;
/

exec dbms_stats.gather_table_stats (tabname => 'PARENT', cascade => true);
exec dbms_stats.gather_table_stats (tabname => 'CHILD', cascade => true);

exec dbms_monitor.session_trace_enable;
alter table child drop constraint child_fk01;
alter table child add constraint child_fk01 foreign key (parent_id)
  references parent (parent_id) on delete cascade enable novalidate ;
delete from parent;
rollback;

在跟踪文件中,你会发现这样一行:

  delete from "<MY_SCHEMA_NAME>"."CHILD" where "PARENT_ID" = :1
END OF STMT
PARSE #6:c=0,e=182,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=1293353992514766
EXEC #6:c=0,e=545,p=0,cr=2,cu=32,mis=1,r=10,dep=1,og=4,tim=1293353992515354
EXEC #6:c=0,e=233,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992515644
EXEC #6:c=0,e=238,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992515931
EXEC #6:c=0,e=252,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992516229
EXEC #6:c=0,e=231,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992516507
EXEC #6:c=0,e=227,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992516782
EXEC #6:c=0,e=244,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992517072
EXEC #6:c=0,e=219,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517337
EXEC #6:c=0,e=236,p=0,cr=3,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517622
EXEC #6:c=0,e=235,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517921
EXEC #6:c=0,e=229,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992518196
EXEC #6:c=0,e=246,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992518487
EXEC #6:c=0,e=234,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992518767
EXEC #6:c=6999,e=570,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992519383

那是 Oracle 针对 CHILD 为它在 PARENT 中删除的每条记录发出删除语句。

一个不同的问题是两者中哪一个更有效:

DELETE FROM CHILD WHERE PARENT_ID = 1;
DELETE FROM PARENT WHERE PARENT_ID = 1;

DELETE FROM PARENT WHERE PARENT_ID = 1;

两者都启用了on delete cascade。令人惊讶的是,在上述第一种情况下,Oracle 将探测子表上的外键索引,以查看是否存在需要级联的行。如果不存在行,Oracle 不会执行级联删除。

【讨论】:

那么答案在哪里?什么更有效。 @magulla:与 Oracle 中的大多数东西一样,这取决于。在删除之前手动删除许多子行可能更有效,但没有什么能阻止另一个会话在此过程中插入更多子行。考虑到如果存在子表,Oracle 会为删除的每个父行发出删除操作,如果性能至关重要,那么您最好用一条语句删除子表感兴趣的行将是一个经验法则,但不能保证“更好”的性能.【参考方案2】:

你不能像这样比较这两个选项。这不是性能问题,而是更多的设计和结构问题。

如果您使用主键/外键设计数据库,则使用级联删除比手动搜索在哪个列和表上有外键并生成匹配的 SQL 语句更容易。

cascading-deletes 功能的主要优点是它允许您减少执行删除操作所需的 SQL 语句数量

【讨论】:

【参考方案3】:

如果你想级联删除并且没有定义外键,你可以使用这样的东西:

DELETE FROM my_table
 WHERE ROWID IN
     ( SELECT ROWID
         FROM my_table
        START WITH (condition_on_the_row_that_you_want_to_delete)
      CONNECT BY PRIOR (primary_key) = (self_foreign_key)
     )

【讨论】:

这种解决方案的缺点是,运行删除的会话没有看到的任何插入的行仍将被插入 - 并且是孤立的,因为您已经杀死了父行,但子行仍然被插入。 @AdamMusch 你提到的场景有解决方案吗?

以上是关于oracle语句的级联问题,这个语句e.mgr=m.empno(+) 谁可以给我讲讲这个是啥意思还带有(+)详细解答哦!的主要内容,如果未能解决你的问题,请参考以下文章

sql 级联删除问题

oracle 4: 视图

对于 N:M 关系,在 MongoDB 中推荐的级联删除等效项是啥?

hibernate 级联删除

ORACLE数据库的级联查询

ORACLE数据库的级联查询