1. 程式人生 > >數據庫sql--總結

數據庫sql--總結

性能測試

--驗證存儲過程是否正確時,需要用declare塊。

declare

i integer;

v_sql varchar2(1000);

-- 定義遊標

CURSOR C_EMP IS SELECT category FROM act_hq_tem_def;

begin

select count(*) into i from user_tables t where t.table_name ='SSS';

dbms_output.put_line('I的值是:');

dbms_output.put_line(i);

if i=1 then

execute immediate 'drop table sss'; end if;

IF I=0 THEN

execute immediate '

create table sss(

name number(20) )';

end if;

dbms_output.enable(1000000);

for tab in (

select t.guid gd, t.name nm from fasp_T_causer t

)

loop --loop 是開始循環, 需要結束標識loop end 。

v_sql := 'select count(*) from fasp_T_causer';

execute immediate v_sql into i;

If i > 0 then

DBMS_OUTPUT.PUT_LINE(tab.nm || ' tab 中的name值 ' || tab.gd );

end if;

end loop ;

--遍歷遊標

for c_row22 in c_emp loop

if substr(c_row22.category,-4) ='2016' then

dbms_output.put_line('流程類型' || c_row22.category);

end if;

end loop ;

------------------------------------------------------------

--創建存儲過程

create or replace procedure p_wf_cf(yn varchar2,yo varchar2,allds out varchar2) as

cursor c_emp is select category from act_hq_tem_def;

tablec1 number;

begin

select count(*) into tablec1 from user_tables where table_name='ACT_HI_PROCINST_' || yn;

allds := tablec1;

end p_wf_cf;




--調用存儲過程,輸出值也在函數裏傳進去。 之後可以替換輸出值,打印出來。

declare

v_titleA VARCHAR2(20) := '2017';

v_titleb VARCHAR2(20) := '2016';

v_titlec11 VARCHAR2(20) :='12';

begin

p_wf_cf(v_titleA,v_titleb,v_titlec11);

v_titlec11 :=p_wf_cf(v_titleA,v_titleb); --存儲過程中需要有return 操作,才可用這種方式。

dbms_output.put_line('輸出值為:' || v_titlec11);

end;







--編寫存儲過程

create or replace procedure p_fasp_sc (dblink in varchar) as

type refcursor is ref cursor;--定義遊標類型

col_cursor refcursor;--定義遊標變量

v_deptRow fasp_T_causer%ROWTYPE ; -- 定義行類型

v_empRow fasp_T_causer%ROWTYPE ; -- 定義行類型

tablename varchar2(100);

tmpsql varchar2(20000);

exesql varchar2(20000);

v_eno emp.empno%TYPE ; -- 與emp表中empno字段類型相同的類型。

v_resultA NUMBER NOT NULL := 100 ; -- 定義一個非空變量v_resultA,同時賦值

v_ename VARCHAR2(10) ;

v_deptRow dept%ROWTYPE ; -- 裝載一行dept表中記錄

v_date1 DATE := SYSDATE ;--定義時間

type emp_type is recode(

ename emp.ename%type,

job emp.job%type,

sal emp.sal%type,

comm emp.comm%type

);

v_emp emp_type;--定義一個指定的復合類型變量

begin

v_eno := &empno ; -- 由鍵盤輸入雇員編號

SELECT * INTO v_deptRow FROM dept WHERE deptno=10 ;--查詢一行記錄放在v_deptRow中。

tmpsql :='select table_name as tablename from fasp_v_usertables where table_name like ''FASP_T_GL%''';


open col_cursor for tmpsql; --打開遊標

loop

fetch col_cursor into tablename ; --取得遊標數據

exit when col_cursor%notfound; --如果沒有數據則退出

exesql := 'select count(*) from fasp_v_usertables';

begin

execute immediate exesql;

exception

when others then

dbms_output.put_line('baocuole');

raise;

end;

end loop;

close col_cursor;

end;




--調用存儲過程

declare

v_titleA VARCHAR2(20) := '1212';

begin

p_fasp_sc(v_titleA) ;

end;

--子程序

if 。。then 。。 else

and

or

between and

is null

not null

like


--case

CASE v_choose

WHEN 0 THEN

DBMS_OUTPUT.put_line('您選擇的是第0項。') ;

WHEN 1 THEN

DBMS_OUTPUT.put_line('您選擇的是第1項。') ;

ELSE

DBMS_OUTPUT.put_line('沒有選項滿足。') ;

END CASE ;


RAISE --報出異常。

COMMIT ;

--for


























--創建表

create table emp1(

empno number(12) unique,

ename varchar2(20) default null,

sal varchar2(20)

);


create table emp2 as select * from Fasp_t_Causer;


