007 SG SQL注意 05

1.INSERT语句一次插入多行( 包括复杂情况 )

  INSERT [ ALL ] [ conditional_insert_clause ]

  [ insert_into_clause values_clause ] ( subquery )

  conditional_insert_clause

    [ ALL ] [ FIRST ]

    [ WHEN condition THEN ] [ insert_into_clause values_clause ]

    [ ELSE ] [ insert_into_clause values_clause]

  注意 : You can perform multitable inserts only on tables , not on views or materialized views .

             You cannot perform a multitable insert into a remote table .

             You cannot specify a table collection expression when performing a multitable insert .

             In a multitable insert , all of the insert_into_clauses cannot combine to specify more than 999 target columns .

Unconditional insert all

  INSERT ALL                          --> 一次性插入两个表

  INTO sal_history VALUES( EMPID, HIREDATE , SAL )

  INTO mgr_history VALUES ( EMPID , MGR,SAL )

  SELECT employee_id  EMPID , hir_date HIREDATE , SALARY SAL , manager_id MGR

  FROM employees

  WHERE employ_id > 200

Conditional insert all  

  INSERT ALL

  WHEN SAL > 10000 THEN

  INTO sal_history VALUES(EMPID, HIREDATE , SAL )

  WHEN MGR > 200 THEN

  INTO mgr_history VALUES(EMPID, MGR, SAL)

  SELECT employee_id EMPID , hire_date HIREDATE , salary SAL , manager_id MGR

  FROM employees

  WHERE employee_id > 200

Conditional insert first

  INSERT FIRST                   -->满足一个就插入其中的一个TABLE , 不是全部 TABLE都插入

  WHEN SAL > 25000 THEN

  INTO special_sal VALUES( DEPTID , SAL )

  WHEN HIREDATE like ( '%00%' ) THEN

  INTO hiredate_history_00 VALUES( DEPTID , HIREDATE )

  WHEN HIREDATE like ( ' %99%') THEN

  INTO hiredate_history_99 VALUES ( DEPTID , HIREDATE )

  ELSE

  INTO hiredate_history VALUES ( DEPTID , HIREDATE )

  SELECT department_id DEPTID , SUM( salary ) SAL , MAX(hire_date ) HIREDATE

  FROM employees

  GROUP BY department_id

Pivoting insert  ( 旋转 / 列 转变 行 / 透析法 )

  支持从非关系格式中接受数据 , 使用pivoting insert操作,可以构建一个转换,将来自任意输入流的记录(比如非关系数据库)转换成关系数据库表中的多条记录

  旋转insert的不同之处在于所有的into子句都使用同一张表

 table : sales_source_date ( EMP_ID , WEEK_ID , SALES_MON , SALES_TUE , SALES_WED , SALES_THUR, SALES_FRI )   --> 1行

 table : sales_info ( EMP_ID , WEEK_ID , SALES )    --> 5 行

 INSERT ALL

 INTO sales_info VALUES ( emp_id , week_id , sales_mon )

 INTO sales_info VALUES ( emp_id , week_id , sales_tue )

 INTO sales_info VALUES ( emp_id , week_id , sales_wed )

 INTO sales_info VALUES ( emp_id , week_id , sales_thur )

 INTO sales_info VALUES (emp_id , week_id , sales_fri )

 SELECT emp_id , week_id ,sales_mon,sales_tue,sales_wed,sales_thur,sales_fri

 FROM sales_source_date ;

 运行结果 1 行 变 5 行

