1. 程式人生 > >oracle學習筆記(基礎版)

oracle學習筆記(基礎版)

一、 Oracle支援表示式 包括:+ - * /   
 dual(虛表,用於簡單的輸出實驗用)
1.SELECT 5+3,5-3,5*3,5/2  FROM dual;


2.SELECT 'hello,world',100 FROM dual; 


3.查員工編號,姓名,工資,新工資(=原始工資上浮25%)  (列值可以直接加減運算,產生的是臨時結果)
    SELECT employee_id,last_name,salary,salary*1.25
    FROM    employees; 


 4.查員工編號,姓名,工資,12月總工資(=原始工資+100)*12  
    SELECT employee_id,last_name,salary,(salary+100)*12
    FROM    employees; 


Oracle資料庫中,空值是無效的,未指定的,未知的或不可預知的值
空值不是空格或者0
在Oracle中,null和空字串是等價的 
包含空值的數學表示式的值都為空值
5.SELECT 5+NULL FROM dual;查詢結果為空 


6.列的別名(用於衍生列) 有兩種方式 一種是 AS; 一種是加空格
    如果別名要是非法識別符號,可以使用雙引號


7.拼接字串 ( || )
    SELECT 'hello' || 'world' FROM dual;                                 helloworld
    SELECT 'hello' || 123 FROM dual;                                      hello123
    SELECT 123  ||  123 FROM dual;                                        123123
    SELECT '200' + '100' FROM dual;                                       300 
    SELECT first_name || '·' ||  last_name  as ename
    FROM employees;    查詢得到1列 格式為 姓·名;


8.多個重複行併成一行
    SELECT DISTINCT department_id FROM employees;


9.通過dual生成訂單編號(getorderno('') 引號中為訂單型別 可以為空 但必須加引號)
select getorderno('apple') from dual 
    
二、Oracle常用資料型別


 1.字元型:varchar2(n):變長字串,n代表允許的最大位元組長度,最大4000位元組
                   char(n):同上,定長字串,最大2000位元組,長度不夠會填充半形空格,
                                查詢效率高 用於(手機號、身份證號等確定長度的)
                clob:大字串資料,最大4G,預設資料在4000位元組內,儲存在表段空間中,超過4000位元組會用LOB段儲存,查詢效率低
2.數字型別:number:儲存整型或浮點型,最大38位精度
                    number(n):僅存整數,n代表最大位數 number(4) 取值範圍: -9999~9999
                    number(p,s):存浮點型別,P代表最大精度(小數位精度和整數精度和的精度),s代表小數位
3.日期:date:儲存年月日時分秒,精確到秒
                timestamp(n) 時間戳,精確到納秒 很少用
4.blob :大二進位制資料,最大4G 可以存圖片、視訊、音樂等等              
 
 
 三,Oracle過濾語句 where

1.加了where,資料查詢出來就做了比較,所以比不帶where的效率要低


2.查詢工資超過10000的員工
SELECT * FROM  employees WHERE salary >= 90    


3.操作符 

>
>=
<
<=
<> 不等於 (其實!=也可以用)如果值為空值也查不出來


 4. 如果需要查詢無條件為真 可以用
SELECT * FROM employees WHERE 1==1;
   無條件為假 
SELECT * FROM employees WHERE 1==0;


5.查詢員工編號,姓名,工資,新工資(只看新工資超過10000的員工)
SELECT employee_id,last_name,salary,salary*1.25 AS new_sal
WHERE salary*1.25 >=10000;
值得注意的是WHERE後面不能用別名 


6.日期型別比較,日期格式敏感,預設的日期格式是DD-MON-RR,沒有常量。
   查詢所有在90年以前入職的員工
SELECT * FROM employees WHERE hire_date < '1-1月-90';
有中文,在其他平臺會出問題
 
7.特殊比較運算子
BETWEEN...AND... 在兩個值之間 包含邊界 可以是日期型別(查不出來空值)
IN(set)     等於值列表中的一個(查不出來空值)
LIKE        模糊查詢
IS NULL     空值 


查詢所有有部門的員工
SELECT last_name , manager_id FROM employees WHERE dapartment_id IS NOT NULL;
 
查詢工資在5000-10000之間的員工
SELECT * FROM employees WHERE salary BETWEEN 5000 AND 10000 ;(有邊界)


查詢工資不在5000-10000之間的員工
SELECT * FROM employees WHERE salary NOT BETWEEN 5000 AND 10000 ;(沒有邊界)


查詢部門不是10,20,50號員工
SELECT * FROM employees WHERE department_id NOT IN (10,20,50);
注意,如果IN後面的值有個為NULL,那麼所有資料都查不出來。

四、在oracle中模糊查詢的關鍵字是like
 

1.其中‘%’代表含有0到多個 ‘_’代表佔一個位
如果查詢中要查詢倒數第5個是下劃線的可以使用ESCAPE關鍵字
其中'\'是自定義的,可以是任何符號 
SELECT * FROM employee WHERE job_id LIKE '%\_____' ESCAPE '\';
其中後四個'_'佔四個位置,倒數第五個'_'代表它本來的意思'_';


2.查詢工資超過5000且last_name以s結尾的員工
SELECT * 
FROM employees
WHERE salary>=5000
AND last_name LIKE '%s';
 
3.查詢部門是10,20,以及沒有部門的員工
SELECT * 
FROM employees
WHERE department IN (10,20) 
OR department IS NULL; 


4.單引號轉義 如果查詢帶單引號的字串時 , 要多加一個單引號對其單引號進行轉義
例如查詢 HELLO'WORLD :
SELECT 'HELLO''WORLD' FROM dual; 
資料庫中單引號要做處理 ,防止別人SQL注入


5.查詢員工編號,姓名,工資,新工資,部門編號,按工資升序排列
SELECT employee_id,last_name,salary,salary*1.25 new_sal
FROM employees
ORDER BY salary;
  
6.查詢員工編號,姓名,工資,新工資,部門編號,按工資降序排列
SELECT employee_id,last_name,salary,salary*1.25 new_sal
FROM employees
ORDER BY salary DESC; 


 7.排序可以是別名
SELECT employee_id,last_name,salary,salary*1.25 new_sal
FROM employees
ORDER BY new_sal DESC;  


8.排序可以是表示式
 SELECT employee_id,last_name,salary,salary*1.25 new_sal
FROM employees
ORDER BY salary*1.25 DESC;  


9.排序可以是列索引,2代表第二列 也就是說按 last_name這一列排序
SELECT employee_id,last_name,salary,salary*1.25 new_sal
FROM employees
ORDER BY 2 DESC;   