--創建表

create table emp3 (

epton number(3)constraint pk_emp3 primary key,

id number(10) not null,

firstname varchar2(22) unique,

waiempno number(12) ,

date2 date default sysdate

);


--添加外鍵 emp1 中的empno 需要是unique 類型。

alter talbe emp3 add constraint fk_emp3 foreign key(waiempno) references emp1(empno) on delete set null;


--增加索引

create index ind_id on emp3(id);


--刪除表

drop table emp;


--修改表

alter table emp add aaa char(10);---oracle 只能一條條的添加列。

alter table emp drop column sss;--刪除行。

alter table emp modify aadd NUMBER(6);--修改列長度。

alter table EMP1 modify sal not null;

alter table emp set unused(sss);--設置成無用狀態。


--插入數據

insert into emp values(123,'張si','','','');

commit;


--刪除數據

delete from emp where empno = 222;

commit;


--查詢數據

select * from emp;--shift+home鍵,然後按f8執行。

select distinct sal from emp; --查詢唯一

select empno 雇員編號, ename as 雇員名稱 from emp; --為查詢結果設置別名。

SELECT '編號是:' || empno || '的雇員姓名是:' || ename || ',基本工資是:' || sal 雇員信息 FROM emp ; -- 使用|| 進行連接

select empno , ename, (sal+200)*12 as 年薪 from emp; --查詢結果可設置函數。

select count(*) from emp;

select * from emp where empno in('112','211');

select * from emp where empno ='23' or empno ='222';

select * from emp where empno like '%222%';

select * from emp order by sal desc;


--更新數據

update emp set empno=2323, ename='zhangsan';








---函數。

select * from emp;

--initcap首字母大寫。

--replace(ename,'a','_') 將ename 中的所有a 替換成‘_’

--substr(ename,0,3)查詢ename 中前三個字符。

--SUBSTR(ename,3)截取ename中第三個以後得字符。

--SUBSTR(ename,length(ename)-2)最後三個字符。

select upper(ename), lower(ename), initcap(ename), replace(ename,'a','_'),substr(ename,0,3),SUBSTR(ename,3) from emp;

--返回ascll碼 。 cha將ascll碼轉為字符。

select ascll('L') from dual;

--ltrim(ename)去掉左邊空格,rtrim() 去掉右邊空格,trim()去掉左右兩邊空格。

select trim(ename) from emp;

--LPAD('MLDN' , 10 , '*') 字符串左邊填充, rpad 是右邊填充。

select lpad(ename,20,'*') from emp;


SELECT LPAD('MLDN' , 10 , '*') LPAD函數使用 , RPAD('MLDN' , 10 , '*') RPAD函數使用 ,

LPAD(RPAD('MLDN' , 10 , '*') , 16 , '*') 組合使用

FROM dual ;


--字符串查找 INSTR(),0表示沒有查找到。

select ename, instr(ename,'a') from emp;

--max最大值,sum 總和,desc降,asc 升

--NVL(E1, E2)的功能為:如果E1為NULL,則函數返回E2,否則返回E1本身。

select sal,nvl(sal,'salweikong') from emp;


--decode(字段或字段的運算,值1,值2,值3)這個函數運行的結果是,當字段或字段的運算的值等於值1時,該函數返回值2,否則返回值3當然值1,值2,值3也可以是表達式,

select sal, decode(sal,'100','ok','no') from emp;


--CONCAT('23','wer')函數用於將兩個字符串連接起來,形成一個單一的字符串

select ename,sal,concat(ename,sal) as 聯合 from emp;



--alt+tab鍵,桌面切換。

--grouping,GROUPING函數可以接受一列,返回0或者1。如果列值為空,那麽GROUPING()返回1;如果列值非空,那麽返回0。

--GROUPING只能在使用ROLLUP或CUBE的查詢中使用。當需要在返回空值的地方顯示某個值時,GROUPING()就非常有用。

select sal, case grouping(sal) when 1 then '男性' else '女性' end as 性別 from emp group by rollup(sal);

select empno, sal,ename from emp for update;

select sal, ename from emp group by sal,ename;

select sal, ename from emp group by rollup(sal,ename);--a+b,a+null,null+null

select sal, ename from emp group by cube(sal,ename);--所有組合。

--abs(數值)返回數值的絕對值。

--ceil(數值)根據輸入值返回一個數值,輸入參數可以是非整數,但返回結果則是大於等於輸入參數的最小整數。

--to_char

select to_char(ename) as enametochar from emp;

select * from emp1 for update ;

select * from emp for update ;

--left join .. on , right join ..on . 左右連接。

select t1.empno , t1.ename from emp t1 right join emp1 t2 on t1.empno=t2.empno;


