【筆記】Oracle SQL語句 | 基礎篇


整理了一下Oracle SQL的基本語句,主要針對Oracle的使用者(Oracle數據庫維護和管理員的常用語句之后整理),可作為一個大綱參考,對某些語句或函數並未深入的詳解,只是簡單列出,留個印象,真正在實踐中遇到問題時能夠聯想起來,再Google之即可。

作為剛接觸學習Oracle的同學,掌握基本的操作語句(sqlplus環境常用命令,CRUD基本語句),進而進階到PL/SQL編程(存儲過程,函數等),差不多可以應付日常的應用需求,之后如果有工作需求或興趣,可以再進一步學習數據庫維護管理,語句優化,以及Oracle體系結構等知識。

  

----------1. SQL PLUS常用命令-------------
------1.1 連接數據庫
sqlplus / as sysdba  ---本地操作系統認證,無需listener進程
sqlplus username/password  ---連接本地數據庫,服務處於可用狀態
sqlplus username/password@orcl  ---listener進程處於可用狀態
sqlplus username/password@host:port/sid  ---無需tnsnames.ora配置

sqlplus /nolog
conn / as sysdba
conn username/password
conn sys/password as sysdba
conn username/password@orcl
conn sys/password@orcl as sysdba
conn username/password@host:port/sid

------1.2 打開/關閉數據庫
startup [nomount|mount|open|force] [restrict] [pfile=filename]
shutdown [normal|transactional|immediate|abort]

------1.3 HELP命令
help st  ---模糊查詢
help startup  ---完整查詢
help index  ---命令清單

------1.4 SET設置運行環境
set echo on|off  ---列出命令
set serverout on [size n]|off  ---存儲過程是否顯示
set heading on|off   ---列標題
set pagesize 14   ---一頁行數
set newpage 1   ---一頁中空行數
set linesize 80   ---一行最多字符總數
set pause on|off|text   ---是否每頁暫停
set numformate $999,999,999.00   ---數值默認格式

------1.5 格式化查詢結果
---column
col empno format $999,999.00
col sal heading SALARY
col sal off|on
col sal null 'NULL'
col sal wrapped|word_wrapped
---ttitle/btitle
title center 'SALARY LIST'
btitle left 'DATE:2018.07.08'
title off
title on

------1.6 查看對象或變量
---desc
desc object;
#desc object   ---命令輸入中間使用
---show
show all|parameters db_block_size|sga|spool|user;

------1.7 運行命令或腳本
edit/save/get filename
/   ---執行上一條語句或塊
start/@ test.sql
---spool
spool [filename] [create|replace|append]
spool off/out

----------2. SQL語句基礎-------------
------2.1 查詢SELECT
/*
select {[distinct | all] column | *}
[into table_name]
from {table | views | other select}
[where conditions]
[group by columns]
[having conditions]
[order by columns]
*/
---簡單查詢
select a.rowid as RI,a.job,a.sal*(1+0.1),a.* from emp a;
---不重復記錄
select distinct job from emp;
---篩選查詢
select empno from emp where sal > 1500 or sal < 500;  --->,<,!,<>,>=,<= value|ANY/ALL(B)
select empno from emp where ename like 'L_\_%' escape '\'; ---Li_ke; %,_,escape
select empno from emp where job in ('PRESIDENT','MANAGER');  ---not in
select empno from emp where job sal between 2000 and 3000;  ---not between A and B
select street_address from locations where state_province is null;
---分組查詢
select job,avg(sal),sum(sal),max(sal),min(sal),count(job) 
from emp 
group by job
having avg(sal) > 2000---單列,分組列名or統計函數
select deptno,job,avg(sal),max(sal) from emp group by deptno,job
group by rollup(deptno,job);  ---多列,rollup/cube/grouping sets
---排序查詢
order by sum(sal) desc;   ---asc
order by 3 desc;   ---asc

------多表關聯查詢SELECT
---表別名
select e.empno,e.ename,d.dname
from emp e,dept d
where e.deptno = d.deptno
and e.job = 'MANAGER';   ---執行順序from,where,select
---內連接
select e.empno,e.ename,d.dname
from emp e join dept d
on e.deptno = d.deptno;
---外連接
select e.empno,e.ename,d.dname
from emp e left|right|full join dept d
on e.deptno = d.deptno;  ---A∪(A∩B),(A∩B)∪B,A∪B-A∩B
---自然連接
select empno,ename,job,dname
from emp natural join dept
where sal > 2000;  ---相同名稱的列自動連接
---自連接
select em2.name as Manager, em1.name as Employee
from emp em1 left join emp em2
where em1.mgr=em2.empno
order by em1.mgr;  ---上下級關系或層次關系
---交叉連接
select count(*) from dept cross join emp;  ---笛卡爾積