2.External table

  External tables are read-only tables , 可以是用 sql 查询数据 , 但是不能使用索引和 DML . ( 可以被看作为一个 view )

  You are not in fact creating a table , Rather , you are creating metadata in the data dictionary that you can use to access external data .

  CREATE TABLE oldemp(

    empno NUMBER , empname CHAR( 20 ) , birthdate DATE )

  ORGANIZATION EXTERIAL                       --> 指示这是一个外部表

  ( TYPE ORACLE_LOADER                  --> access_driver_type, 默认的是 ORACLE_LOADER

    DEFAULT DIRECTORY emp_dir           --> 这块用到 dircetory ( 指定 metadata reside , 就是创建table的metadata 寄存在哪里 )

    ACCESS PARAMETERS                       --> 可选的 , 不是必须的

    ( RECORDS DELIMITED BY NEWLINE

    BAD FILE 'bad_emp'

    LOGFILE 'log_emp'

    FIELDS TERMINATED BY ' , '                                            --> fields are all terminated by a ' , ' , 有这个符号分隔字符

    ( empno CHAR ,

       empname CHAR ,

       birthdate CHAR date_format date mask "dd-mon-yyyy"))

       LOCATION ( 'emp1.txt' ))                      --> 文件

      PARALLET 5                                 --> 同时被访问的限制量

      REJECT LIMIT 200 ;                    --> specify how many conversion errors can occur during a query of the external data before an Oracle error is returned

                                                              --> 默认值是 0 .

  假如现在有个文件  ( /flat_files/emp1.txt ) 内部格式为 : ( 10, jones , 11-Dec-1934 )

  CREATE OR REPLACE DIRECTORY emp_dir AS '/flat_files' ;

  When the database server needs to access data in an external source , it calls the appropriate access driver to get the data from an external

  source in a form that database server expects .

  3.Composite Data Types

  PL/SQL RECORDS , PL/SQL COLLECTIONS ( include --> index by table , nested table , varry )

  PL/SQL RECORDS ( 就跟 scalar variable 一样 , 一样在 declare 中定义 )

    跟struct差不多 , 将多个字段 ( fields ) 作为一个处理单元 , 方便从表中取一行数据时, 接收数据 . 可以嵌套使用 .

    A record is a group of related data items stored in fields , each with its own name and data type .

    TYPE type_name IS RECORD

               ( field_declaration  ... ) ;

    identifier type_name ;

    file_declaration

    filed_name { field_type | variable%TYPE | table.column%TYPE | table%ROWTYPE }

                           [ [ NOT NULL ] { := | DEFAULT } expr ]

    例如 :

    DECLARE

    TYPE emp_record_type IS RECORD                           --> 不用非的是一个table中的内容 , 可以多个 table的列的组合

            ( first_name                     VARCHAR2( 25 ) ,

              employee_id                 NUMBER( 5 ) NOT NULL := 100 ,

              last_name                     employees.last_name%TYPE ,

              job_id                             employees.job_id%TYPE  ) ;

           emp_record                     emp_record_type ;

    使用 : emp_record.job_id := ' ST_CLERK '  ;      这样使用

    DECLARE

             emp_record                   employees%ROWTYPE    --> 相当于上面将这个table的所有column都包括进来 

    使用 :  同上 emp_record.job_id

    %ROWTYPE 是动态的 , 就是说底层的 table 或者 view 列的定义变化了 , 那么 %ROWTYPE 也自动变化 .

  PL/SQL COLLECTION

    INDEX BY TABLES : Objects of the TABLE type are called INDEX BY TABLES . They are modeled as ( but not the same as )

    database tables . INDEX BY tables use a primary key to provide you with array-like access to rows .

    Must contain two components

         -  A primary key of data type BINARY_INTEGER that indexes the INDEX BY table

         -  A column of a scalar or record data type , which stores the INDEX BY table elements 

    TYPE type_name IS TABLE OF

        {  column_type | variable%TYPE | table.column%TYPE [ NOT NULL ] } | table.%ROWTYPE

        [ INDEX BY BINARY_INTEGER] ;

    identifier type_name ;

    TYPE ename_table_type IS TABLE OF

                employees.last_name%TYPE

         INDEX BY BINARY_INTEGER ;

    ename_table ename_table_types ;

   

                 结构

Unique identifierColumn
......
1Jones
2Smith
3maduro
......

BINARY_INTEGER               Scalar

INDEX BY tables can have one column and a unique identifier to that one column ,

例如 : DECLARE

                TYPE ename_table_type IS TABLE OF

                      employees.last_name%TYPE

                      INDEX BY BINARY_INTEGER ;

                 ename_table       ename_table_type ;

           BEGIN

                 ename_table(1)       :=  'Cameron' ;

 注意此处的 (1) , 有点类似高级语言的数组 .

 ( INDEX TABLE Methods ( ”数组“所带的方便使用的函数 )

 EXISTS NEXT COUNT TRIM FIRST and LAST DELETE PRIOR         ename_table.method_name

 

MethodDecription
EXISTS(n)Returns TRUE if the nth element in a PL/SQL table exists.
COUNTReturns the number of elements that a PL/SQL table currently contains
FIRST
LAST
Returns the first and last( samllest and lagest )index numbers in a PL/SQL table . Returns NULL if the PL/SQL table is empty .
PRIOR(n)Returns the index number tahta precedes index n in a PL/SQL table
NEXT(n)Returns the index number that succeeds index n in a PL/SQL table
TRIMTRIM removes one element from the end of a PL/SQL table.
TRIM(n) removes n elements from the end of a PL/SQL table
DELETEDELETE removes all elements from a PL/SQL table.
DELETE( n ) removes the nth element from a PL/SQL table.
DELETE(m ,n) removes all elements in the range m ... n from a PL/SQL table .

例子 : ( 类似数组保存 )

 DECLARE

     TYPE emp_table_type is table of

         employees%ROWTYPE INDEX BY BINARY_INTEGER ;

     my_emp_table              emp_table_type ;

     v_count        NUMBER( 3 ) := 104 ;

 BEGIN

    FOR i IN 100 ...v_count

    LOOP

       SELECT * INTO my_emp_table(i) FROM employees                --> 这之所以可以使用 * 的原因是 %ROWTYPE 是动态的 , 当table 发生变化时,

                                                                                                                           %ROWTYPE也自动跟着变化 , 另外注意 i , 是不是有点 a[i] 的感觉...

       WHERE employee_id = i ;

    END LOOP ;

 

 




    

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值