Oracle_071_lesson_p19

Manipulating Data 數據操作

you should be able to:
1、Specify explicit default values in the INSERT and UPDATE statements
2、Describe the features of multitable INSERTs
3、Use the following types of multitable INSERTs:
4、Unconditional INSERT
5、Conditional INSERT ALL
6、Conditional INSERT FIRST
7、Pivoting INSERT
8、Merge rows in a table
9、Perform flashback operations
10、Track the changes made to data over a period of time

default 值
1、default with insert:
INSERT INTO deptm3
(department_id, department_name, manager_id)
VALUES (300, 'Engineering', DEFAULT);

2、default with update
UPDATE deptm3
SET manager_id = DEFAULT WHERE department_id = 10;

multitable insert statements 多表insert語句
INSERT…SELECT...

INSERT ALL
INTO target_a VALUES(…,…,…)
INTO target_b VALUES(…,…,…)
INTO target_c VALUES(…,…,…)
SELECT …
FROM sourcetab
WHERE …;

Unconditional INSERT ALL 無條件全插入
例:
create table sal_history as
select employee_id,hire_date,salary
from emp
where 1=0;

create table mgr_history as
select employee_id,manager_id,hire_date
from emp
where 1=0;

INSERT ALL
INTO sal_history VALUES(EMPID,HIREDATE,SAL)
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 ALL 有條件全插入 (會逐條匹配)
例:
INSERT ALL
WHEN HIREDATE < '01-JAN-05' THEN
INTO emp_history VALUES(EMPID,HIREDATE,SAL)
WHEN COMM IS NOT NULL THEN
INTO emp_sales VALUES(EMPID,COMM,SAL)
SELECT employee_id EMPID, hire_date HIREDATE,
salary SAL, commission_pct COMM
FROM employees;

Conditional INSERT FIRST 有條件INSERT FIRST (當找到滿足條件則不再向下匹配)
例:
INSERT FIRST
WHEN salary < 5000 THEN
INTO sal_low VALUES (employee_id, last_name, salary)
WHEN salary between 5000 and 10000 THEN
INTO sal_mid VALUES (employee_id, last_name, salary)
ELSE
INTO sal_high VALUES (employee_id, last_name, salary)
SELECT employee_id, last_name, salary
FROM employees;

Pivoting INSERT 旋轉插入(行列轉換)
INSERT ALL
INTO sales_info VALUES (employee_id,week_id,sales_MON)
INTO sales_info VALUES (employee_id,week_id,sales_TUE)
INTO sales_info VALUES (employee_id,week_id,sales_WED)
INTO sales_info VALUES (employee_id,week_id,sales_THUR)
INTO sales_info VALUES (employee_id,week_id, sales_FRI)
SELECT EMPLOYEE_ID, week_id, sales_MON, sales_TUE, sales_WED, sales_THUR,sales_FRI
FROM sales_source_data;

Merging rows in a table 可新表數據更新到舊錶
MERGE INTO table_name table_alias
USING (table|view|sub_query) alias
ON (join condition)
WHEN MATCHED THEN
UPDATE SET
col1 = col1_val,
col2 = col2_val
WHEN NOT MATCHED THEN
INSERT (column_list)
VALUES (column_values);

MERGE INTO copy_emp3 c
USING (SELECT * FROM EMPLOYEES ) e
ON (c.employee_id = e.employee_id)
WHEN MATCHED THEN
UPDATE SET
c.first_name = e.first_name,
c.last_name = e.last_name,
...

DELETE WHERE (E.COMMISSION_PCT IS NOT NULL)
WHEN NOT MATCHED THEN
INSERT VALUES(e.employee_id, e.first_name, e.last_name,
e.email, e.phone_number, e.hire_date, e.job_id,
e.salary, e.commission_pct, e.manager_id,
e.department_id);

TRUNCATE TABLE copy_emp3;
SELECT * FROM copy_emp3;
no rows selected

MERGE INTO copy_emp3 c
USING (SELECT * FROM EMPLOYEES ) e
ON (c.employee_id = e.employee_id)
WHEN MATCHED THEN
UPDATE SET
c.first_name = e.first_name,
c.last_name = e.last_name,
...