--dual 是一張表,只有一個字段的偽表。


--round ,對小數的處理是四舍五入。

select round(456.1214) 不保留小數,round(45.13632,2) 保留兩位小數,round(2154.121,-2) 處理整數進位 from dual;


--trunc ,直接截取掉了,不四舍五入。

SELECT TRUNC(789.652) 截取小數, TRUNC(789.657,2) 截取兩位小數, TRUNC(789.652,-2) 取整 FROM dual ;



--獲取系統當前時間。

select sysdate+3 三天之後日期,add_months(sysdate , 3) 三個月之後日期 ,next_day(sysdate,'星期日') 下一個星期日 ,last_day(sysdate) 當前月的最後一天 , months_between(sysdate+30,sysdate) 相差月數 from dual;


--修改日期顯示格式。

alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';


--從日期中獲取出年月日。 month hour , minute , second , 時分秒。

select extract(year from date '2017-10-13') years , extract(month from date '2017-10-13') months , extract(day from date '2017-10-13') days from dual;



---復雜的時間間隔。

select extract (day from datatime_one - datetime_two) days from ( select to_timestamp('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss') datatime_one , to_timestamp('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss') datetime_two from dual);



--to_date, to_number , nullif , coalesce

SELECT TO_DATE('1979-09-19','YYYY-MM-DD') FROM dual ;


--NULLIF(表達式1,表達式2),如果表達式1和表達式2相等則返回空值,如果表達式1和表達式2不相等則返回表達式1的結果。

--COALESCE(表達式1,表達式2,...,表達式n),n>=2,此表達式的功能為返回第一個不為空的表達式,如果都為空則返回空值。


select nullif(ename , sal) from emp;


select nullif(ename , ename) from emp;


select coalesce(sal,ename ) from emp;






declare

--類型定義

cursor c_sal

is

select empno,ename,sal from emp ;

--定義一個遊標變量v_cinfo c_emp%ROWTYPE ,該類型為遊標c_emp中的一行數據類型

c_row c_sal%rowtype;

begin

for c_row in c_sal loop

dbms_output.put_line(c_row.empno||'_'||c_row.ename||'-'||c_row.sal); end loop;

end;


select * from Fasp_t_Carole;--角色

select * from Fasp_t_Causer;--用戶

select * from Fasp_t_Causerrole;--用戶和角色


select * from fasp_t_carole r, Fasp_t_Causer u , Fasp_t_Causerrole ur where u.guid = ur.userguid;

--join ... on ..

select * from Fasp_t_Causerrole ur right join fasp_t_causer u on u.guid = ur.userguid;


--union 代替 or 。

select * from Fasp_t_Causerrole where userguid='9FBCC6BADF91A51BDD1B0A6F5CCAA423' union

select * from Fasp_t_Causerrole where userguid='F7EF4442F65370EFC8ED936ECB210A07' ;



--sum , avg , max , min , round , median中間,count , distinct , group by ,

select sum(empno) from emp;

select COUNT(*) from EMP GROUP BY SAL;


select '領取傭金' , round(avg(sal),2) avgsal, count(empno) count from emp ;


--group by ... having ,

select count(empno), round(avg(sal),2) from emp group by ename having avg(sal) >100;


--sal in ... .

--sal not in

--sal = ,> ,< ,<>all , >any

--sal exists , not exists ,

select * from emp where sal=(select min(sal) from emp) and sal>100;


select * from emp where sal <>all (select min(sal) from emp);


--with 子句,將emp中表的數據定義為臨時表。

with e as(select * from emp) select * from e ;



--group by是對檢索結果的保留行進行單純分組,一般總愛和聚合函數一塊用例如AVG(),COUNT(),max(),main()等一塊用。

--sum() over (PARTITION BY ...) 是一個分析函數。 他執行的效果跟普通的sum ...group by ...不一樣,它計算組中表達式的累積和,而不是簡單的和。

select sum(sal) over(partition by empno order by sal) row_red,sal,empno from emp;--按照分組,一條一條累計和顯示。

select sum(sal) row_red from emp group by empno;

select * from emp for update;


--rollback , commit ,

--事物設置成自動提交。

set autocommit on;

--查看數據庫鎖定情況。

select session_id,oracle_username,process from v$locked_object where oracle_username='FASP_14';

--查詢v$session 數據字典

select sid,serial#,username,lockwait,status from v$session where sid in(152,394);

--解除死鎖

alter system kill session '111';






create table member(

mid number(5),

name varchar2(20) default '無名氏',

age number(3),

birthday date default sysdate,

note clob

);


--查看當前用戶下所有表。

select * from tab;

--查看表結構