10.查詢員工編號,姓名,工資,入職日期,部門編號(多排序表示式)
    按部門升序,工資降序,入職日期升序
SELECT employee_id,last_name,salary,hire_date,department_id
FROM     employees 
ORDER BY  department_id,salary DESC,hire_date;


11.排序表示式可以不是列列表中的列
SELECT employee_id,last_name,salary,hire_date,department_id
FROM     employees 
ORDER BY  job_id;
 
12.查詢50號部門的員工,按工資降序
子句是有順序的,先過濾,後排序
SELECT * 
FROM     employees
WHERE     department_id = 50
ORDER BY salary DESC; 


13.大資料排序的問題(非常耗費資源,容易造成伺服器宕機)
排序就是兩兩比較,排序預設產生的臨時資料放到排序區的記憶體中,
如果排序區不夠用,就會利用臨時表空間(排序區預設128K很小)
大排序之前一定要做資料庫優化 (怎麼優化目前不太清楚。。繼續學習中!)

 rownum和rowid是三大偽列中的其中兩個,是最容易搞混的兩個
偽列和虛表差不多,看不到,卻可以使用


五、rownum偽列
 

1.SELECT rownum,employee_id,last_name,salary
FROM    employees 
WHERE department_id = 50;
查詢結果是多了一列名為ROWNUM的列,這一列資料從1開始一直遞增。


2.查詢某表中的前5條資料(有其他欄位的時候查詢所有列要在前面加表名.*)
SELECT rownum,employees.* 
FROM employees
WHERE rownum<=5;


3.
rownum在以下條件一定為假,查不出來資料
rownum>n
rownum>=n
rownum=1以外的值 


4.rowid偽列
表資料行的實體地址
在插入資料時生成
在資料庫彙總是唯一的 
SELECT ROWID,employees.* 
FROM employees


六、函式(和帶返回值的方法一樣)分為兩類 
單行函式 和 多行函式
1.單行函式 upper() 將小寫變成大寫 傳入一行
用於 字元 通用 轉換 日期 數值
SELECT last_name,upper(last_name) 
FROM employees;


2.多行函式 傳入多行 得到一個結果
SELECT count(last_name)
FROM enployees; 


3.單行函式-字元函式 
    lower,upper:轉換大小寫
SELECT lower(last_name),upper(last_name)
FROM    employees;
 
4.initcap:單詞首字母大寫,其餘小寫
SELECT initcap('This IS a book') 
FROM dual ;
查詢結果 This Is A Book


5. concat(字串1,字串2):拼接字串
SELECT concat('hello','world')
FROM dual;
查詢結果 helloworld 


6.substr(字串,起始位置,擷取個數) :擷取一個字元的子串,起始位置可以是負數(右數第N位)
 SELECT substr('abcdefg',3) FROM dual;   結果:cdefg
 SELECT substr('abcdefg',3,2) FROM dual;   結果:cd
 SELECT substr('abcdefg',-3) FROM dual;   結果:efg
SELECT substr('abcdefg',-3,2) FROM dual;   結果:ef 


7.length:返回字串長度
SELECT length('abcd') FROM dual;  結果:4
SELECT length('') FROM dual;          結果:null(不返回0)


8.instr(字串,查詢子串[,起始位置[,第幾次出現]]);
查詢字串中子串的起始位置,如果找不到返回0
起始位置可以為負數(從右向左反向搜尋) 
SELECT inset('abcdefg','cd') FROM dual;   結果:3
SELECT inset('abcdefg','cdf') FROM dual;   結果:0
SELECT inset('abcdefgcdefg','cd') FROM dual;   結果:3  
SELECT inset('abcdefgcdefg','cd',4) FROM dual;   結果:8
SELECT inset('abcdefgcdefg','cd',-1) FROM dual;   結果:8 
SELECT inset('abcdefgcdefg','cd',1,2) FROM dual;   結果:8   


9.lpad(字串,固定長度,填充字元):左填充
    rpad:同上,右填充
SELECT lpad('abcd',7,'#') FROM dual; 結果:###abcd
SELECT lpad('abcd',3,'#') FROM dual;結果:abc  
SELECT rpad('abcd',7,'#') FROM dual;結果:abcd###
SELECT lpad('',7.'*') FROM dual;         結果:null 給空字串填充結果還是null
SELECT lpad(' ',7 ,'*') FROM dual;        結果: ******空格佔一個位
SELECT lpad('abcd',0,9,'*') FROM dual;結果:null 0.9算0 ,1.9算1   


10.trim(關鍵字 from 字串): 修建字串兩邊的關鍵字
SELECT trim('a' FROM 'aabcdaaxyza') FROM dual; 結果 bcdaaxyz(兩邊的a沒了)


SELECT 123||ltrim('   abcd   ') ||456 FROM dual; 結果:123abcd   456(修剪左邊空格)
SELECT 123||rtrim('   abcd   ') ||456 FROM dual; 結果:123   abcd456(修剪右邊空格)


SELECT rtrim('aabcdaaxyza','a') FROM dual; 結果:aabcdaaxyz(修剪右邊a)
SELECT ltrim('aabcdaaxyza','a') FROM dual; 結果:bcdaaxyza(修剪左邊a) 


11.replace(字串,查詢字串[,替換字串])
替換字串中的子串,預設替換為空的字串
SELECT replace('abcdefgabcd','cd') FROM dual; 結果:abefgab
SELECT replace('abcdefgabcd','cd','#') FROM dual; 結果:ab#efgab#


12.chr:把編碼轉化字元
SELECT chr(65) FROM dual; 結果 A


13.ascii:把字元轉換為編碼
SELECT ascii('A') FROM dual; 結果:65
SELECT ascii('國') FROM dual;結果:47610 
 
14.查詢員工姓和名字數相等的員工
SELECT * 
FROM    employees
WHERE     length(first_name) = length(last_name); 


15.查詢last_name以s結尾的員工(不用like)
SELECT * 
FROM  employees
WHERE substr(last_name,-1) = 's';


16.查詢所偶遇員工姓和名,輸出以下格式s.king
SELECT substr(first_name,1,1)||'.'||last_name
FROM employees ;


17.查詢所有的電話號碼,把分隔符“.”換成“-”之後再輸出
SELECT replace(phone_number,'.','-')
FROM employees ;


18.使用者輸入一個任意編號,查詢此編號的員工
(&後面的input是變數,input可以改成任意值,執行此SQL語句時Oracle會提示你輸入一個值)
SELECT * 
FROM employees
WHERE employee_id = &input; 