------子查詢SELECT
select empno from emp
where sal > (select min(sal) from emp);  ---單行
select empno from emp
where deptno in (select deptno from dept where dname<>'SALES');  ---多行 ANY/ALL
select empno from emp f
where sal > (select avg(sal) from emp where job = f.job);  ---關聯
      
------2.2 新增INSERT
insert into dept(deptno,dname,loc) values(88,'design',''beijing);  ---單條
accept salary prompt 'Please input salary';
insert into jobs values('PRO','IT',&salary,DEFAULT);  ---替代變量,default值
insert into jobs_temp select * from jobs where jobs.max_salary > 10000;  ---批量

------2.3 更新UPDATE
update emp set sal = sal*1.2 where job = 'SALESMAN';
update emp set job = DEFAULT where ename = 'SCOTT';
update emp set sal = (select avg(sal) from emp where job = 'MANAGER');

------2.4 刪除DELETE/TRUNCATE
delete from jobs where job_id = 'PRO';
truncate table jobs_temp;

------2.5 常用系統函數
---字符類
--ASCII/CHR,CONCAT/||,INITCAP,INSTR,LENGTH,
--LOWER/UPPER,LTRIM/RTRIM/TRIM,REPLACE,SUBSTR
---數字類
--ABS,CEIL,COS,EXP,FLORR,LOG,MOD,POWER,ROUND,SIGN,SIN,SQRT,TRUNC
---日期/時間類
--ADD_MONTHS,LAST_DAY,MONTHS_BETWEEN,NEW_TIME,SYSDATE
---轉換類
--CHARTORWIDA,CONVERT,ROWIDTOCHAR,TO_CHAR,TO_DATE,TO_NUMBER,NVL
---聚合類
--AVG,COUNT,MAX,MIN,SUM,VARIANCE,STDDEV

----------3. PL/SQL編程-------------
------3.1 塊結構
declare
  a number(7,2):=999.99;  --數字類型decimal,double,int,numeric,binary_integer,pls_integer
  b varchar2(10);  --字符類型char,long,nchar,nvarchar2
  c date;  --日期類型
  d emp.job%type;  --%type類型
  e emp%rowtype;  --%rowtype類型
  type ftype is record
  (
       f1 number(7,2),
       f2 varchar2(10)
  );
  f ftype;  --record類型
  g boolean;  --布爾類型
  con_h constant int:=1500;  --常量
  ---
  i int:=0;
  sum_i int:=0;
  ---
  cursor cur_emp(var_job in varchar2:='SALESMAN')
  is select empno,ename,sal from emp where job=var_job;  --定義游標
  type record_emp is record
  (
    var_empno emp.empno%type,
    var_ename emp.ename%type,
    var_sal   emp.sal%type
  );
  emp_row record_emp;
  cursor cur_emp2 is select * from emp where deptno = 30;
  ---
  primary_iterant exception;
  pragma exception_init(primary_iterant,-00001); --自定義錯誤編號異常
  sal_exception exception;  ---自定義業務邏輯異常
begin
  --基本類型
  select sal,ename,sysdate,job into a,b,c,d
  from emp where empno = 7499;
  dbms_output.put_line('Date:'||c||','||b||' job:'||d||',salary:'||a);
  --%rowtype類型
  select * into e
  from emp where empno = 7499;
  dbms_output.put_line(e.ename||' empno:'||e.empno);
  --%record類型
  select sal,ename into f
  from emp where empno = 7499;
  dbms_output.put_line(f.f2||' salary:'||f.f1);
  --選擇語句if
  g:=a<con_h;
  if g then
    dbms_output.put_line('salary '||a||'<'||con_h);
  elsif a>con_h then
    dbms_output.put_line('salary '||a||'>'||con_h);
  else
    dbms_output.put_line('salary '||a||'='||con_h);
  end if;
  --選擇語句case
  case g
    when true then
      dbms_output.put_line('salary '||a||'<'||con_h);
    when false then
      dbms_output.put_line('salary '||a||'>='||con_h);
    else
      dbms_output.put_line('Can not Happen!');
  end case;
  --循環語句loop
  loop
    i:=i+1;
    sum_i:=sum_i+i;
    exit when i=100;
  end loop;
  dbms_output.put_line('loop:sum of first 100 num is:'||sum_i);
  --循環語句while
  i:=0;
  sum_i:=0;
  while i<=99 loop
    i:=i+1;
    sum_i:=sum_i+i;
  end loop;
  dbms_output.put_line('while:sum of first 100 num is:'||sum_i);
  --循環語句for
  sum_i:=0;
  for i in reverse 1..100 loop
    sum_i:=sum_i+i;
  end loop;
  dbms_output.put_line('for:sum of first 100 num is:'||sum_i);
  ---顯式游標
  open cur_emp('MANAGER'); --打開游標
  fetch cur_emp into emp_row;  --獲取當前游標記錄
  while cur_emp%found loop  --%notfound,rowcount,isopen
    dbms_output.put_line(emp_row.var_ename||' empno:'||emp_row.var_empno||' salary:'
                       ||emp_row.var_sal);
    fetch cur_emp into emp_row;  --指向下一記錄
  end loop;
  close cur_emp;  --關閉游標
  --隱式游標
  update emp set sal=sal*1.01 where job = 'SALESMAN';
  if sql%notfound then
    dbms_output.put_line('No record update!');
  else
    dbms_output.put_line(sql%rowcount||' record updated!');
  end if;
  --for循環游標
  for emp_record in cur_emp
  loop
    dbms_output.put_line(emp_record.empno||' empno:'||emp_record.ename||' salary:'
                       ||emp_record.sal);    
  end loop;  --顯示
  for emp_record in (select empno,ename,sal from emp where job = 'SALESMAN')
  loop
    dbms_output.put_line(emp_record.empno||' empno:'||emp_record.ename||' salary:'
                       ||emp_record.sal);
  end loop;  --隱式
  ---異常處理
  select * into e from emp; --where empno = 7499;
  insert into dept values(10,'Software','SZ');
  if e.sal > con_h then
    raise sal_exception;
  end if;  