select column_name,data_length,data_type from user_tab_cols where table_name='MEMBER';


insert into member(mid,name,age,birthday,note) values(1,'李興華',30,to_date('1978-6-8','yyyy-mm-dd'),'總公司活動提倡者');

commit;


--用現有表創建其他表。

create table myemp as select * from emp;

select column_name,data_length,data_type from user_tab_cols where table_name='MYEMP';



CREATE TABLE department

AS

SELECT d.deptno deptno,d.dname dname,d.loc loc,

COUNT(e.empno) count, SUM(e.sal + NVL(e.comm,0)) sum,

ROUND(AVG(e.sal + NVL(e.comm,0)),2) avg, MAX(e.sal) max, MIN(e.sal) min

FROM dept d,emp e

WHERE d.deptno=e.deptno(+)

GROUP BY d.deptno,d.dname,d.loc

ORDER BY d.deptno ;


create talbe department as

select m.mid,m.name,m.age,m.birthday,m.note,e.empno,e.ename,count(e.empno) from member m , emp e where d.deptno






--創建分區表。

--check 用於限制列中值的範圍。

create table t_test(

guid number(20) not null ,

indexid varchar2(20),

pk_id number(30) not null,

add_date_time Date,

sex varchar2(20),

mid varchar2(10),

constraint pk_t_test primary key (pk_id),

constraint ck_sex check (sex in('男','女')),

constraint fk_mid foreign key(mid) references menber(mid)on delete cascade --// on delete set null

)

--partition by list(add_date_time)

partition by range (add_date_time)(

partition t_Test_2013 values less than (to_date('2017-11-15 00:00:00','yyyy-mm-dd hh24:mi:ss')) tablespace efmis

);

--索引

create index ind_t_testid on t_test (indexid) tablespace efmis;

--分權限

grant select on t_test to sys;


--mid作為另一個表的外鍵,需要是這個表的主鍵。

create table menber(

mid varchar2(10),

constraint pk_mid primary key(mid)

);


--強制刪除父表。 解除主外鍵關系

drop table menber cascade constraint;



--查看全部的約束名稱、類型、約束設置對應的表名稱

select constraint_name,constraint_type,table_name from user_constraints where table_name='T_TEST';

--查詢表的信息。

select * from user_cons_columns;


--給表增加約束。

alter table member add constraint pk_mid primary key(mid);

alter table member add constratint ck_age check (age between 0 and 200);

alter table member modify (name varchar2(30) not null);



--得出一個行數和p#fasp_T_pupcs021表行數一樣的臨時列,每行的列值是1;

select 1 from p#fasp_T_pupcs021;


--查詢一棵樹, start with 第一個節點的guid 開始, connect by prior 條件是 guid = superguid 。 查詢這棵樹。 prior 是自頂向下的方式。

select * from p#FASP_T_PUBDEPARTMENT start with guid='90218F42D8491150E5D7892146E44FF9' connect by prior guid=superguid; --查詢出所有父節點為這個值的數。





















































--性能優化時用的。

--查看為數據庫分配的內存。

select * from v$sga;

select * from v$sgastat;


--xshell 中, 查看為數據庫分配多少cpu 。

[root@localhost ~]# su - oracle

[oracle@localhost ~]$ sqlplus zy_12c/[email protected]:1521/orcl

SQL> show parameters cpu


--1、查看ORACLE最大遊標數

SQL> show parameter open_cursors;

--2、查看當前打開的遊標數目

SQL> select count(*) from v$open_cursor;

--3、修改ORACLE最大遊標數

SQL> alter system set open_cursors=1000 scope=both;

--系統已更改。

SQL> show parameter open_cursors;















--數據庫性能瓶頸分析。

select * from v$parameter a where a.NAME in('shared_pool_size','log_buffer','db_cache_size','java_pool_size','larger_pool_size'); --SGA分配情況。

select component,current_size/1048576,min_size/1048576 from v$sga_dynamic_components; --查看SGA使用情況




SQL> show parameter pga ; ---查詢PGA總大小。

SQL> select round(sum(pga_alloc_mem)/1048576,1) from v$process; --已經消耗的PGA


--每個session都會占用一定的PGA資源,必要的時候,需要控制session的數量。

select count(*) from v$session;




--查詢數據庫表空間使用情況。

SELECT a.tablespace_name,

a.bytes total,

b.bytes used,

c.bytes free,

(b.bytes * 100) / a.bytes "% USED ",

(c.bytes * 100) / a.bytes "% FREE "

FROM sys.sm$ts_avail a, sys.sm$ts_used b, sys.sm$ts_free c

WHERE a.tablespace_name = b.tablespace_name

AND a.tablespace_name = c.tablespace_name;









數據庫sql--總結