19.使用者輸入一個關鍵字,查詢last_name包含此關鍵字的員工(不用like)
 SELECT * 
FROM employees
WHERE instr(last_name,'&input')>0; 
用這個方法好處是使用者查詢帶%的資料不用轉義

20.自定義方法,用自動生成用註釋做別名的查詢發放

CREATE OR REPLACE FUNCTION F_COLCOM(TNAME IN VARCHAR2) RETURN VARCHAR2 IS
  RESULT VARCHAR2(4000);
  TSQL   VARCHAR2(4000);
BEGIN
  DECLARE
    CURSOR C_JOB IS
      SELECT COLUMN_NAME, COMMENTS
        FROM USER_COL_COMMENTS
       WHERE UPPER(TABLE_NAME) = UPPER(TNAME);
    C_ROW C_JOB%ROWTYPE;
  BEGIN
    FOR C_ROW IN C_JOB LOOP
      TSQL := TSQL || C_ROW.COLUMN_NAME || ' "' || C_ROW.COMMENTS || '|' || C_ROW.COLUMN_NAME || '",';
    END LOOP;
    TSQL := SUBSTR(TSQL, 1, LENGTH(TSQL) - 1);
    TSQL := 'select ' || TSQL || '  from ' || TNAME || ';';
  END;
  RESULT := TSQL;
  RETURN(RESULT);

END F_COLCOM;

呼叫方法:SELECT f_colcom('bz_projectcase') FROM dual;

如果只要註釋,不要列名:

CREATE OR REPLACE FUNCTION F_COLCOM(TNAME IN VARCHAR2) RETURN VARCHAR2 IS

  RESULT VARCHAR2(4000);

  TSQL   VARCHAR2(4000);

BEGIN

  DECLARE

    CURSOR C_JOB IS

      SELECT COLUMN_NAME, COMMENTS

        FROM USER_COL_COMMENTS

       WHERE UPPER(TABLE_NAME) = UPPER(TNAME);

    C_ROW C_JOB%ROWTYPE;

  BEGIN

    FOR C_ROW IN C_JOB LOOP

      TSQL := TSQL || C_ROW.COLUMN_NAME || ' "' || C_ROW.COMMENTS || '",';

    END LOOP;

    TSQL := SUBSTR(TSQL, 1, LENGTH(TSQL) - 1);

    TSQL := 'select ' || TSQL || '  from ' || TNAME || ';';

  END;

  RESULT := TSQL;

  RETURN(RESULT);

END F_COLCOM;

七、常用的數學函式和日期函式


1.round:(數字【,小數位數】):按照指定小數位數,四捨五入,預設到整數位
SELECT round(3.1415927) FROM dual;   結果--3
SELECT round(3.5415927) FROM dual;   結果--4
SELECT round(3.5415927,2) FROM dual;   結果--3.54 
 
2.trunc:(數字【,小數位數】):截斷到指定位數,不四捨五入,預設保留到整數位
SELECT trunc(3.1415927) FROM dual;  結果:3
SELECT trunc(3.5415927) FROM dual;  結果:3
SELECT trunc(3.5415927,2) FROM dual; 結果3.54
SELECT trunc(3.5) FROM dual; 結果:3


3.floor:返回不大於本身的最大整數 
SELECT floor(-3.5) FROM dual; 結果-4


4.ceil(數字):進位取整
SELECT ceil(3.000001) FROM dual; 結果:4
SELECT ceil(3.0) FROM dual;   結果:3 


5.mod:(被除數,除數):求模
SELECT mod(5,3) FROM dual;   結果:2


6.sysdate:返回當前系統的日期時間
SELECT sysdate FROM dual; 


7.日期型別和數字型別可以做加減運算:一個日期加減一個數字返回的還是一個日期(單位是天)
SELECT sysdate+3 FROM dual;
SELECT sysdate-100 FROM dual;
SELECT sysdate+1/24/60*25 FROM dual;         +25分鐘 


8.一個日期減去另外一個日期返回的是兩個日期間隔的天數
日期加減會有小數,可以用數學函式進行截斷
SELECT hire_date,trunc(sysdate-hire_date) AS 間隔天數 FROM    employees;


9.months_between(日期1,日期2):返回兩個日期間隔多少月 hire_date為入職日期
查詢每個員工的編號,姓名,入職日期,工齡
SELECT employee_id,last_name,hire_date,trunc(months_between(sysdate,hire_date)/12) 工齡
FROM employees ;


10.add_months(日期,N):給一個日期加減若干個月,返回一個新日期
N為正數是加,為負數是減
SELECT add_months(sysdate,-15) FROM dual; 


11.查詢入職日期超過20年的員工資訊(months_between和add_months兩種方式)
 SELECT *
FROM employees 
WHERE trunc(months_between(sysdate,hire_date)/12)>=20;


  SELECT *
FROM employees 
WHERE add_months(hire_date,20 * 12)<=sysdate;


12.next_day(日期,星期幾):返回以指定日期為準,一個最近的星期幾的日期
SELECT next_day(sysdate,'星期五') FROM dual;
可以用數字1-7代表日—六  1代表星期日
SELECT next_day(sysdate,6) FROM dual; 下週五


13. last_day(日期):返回指定日期的月最後一天的日期
SELECT last_day(sysdate) FROM dual;


14.round(日期【,日期單位】):對日期進行四捨五入 從12點開始
SELECT round(sysdate) FROM dual; 
SELECT round(sysdate,'month') FROM dual; 超過半月就是下一個月
SELECT round(sysdate,'year') FROM dual ; 超過半年就是下一年


15.trunc(日期【,日期單位】):對日期進行截斷
SELECT trunc(sysdate) FROM dual;    返回當天日期 月分秒都會被捨去
SELECT trunc(sysdate,'month') FROM dual ; 返回月初日期
 SELECT trunc(sysdate,'year') FROM dual ; 返回年初日期

oracle轉換函式主要轉換3種類型,日期,數字,字串
分隱式和顯示轉換 日期和數字都可以自由轉化字串
但是日期不能轉換為數字


16.SELECT '100' + '50' FROM dual;  結果:150


17.SELECT * 
FROM employees 
WHERE hire_date<='1-1月-90'; 字元型別自動轉化成日期型別 


18.SELECT 100||'hello' FROM dual; 結果100hello 轉化成字元型別


19.SELECT ’現在的時間:‘||sysdate FROM dual; 查詢結果為 現在時間:10-10月-16