exception
  when too_many_rows then
    dbms_output.put_line('too many rows!');  --預定義異常
  when primary_iterant then
    dbms_output.put_line('duplicate record!');  --自定義錯誤編號異常
  when sal_exception then
    dbms_output.put_line('sal is high!');  --自定義業務邏輯異常
end;
/

------3.2 存儲過程
---創建
create or replace procedure square(
  numb in out number default 100,
  flag in boolean) 
is  --as
  i int:=2;  --內部變量
begin
  if flag then
    numb:=power(numb,i);  --平方
  else
    numb:=sqrt(numb);  --開方
  end if;
exception
  when others then
    dbms_output.put_line('Error!');
end;
/

---調用
declare
 var_number number;
 var_temp number;
 boo_flag boolean;
begin
 var_temp:=3;
 var_number:=var_temp;
 boo_flag:=false;
 square(var_number,boo_flag);  --調用
 dbms_output.put_line(var_number);
end;
/ ---單獨調用可以在sqlplus中使用exec命令

---刪除
drop procedure square;

------3.3 函數
--創建
create or replace function get_avg_pay(num_deptno number) return number --必須有返回值
is
  num_avg_pay number;  --內部變量
begin
  select avg(sal) into num_avg_pay from emp where deptno=num_deptno;--獲取某個部門的平均工資
  return(round(num_avg_pay,2));--返回平均工資
exception
  when no_data_found then --若此部門編號不存在
    dbms_output.put_line('該部門編號不存在');
    return(0); --返回平均工資為0
end;
/

--調用
declare
  avg_pay number;
begin
  avg_pay:=get_avg_pay(10);
  dbms_output.put_line('平均工資:'||avg_pay);
end;
/

--刪除
drop function get_avg_pay;

------3.4 觸發器
--創建
create or replace trigger tri_dept
  before insert or update or delete ---after/instead of
  on dept ---語句級觸發器  
  ---for each row 行級別觸發器
  ---替換觸發器instead of主要針對視圖
declare
  var_tag varchar2(10);
begin
  if inserting then
    var_tag := 'Insert';
  elsif updating then
    var_tag := 'Update';
  elsif deleting then
    var_tag := 'Delete';
  end if;
  insert into dept_log values(var_tag,sysdate);--向日志表中插入對dept表的操作信息
end tri_dept;
/

--觸發
insert into dept values(66,'Sales','SH');
update dept set loc='SY' where deptno = 66;
delete from dept where deptno = 66;

--刪除
drop trigger tri_dept;

------3.5 程序包
---程序包
create or replace package pack_emp is
  function fun_avg_sal(num_deptno number) return number;
  procedure pro_regulate_sal(var_job varchar2,num_proportion number);
end pack_emp;
/

---程序包主體
create or replace package body pack_emp is
  function fun_avg_sal(num_deptno number) return number is  --引入“規范”中的函數
    num_avg_sal number;--定義內部變量
  begin
    select avg(sal)
    into num_avg_sal
    from emp
    where deptno = num_deptno;--計算某個部門的平均工資
    return(num_avg_sal);--返回平均工資
  exception
    when no_data_found then--若未發現記錄
      dbms_output.put_line('該部門編號不存在雇員記錄');
    return 0;--返回0
  end fun_avg_sal;

  procedure pro_regulate_sal(var_job varchar2,num_proportion number) is--引入“規范”中的存儲過程
  begin
    update emp
    set sal = sal*(1+num_proportion)
    where job = var_job;--為指定的職務調整工資
  end pro_regulate_sal;
end pack_emp;
/

---刪除
drop package pack_emp;

 

注:部分SQL語句來源於《Oracle 11g從入門到精通(第2版)》——清華大學出版社


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM