• oracle-sql系统学习-ddl-dml


    e41084-04  oracle database sql language reference 11g release 2

    sql语句类型

    ddl

      alter ...除了alter session和alter system

      analyze

      associate statistics,disassociate statistics

      audit,noaudit

      comment

      create ...

      drop ...

      flashback ...

      grant,revoke

      purge,rename,truncate

    dml

      call

      delete

      explain plan

      insert

      lock table

      merge

      select  

      update

    transaction control statements

      commit,rollback,savepoint,set transaction,set constraint

    session control statements

      alter session,set role

    system control statements

      alter system  动态管理一个oracle 实例的属性

    embedded sql statements

    书中的sql语句描述

    statements,clause,keywords,parameters

    create database语句说明

    create database
    
    /*lcp是数据库的名字,必须匹配初始化参数的db_name参数。最多8个字节长,仅包含ascii字符。
    oracle写这个名字到控制文件中,如果后续提交alter database语句,它显示地规定了一个库名,
    那么数据库校验那个名字与控制文件中的名字
    库名大小写不敏感,被存储为大写的ascii字符。
    如果没有这个库名,那么oracle使用db_name中的名字,db_name必须被设置,
    如果你指定了不同于参数值db_name的名字,数据库返回错误。
    也就是说,要么这里不指定,要么指定与参数一样的名字。*/
    
    	lcp
    	
    /*为两个用户建立密码,不是强制的。但是如果指定一个,就必须指定另外一个,也就是说要么都出现,
    要么都不出现。
    如果不指定,那么oracle创建默认的密码,后续可以通过alter user来更改密码,也可以使用alter user
    在数据库创建之后来添加密码管理属性。*/
    	user sys identified by 123456
    	user system identified by 123456
    /*重用由初始化参数control_files标识的已存在的控制文件,覆盖内容。使用这个子句仅当重创数据库时,
    而不是首次建库时用到。当首次建库时,oracle在默认目的创建一个控制文件,依赖于值或一些初始化参数
    参见create controlfile。
    如果你错过这个子句并且由control_files规定的任意文件已经存在,那么数据库返回一个错误。*/
    	controlfile reuse
    /*规定控制文件的数据文件部分的初始大小,添加一个文件(它的号大于maxdatafiles但小于等于db_files)
    的尝试,引起控制文件自动扩展以便数据文件部分能容纳更多的文件。
    实例可访问的data files的数量也被db_files参数限制。*/
    	maxdatafiles 
    /*规定了数据库同时挂载和打开的最大数量的实例,这个值优先于参数instances,最小值是1,最大值是1055,
    默认依赖于操作系统。*/
    	maxinstances
    /*规定了数据库用来存储数据的字符集。支持的字符集和这个参数的默认值依赖于操作系统。不能指定al16utf16*/
    	character set al32utf8
    /*规定了nchar,nclob,nvarchar2类型的数据,有效值是al16utf16和utf8,默认是al16utf16。*/
    	national character set al16utf16
    /*使用这个子句决定了后续创建表空间和system,sysaux表空间的默认类型。要么bigfile,要么smallfile。
    bigfile tablespace只包含一个数据文件或临时文件...
    smallfile tablespace
    如果没有这个子句,默认创建smallfile tablespace*/
    	set default smallfile tablespace
    
    --database_logging_clauses	决定oracle如何处理redo log files
    /*
    	logfile
    		group 1
    		group 2
    		group 3
    	maxlogfiles 
    	maxlogmembers
    	maxloghistory
    	archivelog
    /*使用这个子句将database放入froce logging 模式。将会记录在数据库中的所有更改,除了在临时表空间和临时
    segment中的更改。这个设置优先并独立于任何nologging或独立表空间的force logging设置和独立数据库对象
    的nologging设置。重启关闭数据库都不影响这个模式,除非重创控制文件。	
    	force logging
    
    --tablespace_clauses	配置system和sysaux表空间,和规定默认临时表空间和undo表空间。
    
    /*这个子句创建一个locally managed system表空间,如果没有这个,system将使用dictionary managed。
    如果你指定了这个子句,那么数据库必须有一个默认的临时表空间,因为locally managed system表空间
    不能存储临时segment。
    还有两条规则。
    	extent management local	
    
    /*
    指定一个或多个文件用于数据文件,所有这些文件成为system表空间的一部分
    这个子句是可选的
    如果你运行数据库在自动undo模式,并且为system表空间指定了一个数据文件名,那么数据库希望为所有的
    表空间生成数据文件。
    oracle自动这样做,如果你使用OMF的话,通过设置db_create_file_dest参数来启用OMF。
    如果没有使用OMF,并且规定了这个子句,那么你必须也指定undo_tablespace和default_temp_tablespace这两个子句。
    如果果没有这个子句
    1并且启用了OMF,那么oracle创建一个100M的OMF文件
    2没有启用OMF,那么oracle创建一个数据文件,它的名字与大小依赖于os。
    */	
    	datafile		文件规范
    
    /*
    oracle创建system和sysaux两个表空间作为每一个数据库的一部分
    如果你没有使用OMF并且想要为sysaux表空间创建一个或多个data files的话,使用这个子句。
    如果你为system 表空间使用datafile子句规定了一个或多个数据文件的话,你必须使用这个子句。
    如果你使用了OMF并且没有这个子句,那么在建立OMF的默认位置创建sysaux数据文件。
    如果你启用了OMF并且没有这个子句,那么数据库创建sysaux表空间为online,permanent,locally managed
    的带有一个100M大小的data file,并且还是logging enabled,automatic segment-space management。
    */	
    	sysaux datafile 文件规范
    
    /*	default_tablespace
    	default_temp_tablespace
    	undo_tablespace	三个表空间子句*/
    	
    /*oracle创建一个smallfile表空间
    datafile子句和extent_management_clause有相同的语义和create tablespace语句。
    如果没有指定这个子句,那么system表空间是默认的永久表空间,为non-system用户。
    */
    	default tablespace aa
    /*如果没有指定临时表空间,并且也没有自动创建temp,那么system成为临时表空间。
    如果通过设置db_creat_file_dest参数已经启用了OMF的话,这个子句的tempfile子句是可选的。
    如果db_create_file_dest没有设置,那么tempfile子句是必须的。
    在一些操作系统上,oracle不为temp file分配空间,直到temp file block被真实访问,这样可以更快的创建。
    */
    	default temporary tablespace bb
    /*如果你打开实例在auto undo mode(undo_management=auto,这是默认,所以可以不用指定)下
    那么你可以指定一个表空间来为undo data使用。oracle强烈推荐使用自动undo mode
    如果你设置了一个undo_tablespace参数值,那么这个子句可以没有
    如果参数值与子句都设置了,那么表空间名必须相同。否则open数据库时会返回一个错误。
    如果通过设置db_creat_file_dest参数已经启用了OMF的话,这个子句的datafile子句是可选的。
    如果db_create_file_dest没有设置,那么datafile子句是必须的。*/
    	undo tablespace cc
    --time zone
    /*使用这个子句设置数据库的时区,你可以以两种方式规定时区
    1规定一个偏移根据utc,有效范围是-12:00 to +14:00
    2规定一个时区,要查看一个有效的时区名列表,查询v$timezone_names的tzname.
    oracle推荐设置0:00,这样可以改进性能,因为没有时间转换发生
    oracle规范化所有 timestamp with local time zone(这是一个datetime数据类型)数据到数据库的时区,当数据被存在磁盘上时。
    如果不规定set time_zone子句,那么数据库使用server上的os time zone。
    如果os time zone不是一个有效的db time zone,那么db time zone默认为utc。*/
    	set time_zone='0:00';

    alter database语句说明

    create schema

    这个语句不实际创建一个schema,当创建用户时自动创建一个schema,这个语句让你用表和视图和关于这些对象的授权来填充你的schema,不用多次事务,而只有一次事务,任意一个语句有错误,将回滚所有语句。

    一次创建多个表和视图及对象。只有一次事务,而不是多次,这是重点

    CREATE SCHEMA AUTHORIZATION oe
    CREATE TABLE new_product
    (color VARCHAR2(10) PRIMARY KEY, quantity NUMBER)
    CREATE VIEW new_product_view
    AS SELECT color, quantity FROM new_product WHERE color = 'RED'
    GRANT select ON new_product_view TO hr;

    create table

    create table aa

      --关系表,要么是关系属性

        (name varchar2(5),age number(3))

      --关系表,要么是as subquery

        as select * from a1;

      --object_type,

        of ...

      --xml_type

        of ...

    指定global temporary来指示表是临时表,它的定义对所有session可见,数据只可被插入表的哪个session可见,其它session不可见

    create table a4 as select * from aa;
    create table a5 (
      col1 varchar2(3) default 2 not null,
      --col2 as (sysdate),
      col3 number(2) unique
    );
    desc a5;
    drop table a5 purge;
    show recyclebin;
    select * from user_recyclebin; purge recyclebin;
    select * from user_constraints;


    在闪回表时,好像自动生成此表
    CREATE GLOBAL TEMPORARY TABLE "TEST"."SYS_TEMP_FBT"
    ( "SCHEMA" VARCHAR2(32 BYTE),
    "OBJECT_NAME" VARCHAR2(32 BYTE),
    "OBJECT#" NUMBER,
    "RID" UROWID (4000),
    "ACTION" CHAR(1 BYTE) )
    ON COMMIT PRESERVE ROWS ;

    insert

    两种方式
    conventional INSERT and direct-path INSERT
    
    传统方式和direct-path
    
    通过以下两种方式可以使用Direct-Path INSERT:
    1    insert /*+APPEND*/ into tab1 select * from tab;
    或者
    insert into tab1 select /*+APPEND*/ from tab;
    2    create table tab1 as select /*+APPEND*/ from tab;

    层级查询

    connect by prior用法
    http://blog.sina.com.cn/s/blog_676015470100ntvw.html

    level,connect_by_leaf,connect_by_iscycle伪列
    prior,connect_by_root操作符

    先是定义父子关系
    select * from employees aa
    connect by prior employee_id= manager_id;

    再加入伪列
    select aa.*,level from employees aa
    connect by prior employee_id= manager_id;


    再加入start with限定根行
    select aa.*,level from employees aa
    start with employee_id=100
    connect by prior employee_id= manager_id;

    再加入order siblings by 子句对子行进行排序,在一个层次查询中,不能指定order by 或group by
    select aa.*,level from employees aa
    start with employee_id=108
    connect by prior employee_id= manager_id
    order siblings by first_name;



    prior在左边,查看下层菜单,自顶向下
    select * from tis_bk_menu_fun
    START WITH MENUFUNC_ID='000102'
    CONNECT BY prior MENUFUNC_ID = PARENT_ID;
    prior在右边,查看上层菜单,自底向上
    select * from tis_bk_menu_fun
    START WITH MENUFUNC_ID='000102'
    CONNECT BY MENUFUNC_ID = prior PARENT_ID;

    level伪列返回是第几层
    select menufunc_id,parent_id,menufunc_name,level from tis_bk_menu_fun
    --START WITH MENUFUNC_ID='000102'
    CONNECT BY prior MENUFUNC_ID = PARENT_ID;

    connect_by_isleaf伪列,是叶子返回1,有子返回0
    select menufunc_id,parent_id,menufunc_name,Connect_By_Isleaf from tis_bk_menu_fun
    --START WITH MENUFUNC_ID='000102'
    CONNECT BY nocycle prior MENUFUNC_ID = PARENT_ID;

    加入sys_connect_by_path函数
    select menufunc_id,parent_id,menufunc_name,Connect_By_Isleaf,
    Sys_Connect_By_Path(menufunc_id, '/')
    from tis_bk_menu_fun
    --START WITH MENUFUNC_ID='000102'
    CONNECT BY nocycle prior MENUFUNC_ID = PARENT_ID;

    序列及序列伪列

    create sequence

    create sequence test
    start with 10
    increment by 2
    nocache
    nocycle;
    select test.nextval from dual;

    select seq_account_user_id.nextval from dual;
    select seq_account_user_id.currval from dual;

    select * from te;
    insert into te values('dd',test.nextval);
    cc    10
    dd    12
    dd    14
    dd    16

    ora_rowscn伪列

    ora_rowscn不应该被认为是一个完全的scn。如果一个事务更改了行R(以块的方式),并提交时scn是10。小于10的永远不会返回,大于等于10可能返回
    如果是以行的方式的话,每一行都有不同的scn

    对于每一行数据,ora_rowscn返回每一行最近被修改的大概时间.这对于判断一行数据大概是在什么时间被修改的还是有用的.因Oracle是通过事务提交对行所在数据块来进行scn的跟踪的所以说它不精确.可以通过在创建表时使用行级别的依赖跟踪来获得一个更加精确的scn.create table ... norowdependencies|rowdependencies
    在对视图进行查询时不能使用ora_rowscn.但对于视图的基表是可以使用ora_rowscn.

    也能在update或delete语句中的where子句中使用ora_rowscn
    ora_rowscn不能用于回闪查询,但是可以用回闪版本查询来代替ora_rowscn
    ora_rowscn也不能用于外部表


    在这介绍两个Oracle 10G开始提供的一个伪列ORA_ROWSCN,它又分为两种模式一种是基于block,这是默认的模式,还有一种是基于row上,这种模式只能在建里表时指定ROWDEPENDENCIES,不可以通过后期的alter table ,同时会给数据库带来性能负载
    每个Block在头部是记录了该block最近事务的SCN的,所以默认情况下,只需要从block头部直接获取这个值就可以了,不需要其他任何的开销,Oracle就能做到这一点。但是这明显第一种模式是scn是不准确的,因为不可能每个事务都能修改整个 块的数据。

    在10g之前,很多系统要实现增量数据抽取,要么通过解析日志,要么加触发器,要么就在表上加一个时间截字段。ORA_ROWSCN其实就是第三种方式,只是这个字段由Oracle来维护,这样可以避免一些应用绕过时间截去更新其他字段带来的问题。


    块级
    insert into te values('dd',test.nextval); select ora_rowscn,scn_to_timestamp(ora_rowscn),id,name from te;


    行级
    create table te1 ROWDEPENDENCIES as select * from te;
    select * from te1;
    insert into te1 values('ee',test.nextval);
    select ora_rowscn,scn_to_timestamp(ora_rowscn),id,name from te1;

    flashback table

    --删除对象系统统一以BIN$unique_id$version的形式命名 
    --can_undrop选项为no的选项为暂时不能恢复,比如索引依赖对应的表要先恢复
    --删除的表已从回收站清除,则不能闪回。
    三种形式 flashback table "BIN$5jXWCqj0Ad/gQAB/AQA2zQ==$0" to before drop; flashback table e2 to before drop; flashback table e2 to before drop rename to test02;

    create restore point aa as of timestamp|scn expr

    默认保留7天

    CONTROL_
    FILE_RECORD_KEEP_TIME initialization parameter.

    create restore point good_data;
    select * from test02;
    update test02 set id=15;
    commit;
    FLASHBACK TABLE test02 TO RESTORE POINT good_data;

    rollback语句

    savepoint语句(与创建恢复点是不一样的) create restore point aa as of timestamp|scn expr;

    保存点概念:
    
    保存点就是为回退做的。
    
    保存点的个数没有限制 ,保存点和虚拟机中快照类似
    保存点是事务中的一点。用于取消部分事务,当结束事务时,会自动的删除该事务中所定义的所有保存点。
    当执行rollback时,通过指定保存点可以回退到指定的点。
    回退事务的几个重要操作
    1.设置保存点 savepoint a
    2.取消保存点a之后事务 rollback to a
    3.取消全部事务 rollback
    注意:这个回退事务,必须是没有commit前使用的;
    如果事务提交了,那么无论你刚才做了多少个保存点,都统统没有。 如果没有手动执行commit,而是exit退出会话了,那么会自动提交 。
    开始实验:创建savepoint还原点
    SQL> set time on
    15:34:12 SQL> create table test(aa varchar(9));
    Table created
    15:44:04 SQL> insert into test values(1);
    1 row inserted
    15:44:36 SQL> savepoint a1;
    Savepoint created
    15:44:39 SQL> select * from test;
    AA
    ---------
    1
    15:45:05 SQL> insert into test values(2);
    1 row inserted
    15:45:10 SQL> savepoint a2;
    Savepoint created
    15:45:16 SQL> select * from test;
    AA
    ---------
    1
    2
    15:45:35 SQL> insert into test values(3);
    1 row inserted
    15:45:39 SQL> savepoint a3;
    Savepoint created
    15:45:44 SQL> select * from test;
    AA
    ---------
    1
    2
    3
    15:45:46 SQL> insert into test values(4);
    1 row inserted
    15:45:56 SQL> savepoint a4;
    Savepoint created
    15:46:00 SQL> select * from test;
    AA
    ---------
    1
    2
    3
    上面设置了4个保存点。
    现在首先从第4个保存点后回退到第三个保存点
    15:47:24 SQL> rollback to a3;
    Rollback complete
    15:47:33 SQL> select * from test;
    AA
    ---------
    1
    2
    3
    
    从第3个保存点回退到第一个保存点,直接跳过了第2个保存点。第二个保存点无效。
    15:47:35 SQL> rollback to a1;
    Rollback complete
    15:47:52 SQL> select * from test;
    AA
    ---------
    1
    15:47:54 SQL> rollback to a2;
    rollback to a2
    
    ORA-01086: savepoint 'A2' never established in this session or is invalid
    
    rollback将所有保存点或未提交事务都回退。
    15:47:59 SQL> rollback;
    Rollback complete
    15:48:06 SQL> select * from test;
    AA
    ---------
    
    15:48:08 SQL> 

    comment

    select * from user_col_comments;
    select * from user_tab_comments;
    comment on table ACCT_SETTLEMENT_CARD_TYPE is '结算卡类型';
    comment on column test_table.col3 is '测试';

    create database link

    The central concept in distributed database systems is a database link.  e25494 31-5

    1
    先查是否有权限创建dblink
    select * from user_sys_privs where privilege like upper('%DATABASE LINK%'); 
    
    2
    无权的话就授权
    grant create public database link,create database link to test;
    在目标机上创建一个用户,有connect role就可以了 3 如果在create之后不加public,则创建的dblink就不是公共的,就只有创建者可以使用了. create public database link test202 connect to test identified by "123456"
       using '(DESCRIPTION =
    (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.3.202)(PORT = 1521))
    )
    (CONNECT_DATA =
    (SERVICE_NAME =kyc)
    )
    )';
    或者
    create public database link lcps
    connect to lcpsys identified by "123456" using 'orcldata';


    4 例如,在本机数据库上创建了一个scott_rmthost的public dblink(使用远程主机的scott用户连接),则用sqlplus连接到本机数据库,执行select * from scott.emp@scott_rmthot即可以将远程数据库上的scott用户下的emp表中的数据获取到. 也可以在本地建一个同义词来指向scott.emp@scott_rmthost,这样取值就方便多了. 5 drop public database link dblinkname; select * from dba_db_links;
    select * from hr.colinfo@lcps;
    using注意事项 没有做成功,因为local和remote的database domain不一样,这个概念有点不清楚
    20170523终于搞清楚了,做成功了。

    ###################################################

    目标如下:a机任意用户都可以访问b机test用户的数据
    总结如下,两步走

    1用a机的sys用户直接创建dblink
    create public database link lcpsys31
    connect to lcpsys identified by "*****"
    using '(DESCRIPTION =
    (ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.30.31)(PORT = 1521)))
    (CONNECT_DATA =(SERVICE_NAME =baoka)))';

    2然后a机任意用户登录,并查询b机lcpsys用户的数据,a机可以没有此用户
    select * from dba_db_links;
    drop public database link lcpsys222;
    select * from lcpsys.tis_ft_user@lcpsys31;


    merge into也是一个dml语句,和其他的dml语句一样需要通过rollback和commit 结束事务。

    MERGE语句是SQL语句的一种。在SQL Server、Oracle数据库中可用,MySQL、PostgreSQL中不可用。MERGE是Oracle9i新增的语法,用来合并UPDATE和INSERT语句。通过MERGE语句,根据一张表(原数据表,source table)或子查询的连接条件对另外一张(目标表,target table)表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE。

    MERGE INTO test T1
    USING (
    SELECT OWNER , OBJECT_NAME , MAX(ID) ID FROM T GROUP BY OWNER, OBJECT_NAME) T
    ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
    WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
    WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);



    语法如下
    MERGE INTO table_name alias1 
    USING (table|view|sub_query) alias2
    ON (join condition) 
    WHEN MATCHED THEN 
        UPDATE table_name 
        SET col1 = col_val1, 
               col2 = col_val2 
    WHEN NOT MATCHED THEN 
        INSERT (column_list) VALUES (column_values); 
    严格意义上讲,”在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记录数,就是Using语句中alias2的记录数”。

    实例如下

    MERGE INTO t2 T6
    USING (SELECT '1001' AS a,'樱桃' AS b,7 as c FROM dual) T5
    ON (T6.month1=T5.c)
    WHEN MATCHED THEN
        UPDATE SET t6.product_name = T5.b
    WHEN NOT MATCHED THEN
        INSERT (t6.product_id,t6.product_name,t6.month1) VALUES(T5.a,T5.b,t5.c);
        
    SELECT '1001' AS a,'樱桃' AS b,4 as c FROM dual;
    select * from t2;

    create synonym

    create public synonym people for kyc_acc.tis_pay_account_card;
    drop public synonym pepole;
    select * from people;
    
    select * from dba_synonyms
    where synonym_name like '%POP%';
    grant create synonym to kyc_acc;
    grant create public synonym to kyc_acc;

    explain plan

    select * from t2;
    explain plan for update t2 set id=11 where name='c';
    select * from plan_table;
    explain plan set statement_id='de' for delete from t2;

    set statement_id语句是为本次执行计划起个名字以区别其它,如果没有这个子句,plan_table的这一列为空


    下面的语句输出类似于sqlplus 中的autotrace的输出格式
    SELECT id, LPAD(' ',2*(LEVEL-1))||operation operation, options,
    object_name, object_alias, position
    FROM plan_table
    START WITH id = 0 AND statement_id = 'de'
    CONNECT BY PRIOR id = parent_id AND statement_id = 'de'
    ORDER BY id;

    select  with as用法

    subquery_factoring_clause

    项目中早些时间,有个oracle查询语句写的极其复杂,因为数据量小的关系,当时也并没有怎么在意,回来随着时间过去,客户数据库数量越来越大,那段语句的劣性就体现的非常明显。优化时,发现查询关系逻辑混乱又复杂(虽然数据查询结果并没有错),多个类似的子查询嵌套,导致查询性能变的很低。
    
      寻求资料知道ORACLE有个WITH as 用法及其好用 
    
         写法大致如下:
    
      WITH  query1 AS
    
    (select ...from ....where ..),
    
    query2  AS
    
    (select...from ...where..),
    
    query3 AS
    
    (select...from ...where..)
    
    SELECT ...FROM query1,quer2,query3 
    
    where ....;
    
      上述代码,每一个逗号(必不可少)代表一段子查询,观察执行计划发现,执行时with as 中的子查询结果会以临时表的形式存在。
    
    这样写每段子查询相应的表仅会被检索一次,不会像原来嵌套的一样反复扫描相同的表,达到了“少读的目的”,大大提高了数据分析以及查询效率.
  • 相关阅读:
    常用sql经典语句
    sql创建 自定义函数返回当前日期所在月的第一天最后一天
    洗洗睡了吧啊,何必在意……费口舌不热么
    asp.net Treeview控件
    MSSQL 触发器
    Mssql 通配符
    C#实现所有经典排序算法
    asp.net Treeview
    Asp.net+json 操作类
    Queue 和Stack 的区别
  • 原文地址:https://www.cnblogs.com/createyuan/p/6723168.html
Copyright © 2020-2023  润新知