20.顯示轉化 3個函式
TO_NUMBER
TO_DATE
TO_CHAR


21.to_char(日期|數字,'模式'):把一個日期或者數字按照指定模式轉化為字串
 SELECT '現在時間:'||sysdate FROM dual; 結果:現在時間:10-OCT-16
 SELECT '現在時間:'||to_char(sysdate,'yyyy-mm-dd') FROM dual; 結果:現在時間:2016-10-10
 SELECT '現在時間:'||to_char(sysdate,'dd/mm/yyyy') FROM dual; 結果:現在時間:10/10/2016
 SELECT '現在時間:'||to_char(sysdate,'dd/mm/yyyy hh24:mi:ss') FROM dual; 結果:時間:10/10/2016 21:26:22
 SELECT '現在時間:'||to_char(sysdate,'dd/mm/yyyy day') FROM dual; 結果:現在時間:10/10/2016 monday
  SELECT '現在時間:'||to_char(sysdate,'dd/mm/yyyy d') FROM dual; 結果:現在時間:10/10/2016 2 (2代表星期一)
 SELECT '現在時間:'||to_char(sysdate,'year-month-ddspth day') FROM dual; 結果:現在時間:twenty sixteen-october  -tenth monday  
(單詞性質的日期)
  SELECT '現在時間:'||to_char(sysdate,'yyyy"年"mm"月"dd"日"') FROM dual; 結果:現在時間:2016年10月10日 注意:要雙引號轉義!
 SELECT '現在時間:'||to_char(ADD_MONTHS(sysdate,-1),'fmyyyy-mm-dd') FROM dual 
結果:現在時間:2016-9-10 fm去除月或者日前面的0.


SELECT '數字:'|| to_char(&input,'fm9990.99') FROM dual; 最大4位整數,兩位小數,個數位必須有一個數字
SELECT '數字:'|| to_char(&input,'fm9990.0099') FROM dual; 最大4位整數,四位小數,個數位必須有一個數字,小數位有兩位小數
SELECT '數字:'|| to_char(&input,'fmL9990.0099') FROM dual; L為本地貨幣符號
SELECT '數字:'|| to_char(&input,'fmL9,990.0099') FROM dual;多一個千分為 :1.001.0052


22.查詢17號入職的員工
SELECT * 
FROM employees
WHERE to_char(hire_date , 'dd') = '17';


23,查詢7,8月份入職的員工
SELECT * 
FROM employees
WHERE to_char(hire_date,'mm') IN (7,8);  


24.to_date(日期字串,’模式‘):把日期字串按一定模式解析為一個日期型別
查詢95年以前入職員工
SELECT * 
FROM employees
WHERE hire_date<=to_date('1995-1-1','yyyy-mm-dd');


25,計算世界末日之後過了多少天
SELECT sysdate - to_date('2012-12-21','yyyy-mm-dd') FROM dual; 


26.to_number(數字字串,’模式‘):把一個字串解析為一個數字型別
SELECT * 
FROM employees
WHERE salary>to_number('$5,600','$9,999');


SELECT * 
FROM employees
WHERE salary>to_number(¥5,600','¥9,999'); 

 八、通用函式,適合所有資料型別
1.nvl(引數1,引數2):如果引數1不為空,返回引數1,如果為空,返回引數2
SELECT nvl(1,2) FROM dual;  結果1
SELECT nvl(null,2) FROM dual; 結果2


2.nvl2(引數1,引數2,引數3):如果引數1不為空,返回引數2,如果引數1為空,返回引數3
SELECT nvl2(1,2,3) FROM dual;  結果:2
SELECT nvl2(null,2,3)    FROM dual;結果:3


3.nullif(引數1,引數2): 引數1不等於引數2,返回引數1,如果相等,返回空
SELECT nullif(1,2) FROM dual;         結果:1
SELECT nullif(1,2) FROM dual;        結果:NULL 


4.coalesce(引數1,引數2,引數3...) :返回第一個非空值,如果都為空,則返回空
SELECT coalesce(1,2,3,4,5) FROM dual;  結果:1
SELECT coalesce(NULL,NULL,3,4,5) FROM dual;


5.查詢員工編號,姓名,工資,獎金金額,實發工資(工資+獎金)
(獎金有可能是空 直接加NULL結果是空 還有運算時不能用別名)
SELECT employee_id , last_name , salary , salary*nvl(commission_pct , 0) AS comm,
                salary+salary*nvl(commission_pct , 0)  AS money
FROM employees; 
 
6.查詢10號 , 20號 和沒有部門的員工(不用is null ,is not null實現)
SELECT * 
FROM employees
WHERE nvl(department_id,-1) IN (10,20,-1);


7. 用case表示式做等值判斷


case 表示式
    when 值1 then 返回值1
    when 值2 then 返回值2 
    ... ...
    CASE department_id
            WHEN 90 THEN 'NEC'
            WHEN 50 THEN 'HSW'
            WHEN 60 THEN 'USO'
            WHEN 80 THEN 'NEC'
    [else 預設返回值]
end


查詢員工編號,姓名,工資,部門編號,部門名稱
部門編號:
90        HEC
50        HSW
60        USO
80        NEC
其他     ICSS
SELECT employee_id,last_name,salary,
                department_id,
                CASE department_id
                    WHEN 90 THEN 'NEC'
                    WHEN 50 THEN 'HSW'
                    WHEN 60 THEN 'USO'
                    WHEN 80 THEN 'NEC'
                    ELSE 'ICSS'
                END    AS department_name 
FROM employees
 
--查詢員工編號,姓名,工資,工資級別,部門編號
工資級別:
>=17000    A
>=10000    B
>=5000      C
其他           D
SELECT employee_id , last_name,salary,
        CASE
                    WHEN salary>=17000    THEN    'A'
                    WHEN salary>=10000     THEN    'B'
                    WHEN  salary>=5000        THEN  'C' 
                    ELSE    'D'
            END AS 工資級別
            department_id
FROM    employees; 


8.decode(表示式,值1,返回值1,值2,返回值2,....【,預設返回值】)做等值判斷
 查詢員工編號,姓名,工資,部門編號,部門名稱
部門編號:
90        HEC
50        HSW
60        USO
80        NEC
其他     ICSS
SELECT employee_id,last_name,salary,department_id,
                decode(department_id,90,'NEC',50,'HSW',60,'USO',80,'GE','ICSS') AS department_name
FROM employees

RDBMS:關係型資料庫管理系統
表和表之間有引用關係,可以減少資料冗餘,方便後期維護


九、關係表的概念名詞
主表:被從表引用的表 有主鍵 唯一 不重複 不為空
從表:引用其他表的表 有外來鍵 外來鍵允許重複 允許為空 必須是主表中存在的值


資料庫中三大關係:
一對多    一條記錄匹配多條記錄(最常見的)
一對一    一條記錄匹配一條記錄
多對多    一個表的多條記錄匹配另外一個表的多條記錄(間接形成 使用者許可權會用到)


關係表三正規化(可以違反提高效率,主要看需求)
表不可以分割,表要有主鍵,表只引用其它表的主鍵


1.查詢員工編號,姓名,部門名稱(SQL1992)(笛卡爾集)
SELECT employee_id , last_name,department_name
FROM employees,departments;
笛卡爾集產生條件:
省略連線條件
連線條件無效
所有表中的所有行互相連線


2.查詢員工編號,姓名,部門名稱
SELECT employee_id , last_name,department_name
FROM employees,departments
WHERE employees.department_id = departments.department_id;
這樣寫得話有一個缺點 , 如果部門值為空的就查不出來 
連線n個表,至少需要n-1個連線條件 起別名要用空格不能用AS
連線表查詢,首先要弄清表關係!


3.查詢所有部門的編號,部門名稱,部門經理ID,部門經理名稱,部門所在城市及地區
SELECT  d.department_id,
                d.department_name,
                e.employee_id,
                e.last_name,
                l.city,
                c.country_name,
                r.region_name
FROM     departments d,
                employees e,
                locations l,
                countyies c,
                regions r
WHERE   d.manager_id=e.employee_id 
 AND        d.location_id=l.location_id
 AND        l.country_id=c.country_id
AND         c.region_id=r.region_id;


 4.檢視員工職務變更歷史記錄:(表多的話兩個兩個來)
員工編號,姓名,起始日期,終止日期,職務名稱,部門名稱
SELECT      e.employ_id,
                    e.last_name,
                    h.start_date,
                    h.end_date,
                    j.job_title,
                    d.department_name
FROM         employees e,
                    job_history h,
                    jobs j,
                    department d
WHERE       e.employee_id=h.employee_id 
AND             h.job_id=j.job_id
AND             h.department_id=d.department_id 


5.非等值連線(級別不存在相交,蠻少用)
查詢每個員工編號,姓名,工資,工資級別
SELECT          e,employee_id,
                        e.employee_name,
                        e.salary,
                        g.grade_level
FROM             employee e,
                        job_grades g
 WHERE          e.salary BETWEEN g.lowest_sal  AND g.highest_sal
ORDER BY      e.employee_id 


 6.內連線:查詢僅滿足連線條件的(連線查詢容易漏掉NULL值的條件)
    外連線:不僅返回滿足連線條件的記錄,不滿足連線條件的也返回 返回空值
查詢員工編號,姓名,部門名稱(外連線,沒有部門的員工也返回)
SELECT     e.employee_id , 
                   e.last_name,
                   d.department_name
FROM        employees e,
                  departments d
WHERE      e.department_id=d.department_id(+); 


查詢員工編號,姓名,部門名稱(外連線,沒有員工的部門也返回) 
SELECT     e.employee_id , 
                   e.last_name,
                   d.department_name
FROM        employees e,
                  departments d
WHERE      e.department_id(+)=d.department_id;  


7.查詢每個部門的編號,部門名稱,部門經理ID,部門經理姓名 (沒有部門經理的部門也返回)
SELECT      d.department_id,
                    d.department_name,
                    e.employee_id,
                    e.employee_name
FROM         departments d,
                    employees  e
WHERE       e.manager_id=e.employee_id(+);


8.自連線查詢(把它當作兩個表)
查詢員工編號,姓名,員工管理者編號,員工管理者姓名
SELECT        e.employee_id,
                      e.last_name,
                      m.employee_id MGR_ID,
                      m.last_name MGR_NAME
FROM            employees e,
                       employees m
WHERE          e.manager_id=m.employee_id(+);


9.查詢誰的工資比Abel高
SELECT     e1.employee_id,
                  e1.last_name,
                  e1.salary, 
                  e2.last_name,
                  e2.salary  
FROM        employees e1,
                   employees e2
WHERE       e1.salary>e2.salary
AND             e2.last_name='Abel' 

十、SQL1999語法(效率比SQL1992的效率要高)
SELECT        table1.column , table2.column
FROM           table1
[CROSS JOIN table2]    |
[NATURAL JOIN table2]    |
[JOIN table2 USING (column_name)]    |
[JOIN table2
    ON(table1.column_name = table2.column_name)]    |
[LEFT|RIGHT|FULL OUTER JOIN table2
    ON (table1.column_name = table2.column_name)];


1.SQL1999連線語法
查詢員工編號,姓名,部門編號,部門名稱(叉表 查詢笛卡爾集 沒啥用)
SELECT     e.employee_id,
                   e.last_name,
                   d.department_id,
                   d.department_name
FROM        employees e
CROSS    JOIN    departments d


2.內連線:INNER JOIN
   外連線:
   左外連線    LEFT  OUTER JOIN
   右外連線    RIGHT OUTER JOIN
    滿外連線    FULL OUTER JOIN


3.查詢員工編號,姓名,部門編號,部門名稱,職務編號,職務名稱(內連線 查不出來空值)
SELECT     e.employee_id,
                   e.last_name,
                   d.department_id,
                   d.department_name,
                   j.job_id,
                   j.job_title 
FROM        employees e
INNER    JOIN    departments d  ON  e.department_id=d.department_id
INNER    JOIN    jobs j     ON      e.job_id=j.job_id
WHERE     e,salary>=5000
ORDER BY e,salary DESC;


4. 查詢員工編號,姓名,部門編號,部門名稱(左外連線 LEFT OUTER左邊不滿足連線條件的也返回 返回employees資料)
SELECT     e.employee_id,
                   e.last_name,
                   d.department_id,
                   d.department_name, 
FROM        employees e  LEFT OUTER JOIN departments d  ON  e.department_id=d.department_id;


5. 查詢員工編號,姓名,部門編號,部門名稱(右外連線 RIGHT OUTER右邊不滿足連線條件的也返回 返回departments資料)
SELECT     e.employee_id,
                   e.last_name,
                   d.department_id,
                   d.department_name, 
FROM        employees e  RIGHT OUTER JOIN departments d  ON  e.department_id=d.department_id; 


6. 查詢員工編號,姓名,部門編號,部門名稱(滿外連線 部門為空的員工和員工為空的部門都返回)
SELECT     e.employee_id,
                   e.last_name,
                   d.department_id,
                   d.department_name, 
FROM        employees e  FULL OUTER JOIN departments d  ON  e.department_id=d.department_id; 

十一、組函式及分析函式

1.組函式作用於一組資料,並對一組資料返回一個值。
 查詢所有工資的總和
SELECT SUM(salary) FROM employees;


2.組函式(如果是0行資料,count返回0 其他返回null)
SELECT SUM(salary),AVG(salary),MAX(salary),MIN(salary),COUNT(salary)
FROM employees
WHERE department_id=50; 


3.所有組函式都是忽略空值
SELECT count(commission_pct) FROM employees;
 
4.查詢所有沒有獎金的人數
SELECT COUNT(*)-COUNT(commission_pct) FROM employees; 


5.查詢部門總數(統計不重複的計數)
SELECT COUNT(DISTINCT department_id) FROM employees;


6.查詢每個部門的ID,員工工資總和,最高工資(三大子句同時使用)
SELECT department_id,
               SUM(salary) SAL_SUM,
               MAX(salary)
FROM    employees
WHERE department_id IS NOT NULL
GROUP BY department_id 
ORDER BY sal_sum DESC;
 
7. 多個分組表示式(兩個欄位完全相同分成一組)
SELECT department_id,
               job_id,
               SUM(salary)
FROM     employees
GROUP BY department_id,job_id;


8.查詢每個部門的名稱.人數
SELECT    d.department_name , count(e.employee_id) emp_count
FROM        employees e
INNER JOIN departments d ON e.department_id=d.department_id
GROUP BY d.department_name;


9.統計每年入職的人數:年份,人數
SELECT to_char(hire_date,'yyyy') 年份,count(*) 人數
FROM    employees
GROUP BY to_char(hire_date,'yyyy') 
ORDER BY 1;


10 .統計每年入職的人數:年份,人數(僅返回不少於2人的年份的資料)
用HAVING還是用WHERE 主要看需要的過濾的結果是分組之前的,還是分組之後的
SELECT to_char(hire_date,'yyyy') 年份,count(*) 人數
FROM    employees
GROUP BY to_char(hire_date,'yyyy')
HAVING COUNT(*)>=2 
ORDER BY 1;


11.分析函式
 over函式連續求和
 over1列資料是根據員工id進行累加求和(每一行結果是上行累加工資總和加這行工資)
 over2總工資
SELECT     employee_id,
                   salary,
                   department_id,
                   SUM(salary) over(ORDER BY employee_id)  over1,
                   SUM(salary) over() over2
FROM         employees; 


12.連續求和 分組求和 將相同部門工資求一個總和 (相同組結果一樣)
 SELECT     employee_id,
                   salary,
                   department_id,
                   SUM(salary) over(PARTITION BY department_id)  over1,
FROM         employees; 


13. 連續求和 over1和12一樣 over2是分組之後累加(相同組結果一樣)
     over3將相同部門進行累計求和 
SELECT     employee_id,
                   salary,
                   department_id,
                   SUM(salary) over(PARTITION BY department_id)  over1,
                   SUM(salary) over(ORDER BY employee_id)  over2,
                   SUM(salary) over(PARTITION BY department_id ORDER BY employee_id)  over3 
FROM         employees; 


14.按照部門編號做排名
row_number()通過部門ID排序做累加 從1開始 1,2,3,4,5,6.....(沒有並列)
dense_rank()通過部門ID分組後排序做累加 相同部門公用1個值 從1開始 1,2,2,3,3,3,4,5,5,6.....
rank()通過部門ID分組後排序做累加 相同部門公用1個值 從1開始 空出被佔的名次 1,2,2,4,4,4,4,4,9,9......
SELECT    row_number()    over(ORDER BY department_id) row_number,
                  dense_rank()    over(ORDER BY department_id) dense_rank,
                  rank() over(ORDER BY department_id) rank,
                  department_id,
                  employee_id,
                  last_name
FROM        employees; 


 15.按照部門編號降序做排名 降序空值排第一位
SELECT     rank() over(ORDER BY department_id DESC) rank,
                  department_id,
                  employee_id,
                  last_name
FROM        employees;  

十二、彙總(ANY、相關子查詢、EXISTS、WITH)

1查詢工資最高的前5名員工
SELECT     * 
FROM      (SELECT    *
                 FROM employees
                  ORDER BY salary DESC)
WHERE ROWNUMBER <=5;


2.查詢員工表中第6到第12條資料
SELECT     *
FROM      (SELECT  ROWNUM rnum     ,e.*     FROM employees    e    WHERE    ROWNUM<=12) 
WHERE     rnum    > =6 ;


3,查詢工資最高的第6到12條員工
SELECT *
FROM (SELECT ROWBUM rnum, e.* 
             FROM (SELECT  * 
                          FROM employees 
                          ORDER BY salary DESC) e 
              WHERE ROWNUM<=12)
where rnum>=6;    
 
4.查詢所有不是部門經理的員工
SELECT *
FROM employees
WHERE employee_id NOT IN   (SELECT manager_id  FROM department WHERE manager_id IS NOT NULL)


5    ANY 邏輯或比較 ALL邏輯與比較(可以用MAX MIN 取代)


6.相關子查詢(內外互動式相關子查詢)
    按照一行接一行的順序執行,主查詢的每執行一行都執行一次子查詢
    子查詢用到主查詢的資料
查詢員工編號,姓名,部門編號,工資,本部門的工資總和
SELECT employee_id,
               last_name,
               department_id,salary,
               (SELECT SUM(salary) 
                 FROM employees 
                 WHERE department_id = e.department_id) 
FROM employees e; 


7查詢所有工資超過本部門平均工資的員工
SELECT * 
FROM employees e
WHERE salary>(SELECT AVG(salary) FROM employees WHERE department_id = e.department_id);


8.查詢是本部門入職最早的但不是部門經理的員工
SELECT * 
FROM employees e
WHERE hire_date=(SELECT MIN(hire_date) 
                                   FROM employees 
                                   WHERE department_id=e.department_id)
AND         employee_id NOT IN (SELECT manager_id 
                                                    FROM employees 
                                                    WHERE manager_id IS NOT NULL) 
9.EXISTS查詢(EXISTS後面的子查詢如果查得出資料,那麼主查詢才查得出來資料)
SELECT    *
FROM    employees
WHERE    EXISTS(SELECT * FROM departments WHERE 1=0) 


10.查詢所有是部門經理的員工(代替in語法 提高效率 X代表任意資料)
SELECT    *
FROM    employees e
WHERE EXISTS(SELECT 'X' 
                            FROM departments d
                            WHERE    e.employee_id = d,manager_id); 


11.查詢所有不是部門經理的員工(代替in語法 提高效率 X代表任意資料)
SELECT    *
FROM    employees e
WHERE  NOT EXISTS(SELECT 'X' 
                            FROM departments d
                            WHERE    e.employee_id = d,manager_id);  


 12.查詢工資最高的前5的員工(WITH子句)
WITH new_emp   as (SELECT * FROM employees ORDER BY salary DESC)
SELECT * FROM new_emp WHERE ROWNUM<=5;


13.WITH子句 定義子查詢作為一個表起別名 然後在後面的查詢中呼叫(可以定義多個表)
WITH dept_costs AS
(SELECT d.department_name,
                SUM(e.salary) AS dept_total)
  FROM    employees e,
                 departments d
  WHERE e,department_id = d.department_id
  GROUP BY d.department_name),