DELETE WHERE (E.COMMISSION_PCT IS NOT NULL)
WHEN NOT MATCHED THEN
INSERT VALUES(e.employee_id, e.first_name, ...

SELECT * FROM copy_emp3;
107 rows selected.

MERGE語法詳解
merge語法是根據源表對目標表進行匹配查詢,匹配成功時更新,不成功時插入。

其基本語法規則是

merge into 目標表 a

using 源表 b

on(a.條件字段1=b.條件字段1 and a.條件字段2=b.條件字段2 ……)

when matched then update set a.更新字段=b.字段

when not macthed then insert into a(字段1,字段2……)values(值1,值2……)

變種寫法①,只更新:

merge into 目標表 a

using 源表 b

on(a.條件字段1=b.條件字段1 and a.條件字段2=b.條件字段2 ……)

when matched then update set a.更新字段=b.字段,a.更新字段2=b.字段2……

變種寫法②,只插入:

merge into 目標表 a

using 源表 b

on(a.條件字段1=b.條件字段1 and a.條件字段2=b.條件字段2 ……)

when not macthed then insert into a(字段1,字段2……)values(值1,值2……)

注:條件字段不可更新

對於Oracle來說,merge是9i新增的語法,在10g進行了一些增強,如下:

測試環境:Oracle Database 11g Enterprise Edition Release 11.2.0.1.0

①條件操作:

merge into 目標表 a

using 源表 b

on(a.條件字段1=b.條件字段1 and a.條件字段2=b.條件字段2 ……)

when matched then update set a.更新字段=b.字段 where 限制條件

when not macthed then insert into a(字段1,字段2……)values(值1,值2……) where 限制條件

舉例:

merge into test_merge a
using test b
on(a.no=b.no)
when matched then update set a.no2=b.no2 where a.no<>1
when not matched then insert values(b.no,b.no2) where a.no<>100

當然也支持變種①②的寫法

②刪除操作

merge into 目標表 a

using 源表 b

on(a.條件字段1=b.條件字段1 and a.條件字段2=b.條件字段2 ……)

when matched then update set a.更新字段=b.字段

delete where b.字段=xxx

舉例:

merge into test_merge a
using test b
on(a.no=b.no)
when matched then update set a.no2=b.no2 where a.no<>1
delete
where b.no=14

備註:刪除動作針對的也是目標表,並且必須在語句最後

基本上merge的用法就是以上這些,建議平常可以多用,比單獨的update+insert的方式效率要更高,尤其是on條件下有唯一索引的時候,效率更高

flashback table 閃回表
system change number (SCN)
FLASHBACK TABLE [ schema. ] table [, [ schema. ] table ]... TO { { { SCN | TIMESTAMP } expr | RESTORE POINT restore_point } [ { ENABLE | DISABLE } TRIGGERS ] | BEFORE DROP [ RENAME TO table ] } ;
例:
DROP TABLE emp3;
SELECT original_name, operation, droptime FROM recyclebin;
FLASHBACK TABLE emp3 TO BEFORE DROP;

select current_timestamp from dual; 查詢當前時間戳
flashback table emp to timestamp ( current_timestamp - interval '5' minute);當前時間減5分鐘.

閃回查詢:
例:
SELECT salary FROM employees3
WHERE last_name = 'Chung';

UPDATE employees3 SET salary = 4000
WHERE last_name = 'Chung';

SELECT salary FROM employees3
WHERE last_name = 'Chung';

SELECT salary FROM employees3
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' MINUTE)
WHERE last_name = 'Chung';

閃回版本查詢:commit 後纔會記錄版本信息
select * from emp as of timestamp ( current_timestamp - interval '5' minute);
select version_starttime, version_endtime, salary
from emp versions between scn minvalue and maxvalue where emp_id=100;

例:
SELECT salary FROM employees3
WHERE employee_id = 107;

UPDATE employees3 SET salary = salary * 1.30
WHERE employee_id = 107;

COMMIT;

SELECT salary FROM employees3
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE employee_id = 107;

例:
SELECT versions_starttime "START_DATE", versions_endtime "END_DATE",
salary FROM employees VERSIONS BETWEEN SCN MINVALUE
AND MAXVALUE WHERE last_name = 'Lorentz';

SELECT salary FROM employees3
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE employee_id = 107;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章