avg_cost AS
(SELECT SUM(dept_total) / COUNT(*) AS dept_avg
  FROM dept_costs)


SELECT * 
FROM dept_costs
WHERE dept_total > (SELECT dept_avg
                                    FROM   avg_cost)
ORDER BY department_name;

十三、樹狀結構分級查詢

 1.分級查詢(遍歷樹結構的資料)(通過子節點查詢父節點 通過父節點查詢子節點)
CONNECT BY PRIOR cloumn1 = column2
從頂到底 cloumn1 = Parent Key
               cloumn2 = Child Key
從底到頂 cloumn1 = Child key
               cloumn2 = Parent Key 


2.查詢206號員工所有的上級管理者(包括管理者的管理者)
<level>代表層次 從1開始 可以並列
SELECT level,employee_id,last_name,manager_id
FROM employees
START WITH employee_id = 206
CONNECT BY PRIOR manager_id = employee_id; 


3.查詢101員工所有的下級員工(從上向下)
SELECT level , employee_id,last_name,manager_id
FROM employees
START WITH employee_id = 101
CONNECT BY PRIOR employee_id =manager_id; 


4.統計101員工的所有的手下的人數
(WHERE子句過濾單個節點)
SELECT COUNT(*)
FROM employees
WHERE employee_id<>101
START WITH employee_id = 101
CONNECT BY PRIOR employee_id = manager_id;


5.過濾整個分支(將205整個分支過濾掉)
SELECT COUNT(*)
FROM employees
START WITH employee_id = 101
CONNECT BY PRIOR employee_id = manager_id AND employee_id <>205;


6. DML(增刪改)
插入資料 insert in 表名 【(列1,列2,...)】 values (值1,值2,...) ;
省略列列表,預設就是表中的所有列
列和值必須要個數,順序,型別相同


7.增加一個新部門
INSERT INTO departments (department_id,department_name,manager_id,localtion_id)
VALUES (120,'NEC',206,1700);


8,查詢結果儲存為表(快速創表)
CREATE TABLE new_emp
AS
SELECT employee_id,last_name,salary
FROM  employees; 

(建立空表)
CREATE TABLE new_dept
AS
SELECT  * FROM departments WHERE 1=0;


9.插入多行資料(底層資料庫維護用處比較多)
INSERT INTO new_dept SELECT * FROM departments;

我們經常寫的update語句其實是被簡寫過的,如果需要給更新語句起別名,參考這種寫法:

UPDATE T SET T.TID=1,T.TNAME='Name',T.TClass=1 FROM [TABLE] T WHERE T.ID=10


10.更新資料 update  表名 set 列1=值1,列2=值,...[where 子句](不加where更新所有資料)
UPDATE new_emp SET first_name='三',last_name='張' WHERE employee_id = 100


11.修改60號部門員工的工資上浮50元
UPDATE new_emp SET salary = salary+50 WHERE department_id = 60;


12.修改103號員工的工資和100號員工相同
UPDATE new_emp SET salary = (SELECT salary FROM new_emp = WHERE employee_id = 100) 
WHERE employee_id = 103;


13.刪除資料 delete from 表名 [where 子句] 
 刪除部門名稱為IT的部門的員工
DELECT FROM new_emp 
WHERE     department_id = (SELECT     department_id
                                              FROM        departments
                                              WHERE      department_name = 'IT');    
 14合併語句merge 解決效率問題 做資料同步 (同步修改 新增)
按照指定的條件執行插入或跟新操作
如果滿足條件的行存在,執行跟新操作,否則執行插入操作
避免多次重複執行插入和刪除操作
提高效率而且使用方便
在資料倉庫用的比較多
 
建立倆個表 修改部分資料
CREATE TABLE emp1
AS
SELECT employee_id,last_name,salary
FROM employees; 


CREATE TABLE emp2
AS
SELECT employee_id,last_name,salary
FROM employees;  


MERGE INTO emp2 e2
USING  emp1 e1 ON(e1.employee_id = e2.employee_id)
WHEN MATCHED THEN
            UPDATE    SET e2.last_name = e1.last_name,e2.salary=e1.salary
WHEN NOT  MATCHED  THEN
            INSERT VALUES (e1.employee_id,e1.last_name, e1.salary)




十三、oracle鎖

oracle鎖一般都是預設加,當一個事務開始的時候預設加鎖,當一個事務結束的時候,預設取消鎖。當然也可以人為加鎖。 
一.oracle鎖按照顆粒劃分可以分為行鎖和表鎖。
1.行鎖是鎖住一行(DML語句中,增,刪,改等都是加的行鎖)。
2.表鎖是鎖住一個表,比如(DDL語句一般加的都是表鎖)。


二.oracle鎖按照顯隱可以劃分為顯示鎖和隱式鎖
1.隱式鎖是預設加的鎖(DML語句中,增,刪,改等都是加的都是隱式鎖);
2.顯示鎖是人工手動加鎖。一般查詢語句是不會加鎖的,但是也可以手動加鎖(sql語句後面加 for update 鎖行)
   還有一種情況是手動鎖表,手動鎖表分為兩種:lock table 表 in share | exclusive mode;
    share模式:禁止其他會話對錶做DML操作,但是允許其他會話也對錶加share鎖
    exclusive模式:禁止其他會話對錶進行DML操作,也禁止其他會話對錶加任何鎖


三.oracle鎖按型別分可以分為獨佔鎖和共享鎖
    1.獨佔鎖  
    2.共享鎖 
     (DML語句對錶中行加的是獨佔鎖,對錶加的是共享鎖) 也就是說,事務執行增,刪,改操作操作的時候,鎖住了表的一行,
    其他的事物對這一行不能進行操作,可以對該表的其他行進行操作。
     (加了共享鎖的表不能再加獨佔鎖) 事務執行增,刪,改操作操作的時候,給表加上了共享鎖,那麼該表就不能執行DDL語句,
    也就是說不能對該表進行刪除表等操作 


四.oracle死鎖(兩個事務互相鎖)
舉個例子。A事務和B事務同時執行操作a,b兩行,首先A事務鎖住了a行,然後B事務鎖住了b行,A事務還要操作b行,
但是b行被B事務鎖住了,所以A事務等待B事務解鎖。而B事務還要操作a行,但是現在a行被A事務鎖住,所以B事務要等待A事務
對a行解鎖。然後兩個事務就發生了死鎖(互相等待別的事務解鎖)。
死鎖是不可避免的,但是oracle會對死鎖進行檢查,如果檢測到死鎖會丟擲一個異常,這裡可以用JAVA捕獲異常的機制捕獲死鎖異常
回滾其中一個事務,就能解決死鎖問題了。


五.oracle強行解鎖
1.下面的語句用來查詢哪些物件被鎖:
select object_name,machine,s.sid,s.serial#
from v$locked_object l,dba_objects o ,v$session s
where l.object_id = o.object_id and l.session_id=s.sid;
2.下面的語句用來殺死一個程序:
alter system kill session '24,111'; (其中24,111分別是上面查詢出的sid,serial#)
【注】以上兩步,可以通過Oracle的管理控制檯來執行。
3.如果利用上面的命令殺死一個程序後,程序狀態被置為"killed",但是鎖定的資源很長時間沒有被釋放,那麼可以在os一級再殺死相應的程序(執行緒),首先執行下面的語句獲得程序(執行緒)號:
select spid, osuser, s.program
from v$session s,v$process p
where s.paddr=p.addr and s.sid=24 (24是上面的sid)
4.在OS上殺死這個程序(執行緒):
1)在unix上,用root身份執行命令:
#kill -9 12345(即第3步查詢出的spid)
2)在windows(unix也適用)用orakill殺死執行緒,orakill是oracle提供的一個可執行命令,語法為:
orakill sid thread
其中:
sid:表示要殺死的程序屬於的例項名
thread:是要殺掉的執行緒號,即第3步查詢出的spid。

oracle鎖一般都是預設加,當一個事務開始的時候預設加鎖,當一個事務結束的時候,預設取消鎖。當然也可以人為加鎖。 

十四、DDL語句
表名和列名:
必須是已字母開頭
必須在1-30個字元之間
必須只能包含A-Z,a-z,0-9,_,$和#
必須不能和使用者定義的其他物件重名
必須不能是Oracle保留字


建立表 CREATE TABLE [schema.] table (column datatype [DEFAULT expr][,...]);
必須具備 CREAT TABLE許可權
儲存空間
必須指定表名,列名,資料型別,尺寸


建立表
CREATE TABLE student
(
    stu_id NUMBER(6),
    stu_name VARCHAR2(50).
    stu_sex CHAR(2),
    stu_hiredate DATE
);
刪除表
DROP TABLE student;


建立表(帶預設值 插入時候使用者沒賦值用預設值,插入賦值就用賦的值)
CREATE TABLE student
(
    stu_id NUMBER(6),
    stu_name VARCHAR2(50).
    stu_sex CHAR(2) DEFAULT '男';,
    stu_hiredate DATE DEFAULT SYSDATE
);
利用子查詢建立表
CREATE TABLE new_emp2
AS 
SELECT employee_id,last_name
FROM employees;
常用的資料字典
SELECT * 
FROM user_tables;


SELECT * 
FROM user_objects;


SELECT * 
FROM user_catalog; 


修改列(使用 ALTER TABLE語句)
追加新的列
修改現有的列
為新追加的列定義預設值
刪除一個列


--追加 
ALTER TABLE student
ADD (phone VARCHAR2(50),address VARCHAR2(100)); 


--修改(資料結構要相容)
ALTER TABLE student
MODIFY (address VARCHAR2(200)); 


--刪除列
ALTER TABLE student
DROP (phone);


--表註釋
COMMENT ON TABLE stu IS '這是我的學生表';


--列註釋
COMMENT ON COLUMN stu.stu_id IS '學生編號';
COMMENT ON COLUMN stu.stu_name IS '學生姓名';
 
--回收站的資料字典
SELECT * FROM user_recyclebin;


--還原表(閃回)
FLASHBACK TABLE stu TO BEFORE DROP;


--清空回收站
PURGE RECYCLEBIN; 


臨時表
建立事務臨時表 : 資料僅在一個事務中存在
CREATE GLOBAL TEMPORARY TABLE temp1
(
id NUMBER , 
name VARCHAR2(50)

ON COMMIT DELETE ROWS;


建立會話臨時表:資料僅在一個會話中存在
CREATE GLOBAL TEMPORARY TABLE temp2
(
id NUMBER,
name VARCHAR2(50)

ON COMMIT PRESERVE ROWS; 


約束(5種)
NOT NULL 非空約束(限制列值不能為NULL)
UNIQUE    唯一值約束
PRIMARY KEY 主鍵約束 (現在列值不允許重複,不能為空,一個表只能有一個)
FOREIGN KEY 外來鍵約束
CHECK  檢查約束


--增加約束
ALTER TABLE 表名
ADD CONSTRAINTS 自定義約束名稱(一般設定表名_列名_pk)  約束設定(列名,...)


--刪除約束
ALTER TABLE newemp
DROP CONSTRAINTS 自定義約束名稱; 

oracle鎖一般都是預設加,當一個事務開始的時候預設加鎖,當一個事務結束的時候,預設取消鎖。當然也可以人為加鎖。 

資料庫快閃記憶體功能,用來解決正式環境刪錯表的問題,慎用!

-- 查詢指定時間之後更新的資料(dcc_org是表名)
select * from dcc_org as of timestamp to_timestamp('2017-12-10 07:30:00', 'yyyy-mm-dd hh24:mi:ss');

-- 閃回操作前啟用行移動功能(不啟用不可以閃回)
alter table dcc_org enable row movement;

-- 執行閃回
flashback table dcc_org to timestamp to_timestamp('2017-12-10 07:30:00', 'yyyy-mm-dd hh24:mi:ss');