一蔫磨、前言
假設(shè)有一張用戶表system_user纳寂,里面包含主鍵id主穗、姓名name、年齡age的列屬性毙芜,用戶足跡表system_user_history忽媒,里面包含主鍵id、外鍵user_id腋粥、足跡name晦雨。
二、DataManipulitionLanguage 數(shù)據(jù)操作語(yǔ)言
insert 新增操作
insert into system_user values (1,'wjx',25); -> 默認(rèn)全字段新增隘冲,按列屬性順序依次填入?yún)?shù)
insert into system_user (id,name) values (1,'wjx'); -> 顯式指定需要新增的列屬性
insert into system_user select id,name,age from system_user; -> 默認(rèn)全字段新增金赦,通過(guò)查詢語(yǔ)句賦值
insert into system_user (id,name) select id,name from system_user; -> 顯式指定需要新增的列屬性
update 更新操作
update system_user set name = 'wjx' where id = 1; -> 顯式指定需要更新的列屬性
delete 刪除操作
delete from system_user where id = 1; -> 顯式指定需要?jiǎng)h除的行
select 查詢操作
select 1 from dual; -> 虛擬表
select * from system_user; -> 真實(shí)表
full outer join / full join 全外連接,a表有x行对嚼,b表有y行,總共為x*y行
select * from system_user,system_user_history; -> 方式一
select * from system_user full outer join system_user_history; -> 方式二
left outer join / left join 左外連接绳慎,a表有x行纵竖,b表有y行漠烧,總共為大于等于x行
select * from system_user su,system_user_history suh where su.id = suh.user_id(+); -> 方式一
select * from system_user su left join system_user_history suh on su.id = suh.user_id; -> 方式二
right outer join / right join 右外連接,a表有x行靡砌,b表有y行已脓,總共為大于等于y行
select * from system_user su,system_user_history suh where su.id(+) = suh.user_id; -> 方式一
select * from system_user su right join system_user_history suh on su.id = suh.user_id; -> 方式二
inner join / join 內(nèi)連接,匹配兩個(gè)表都符合條件的行
select * from system_user su inner join system_user_history suh on su.id = suh.user_id;
group by 分組通殃,分組條件必須作為查詢列
select id from system_user group by id having id = 1
Merge 聯(lián)合操作度液,有則更新,無(wú)則新增
MERGE INTO
SYSTEM_USER_DETAIL SUD
USING
(SELECT * FROM SYSTEM_USER where AGE = 20) SU
ON
(SU.USER_ID = SUD.USER_ID)
WHEN MATCHED THEN
UPDATE SET SUD.USER_ID = SU.USER_ID
WHEN NOT MATCHED THEN
INSERT (SUD.USER_ID) VALUES (SU.USER_ID);
三画舌、運(yùn)算符號(hào)
alias 別名
select id alias_id from system_user; -> 空格
select id as alias_id from system_user; -> as
select id as "alias_id" from system_user; -> 雙引號(hào)
|| 連接符
select id || '-' || name || '-' || age from system_user; -> 以id-name-age格式輸出屬性值
in(set) 等于集合里某個(gè)元素即返回
select * from system_user where id in (1,2,3); -> 返回id為1的行
all(set) 大于/小于集合里的所有元素即返回
select * from system_user where id > all (0,2,4); -> 不返回行堕担,id為1的行不滿足大于2/4
any(set) 大于/小于集合里的某個(gè)元素即返回
select * from system_user where id > any(0,2,4); -> 返回id為1的行,id為1的行滿足大于0
distinct 去重
select distinct * from system_user;
= 等于曲聂、> 大于霹购、>= 大于等于、< 小于朋腋、<= 小于等于齐疙、!= 不等于、<> 不等于
select * from system_user where id = 1;
select * from system_user where id > 1;
select * from system_user where id >= 1;
select * from system_user where id < 1;
select * from system_user where id <= 1;
select * from system_user where id != 1;
select * from system_user where id <> 1;
between and 范圍閉區(qū)間
select * from system_user where id between 1 and 10; -> id在1到10的行
like 模糊查詢旭咽,%匹配任意多個(gè)字符贞奋,_匹配任意單個(gè)字符,escape 轉(zhuǎn)義關(guān)鍵字
select * from system_user where name like '%\_%' escape '\'; -> 匹配name帶有_的行
is null 判斷空
select * from system_user where age is null;
is not null 判斷非空
select * from system_user where age is not null;
and 并
select * from system_user where id = 1 and name = 'wjx';
or 或
select * from system_user where id = 2 or name = 'wjx';
not 非穷绵,搭配其它關(guān)鍵字使用
select * from system_user where id not between 1 and 10; -> id不在1到10范圍內(nèi)
select * from system_user where id not in (1,2,3); -> id不等于1/2/3
order by 排序轿塔,desc降序、asc升序
select * from system_user order by id asc,name desc; -> id升序请垛、name降序來(lái)排列行
case when then else end 多條件分支
select case id when 1 then 1 else 0 end from system_user;
decode 多條件分支
select decode(id,1,1,0) from system_user;
case id when 1 then 1 else 0 end;
savepoint 設(shè)置保存點(diǎn)
savepoint point_user;
rollback 回滾事務(wù)
rollback; -> 全回滾
rollback to savepoint point_a; -> 回滾到某個(gè)保存點(diǎn)
commit 提交事務(wù)
commit;
四催训、內(nèi)置函數(shù)
lower 全小寫
lower('A'); -> a
upper 全大寫
upper('a'); -> A
initcap 首字母大寫,空格隔開被認(rèn)為不同詞匯
initcap('hello world'); -> Hello World
concat 連接
concat('a','b'); -> ab
concat(concat('%', 'a'), '%'); -> %a%
substr 截取字符串
substr('abcdefg',1,5); -> abcde宗收,從第1個(gè)字符開始漫拭,截取5個(gè)
length 字符串長(zhǎng)度
length('abcde'); -> 5
regexp_replace 根據(jù)正則表達(dá)式替換字符串
regexp_replace(str, ',', ''); -> 字符串/被替換字符/替換字符
regexp_substr 根據(jù)正則表達(dá)式切割字符串
select regexp_substr(str, '[^,]+', 1, Level,'i') from dual
connect by Level <= LENGTH(str) - LENGTH(regexp_replace(str, ',', '')) + 1);
instr 返回字符串的下標(biāo),沒有則-1
instr('hello',o); -> 5
lpad 左對(duì)齊混稽,缺位補(bǔ)符號(hào)
lpad('hello',10,'*'); -> *****hello
rpad 右對(duì)齊采驻,缺位補(bǔ)符號(hào)
rpad('hello',10,'*'); -> hello*****
trim 清除左右兩側(cè),默認(rèn)是空格
trim(' hello '); -> hello
trim('h' from 'hello'); -> ello
replace 替換字符串
replace('abc','b','d'); -> adc
round 四舍五入
round(5.234,2); -> 5.23
round(2.345,2); -> 2.35
round(sysdate,'month'); -> 按月份四舍五入
trunc 截?cái)?/p>
trunc(2.345,2); -> 2.34
trunc(sysdate); -> 2022-01-01
mod 求余
mod(10,3); -> 1
sysdate 當(dāng)前日期
select sysdate from dual; -> 今天
select sysdate+1 from dual; -> 明天
select sysdate-1 form dual; -> 昨天
add_months 月份加減
add_months(sysdate,2); -> 兩個(gè)月后
add_months(sysdate,-2); -> 兩個(gè)月前
last_day 月份最后一天
last_day(sysdate); -> 當(dāng)月最后一天
next_day 下一個(gè)同等日期
next_day(sysdate,'星期五'); -> 下個(gè)星期五日期
to_date 字符串轉(zhuǎn)日期
to_date('2022-01-01','yyyy-mm-dd');
to_char 其它類型轉(zhuǎn)字符串
to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'); -> 日期轉(zhuǎn)字符串
to_char(1234567.89,'999,999,999.99'); -> 1,234,567.89 -> 9代表不補(bǔ)零
to_char(1234567.89,'000,000,000.99'); -> 001,234,567.89 -> 0代表補(bǔ)零
to_number 字符串轉(zhuǎn)數(shù)字
to_number('1,234','9,999'); -> 1234
nvl 輸出非空
nvl(null,0); -> 0
nvl(1,0); -> 1
nvl2 非空輸出表達(dá)式一匈勋,空輸出表達(dá)式二
nvl2(null,0,1); -> 1
nvl2(2,0,1); -> 0
coalesce 輸出非空礼旅,可變長(zhǎng)度參數(shù)
coalesce(null,0,1); -> 0
coalesce(null,null,1); -> 1
nullif 相等輸出空
nullif(1,1); -> null
nullif(1,2); -> 1
avg 平均值
select avg(id) from system_user group by id;
count 統(tǒng)計(jì)非空行數(shù)
select count(*) from system_user;
max 最大值
select max(id) from system_user group by id;
min 最小值
select min(id) from system_user group by id;
stddev 標(biāo)準(zhǔn)差
select stddev(id) from system_user group by id;
sum 合計(jì)
select sum(id) from system_user group by id;
listagg 分組拼接
select user_id, listagg(name,',') within group (order by user_id) name
from system_user_history group by user_id; -> 將用戶所有足跡用,串起來(lái)
CHR & ASCII 特殊字符轉(zhuǎn)義
select ascii('''') from dual; -> 39
select chr(39) from dual; -> '
ASCIISTR & UNISTR 編碼互轉(zhuǎn)解決亂碼
select ASCIISTR('我') from dual;
select UNISTR('\6211') from dual;
五、約束
not null 非空約束
alter table system_user modify id constraint suid not null; -> 添加名為suid的約束
unique 唯一約束
alter table system_user add constraint suid unique(id); -> 添加名為suid的約束
primary key 唯一非空約束
alter table system_user add constraint suid primary key(id); -> 添加名為suid的約束
foreign key 外鍵
alter table system_user_history add constraint suhuserid foreign key(user_id)
references system_user(id) -> 關(guān)聯(lián)外表
on delete cascade / on delete set null -> 外表刪除時(shí)執(zhí)行操作(級(jí)聯(lián)刪除/級(jí)聯(lián)置空)
check 檢查
alter table system_user add constraint suage check(age between 18 and 35);
drop 刪除約束
alter table system_user drop constraint suid;
disable 約束無(wú)效化
alter table system_user disable constraint suid;
enable 約束有效化
alter table system_user enable constraint suid;
modify 約束不能修改洽洁,只能刪除再添加
alter table system_user modify(id number(10,0) constraint suid not null);
六痘系、DataDefinitionLanguage 數(shù)據(jù)定義語(yǔ)言
創(chuàng)建表
create table system_user( -> 列級(jí)約束
id number(10) constraint id primary key,
name varchar2(20) constraint name unique,
age number(10) constraint age not null
);
create table system_user( -> 表級(jí)約束
id number(10),
name varchar2(20),
age number(10),
constraint id primary key(id),
constraint name unique(name),
constraint age not null(age),
constraint range check(age>0 and age<100)
);
create table system_people as select * from system_user; -> 復(fù)制現(xiàn)有的表和數(shù)據(jù)
create table system_people as select * from system_user where 1=2; -> 復(fù)制空表
修改表
alter table system_user add(email varchar2(20)); -> 添加列
alter table system_user modify(age number(15) default 0); -> 修改列
alter table system_user drop column email; -> 刪除列
alter table system_user rename column name to username; -> 修改列名
刪除表
drop table system_user;
清空表
truncate table system_user;
重命名表
rename system_user to system_people;
創(chuàng)建索引
create index index_name on system_user(name);
刪除索引
drop index index_name;
創(chuàng)建序列
create sequence seq_system_user -> 序列名
increment by 1 -> 自增量
start with 1 -> 起始值
maxvalue 99999999 -> 最大值
cycle/nocycle -> 是否循環(huán)
order/noorder -> 是否有序
cache 20/nocache -> 是否緩存
修改序列
alter sequence seq_system_user order cycle; -> 修改多個(gè)屬性
刪除序列
drop sequence seq_system_user;
使用序列作為自增主鍵
select seq_system_user.nextval from dual; -> 下一個(gè)值
select seq_system_user.currval from dual; -> 當(dāng)前值
創(chuàng)建視圖
create view view_system_user as select id,name from system_user with read only; -> 添加只讀權(quán)限
create or replace view view_system_user as select * from system_user; -> 修改視圖
更新視圖
update view_system_user set age = 25 where id = 1;
delete from view_system_user where id = 1;
刪除視圖
drop view view_system_user;
兼容語(yǔ)法
declare
num number;
begin
select count(1) into num from user_tables where table_name = upper('system_user');
if num > 0 then
execute immediate 'drop table system_user';
end if;
select count(1) into num from user_ind_columns where index_name = upper('system_user_index');
if num > 0 then
execute immediate 'drop index system_user_index';
end if;
select count(1) into num from user_sequences where sequence_name= upper('system_user_index_seq');
if num > 0 then
execute immediate 'drop sequence system_user_index_seq';
end if;
select count(1) into num from user_tab_cols where table_name = upper('system_user') and column_name = upper('user_id');
if num > 0 then
execute immediate 'alter table system_user drop column user_id';
end if;
select count(1) into num from user_constraints where table_name = upper('system_user') and constraint_name = upper('user_id');
if num > 0 then
execute immediate 'alter table system_usermodify user_id null';
end if;
end;
七、存儲(chǔ)過(guò)程
create 創(chuàng)建函數(shù)
CREATE OR REPLACE PACKAGE -> 定義包名
CUSTOM_PACKAGE IS -> 包內(nèi)可以定義多個(gè)函數(shù)
PROCEDURE CUSTOM_PROCEDURE_1(PARAM IN VARCHAR2);
PROCEDURE CUSTOM_PROCEDURE_2(PARAM OUT VARCHAR2);
END CUSTOM_PACKAGE;
CREATE OR REPLACE PACKAGE BODY -> 定義包體
CUSTOM_PACKAGE IS
PROCEDURE CUSTOM_PROCEDURE_1(PARAM IN VARCHAR2) AS ... END;
PROCEDURE CUSTOM_PROCEDURE_2(PARAM OUT VARCHAR2) AS ... END;
END CUSTOM_PACKAGE;
BEGIN -> 調(diào)用函數(shù)
CUSTOM_PACKAGE.CUSTOM_PROCEDURE_1('');
END;
declare 定義變量
declare
name varchar2(20) := null;
age student.age%type := null; -> 動(dòng)態(tài)定義類型
row student&rowtype := null; -> 動(dòng)態(tài)定義整行
into 賦值
begin
select student.name,student.age into name,age from student where id = 1;
exception
when not found then
end;
cursor 游標(biāo)饿自,存儲(chǔ)臨時(shí)數(shù)據(jù)
cursor student_cursor is select * from student; -> 定義游標(biāo)
student_id student.id%type; -> 定義游標(biāo)屬性
student_name student.name%type; -> 定義游標(biāo)屬性
open student_cursor; -> 打開游標(biāo)
loop
fetch student_cursor into student_id, student_name; -> 讀取數(shù)據(jù)
exit when student_cursor%NOTFOUND; -> 無(wú)數(shù)據(jù)時(shí)退出
end loop;
close student_cursor; -> 關(guān)閉游標(biāo)
type student_type is record ( -> 定義游標(biāo)類別
student_id student.id%type,
student_name student.name%type
);
type student_cursor is ref cursor return student_type; -> 定義游標(biāo)返回類別
exception 異常汰翠,捕獲程序錯(cuò)誤
declare custom_exception exception; -> 自定義異常
begin
raise custom_exception; -> 手動(dòng)拋出異常
commit;
exception
when NO_DATA_FOUND then
dbms_output.put_line(sqlcode); -> 編號(hào)
dbms_output.put_line(sqlerrm); -> 描述信息
dbms_output.put_line(dbms_utility.format_error_backtrace); -> 發(fā)生位置
dbms_output.put_line(dbms_utility.format_call_stack); -> 發(fā)生棧
when others then -> 捕獲并處理
rollback;
end;
dbms_output 輸出日志
set serveroutput on; -> 開啟輸出服務(wù)
set serveroutput off; -> 關(guān)閉輸出服務(wù)
dbms_output.put('不換行');
dbms_output.new_line; -> 換行
dbms_output.put_line('自動(dòng)換行');
dbms_metadata 獲取創(chuàng)建語(yǔ)句
select dbms_metadata.get_ddl('TABLE','TABLE_NAME','TABLE_SCHEMA') from dual; -> 參數(shù)2/3動(dòng)態(tài)變更
if (boolean) then (logic) elsif (boolean) then (logic) else (logic) end if; 條件表達(dá)式
if name = 'wjx' then update student set age = '20' where id = 1;
elsif name = 'xjw' then update student set age = '21' where id = 2;
else update student set age = '21' where id = 3;
end if;
goto 循環(huán)
declare x :=10;
begin
<<circle_point>>
if x>0 then
x := x -1;
goto circle_point;
else
dbms_output.put_line('循環(huán)結(jié)束');
end if;
for (var) in (set) loop (logic) end loop; 循環(huán)
begin
for student_list in select * from student loop
if student_list.name = 'wjx' then
update student set age = '20' where id = 1;
else end if;
end loop;
end;
begin
for i in 1..100 loop
dbms_output.put_line(i); -> 打印1-100
end loop;
end;
while (boolean) loop (logic) end loop; 循環(huán)
declare x := 0;
begin
while x < 10 loop
x := x+1;
end loop;
end;
loop (logic) exit when (boolean) end loop; 循環(huán)
declare x:= 0;
begin
loop x := x + 1;
exit when x > 10;
end loop;
end;
八龄坪、權(quán)限
為用戶授予權(quán)限
create public synonym db_name.table_name for table_name; -> 同義詞
grant select on db_name.table_name to oracle_username; -> 查詢
grant update on db_name.table_name to oracle_username; -> 更新
grant delete on db_name.table_name to oracle_username; -> 刪除
grant insert ondb_name.table_name to oracle_username; -> 新增
查詢用戶表權(quán)限
select * from dba_tab_privs
where 1= 1
and table_name = 'table_name'
and grantee = 'oracle_username'
and privilege in ('SELECT','UPDATE','DELETE','INSERT');
九、觸發(fā)器
觸發(fā)類型(12種)复唤,包含新增健田、修改、刪除
類型 | 描述 |
---|---|
BEFORE INSERT | 新增前佛纫,表級(jí) |
BEFORE INSERT FOR EACH ROW | 新增前妓局,行級(jí) |
AFTER INSERT | 新增后,表級(jí) |
AFTER INSERT FOR EACH ROW | 新增前呈宇,行級(jí) |
BEFORE UPDATE | 更新前好爬,表級(jí) |
BEFORE UPDATE FOR EACH ROW | 更新前,行級(jí) |
AFTER UPDATE | 更新后攒盈,表級(jí) |
AFTER UPDATE FOR EACH ROW | 更新后抵拘,行級(jí) |
BEFORE DELETE | 刪除前,表級(jí) |
BEFORE DELETE FOR EACH ROW | 刪除前型豁,行級(jí) |
AFTER DELETE | 刪除后僵蛛,表級(jí) |
AFTER DELETE FOR EACH ROW | 刪除后,行級(jí) |
:NEW.column | 新值迎变,INSERT/UPDATE有充尉,DELETE無(wú) |
:OLD.column | 舊值,UPDATE/DELETE有衣形,INSERT無(wú) |
OR驼侠,AFTER INSERT OR DELETE ON system_user | 設(shè)立在某幾種操作上觸發(fā) |
OF,AFTER UPDATE OF name ON system_user | 設(shè)立在某個(gè)字段上觸發(fā) |
Insert 時(shí)機(jī)
CREATE OR REPLACE TRIGGER SYSTEM_USER_A_I
AFTER INSERT
ON system_user
FOR EACH ROW
BEGIN
INSERT INTO system_user_log(ID, DATE, TYPE, USER_ID, USER_NAME, USER_AGE)
VALUES(SEQ_SYSTEM_USER_LOG.nextval, sysdate, 'INSERT', :NEW.id, :NEW.name, :NEW.age);
END;
Update 時(shí)機(jī)
CREATE OR REPLACE TRIGGER SYSTEM_USER_B_U
BEFORE UPDATE
ON system_user
FOR EACH ROW
BEGIN
INSERT INTO system_user_log(ID, DATE, TYPE, USER_ID, USER_NAME, USER_AGE)
VALUES(SEQ_SYSTEM_USER_LOG.nextval, sysdate, 'UPDATE', :OLD.id, :OLD.name, :OLD.age);
END;
CREATE OR REPLACE TRIGGER SYSTEM_USER_A_U
AFTER UPDATE
ON system_user
FOR EACH ROW
BEGIN
INSERT INTO system_user_log(ID, DATE, TYPE, USER_ID, USER_NAME, USER_AGE)
VALUES(SEQ_SYSTEM_USER_LOG.nextval, sysdate, 'UPDATE', :NEW.id, :NEW.name, :NEW.age);
END;
Delete 時(shí)機(jī)
CREATE OR REPLACE TRIGGER SYSTEM_USER_B_D
BEFORE DELETE
ON system_user
FOR EACH ROW
BEGIN
INSERT INTO system_user_log(ID, DATE, TYPE, USER_ID, USER_NAME, USER_AGE)
VALUES(SEQ_SYSTEM_USER_LOG.nextval, sysdate, 'DELETE', :OLD.id, :OLD.name, :OLD.age);
END;
十谆吴、JDBC連接
SQL
String sql = "select id from system_user where name = ?";
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
connection = super.dataSource.getConnection();
ps = connection.prepareStatement(sql);
ps.setString(1, "wjx"); -> 入?yún)?
rs = ps.executeQuery();
while (rs.next()) {
String id = rs.getString("id"); -> 出參
}
} finally {
if(rs != null) rs.close();
if(ps != null) ps.close();
if(connection != null) connection.close();
}
PLSQL
CREATE OR REPLACE PROCEDURE SCHEMA.GET_NEW_USER(in_date IN DATE DEFAULT sysdate, out_user_list OUT SYS_REFCURSOR) IS
-- DECLARE
-- in_date DATE := to_date('2023-01-01', 'yyyy-mm-dd');
BEGIN
OPEN out_user_list FOR
SELECT su.*
FROM system_user su
WHERE create_date > TRUNC(in_date - 7);
END;
/
String sql = "{call SCHEMA.GET_NEW_USER(?, ?)}";
Connection connection = null;
CallableStatement cs = null;
ResultSet rs = null;
try {
connection = super.dataSource.getConnection();
cs = connection.prepareCall(sql);
cs.setString(1, new java.sql.Date());
cs.registerOutParameter(2, -10);
cs.execute();
rs = cs.getObject(2, ResultSet.class);
while (rs.next()) {
String id = rs.getString("id"); -> 出參
}
} finally {
if(rs != null) rs.close();
if(ps != null) ps.close();
if(connection != null) connection.close();
}
FUNTION
create or replace function f_no_param return varchar2 is
begin
return 'hello, no param';
end;
create or replace function f_have_param(id in integer, name out varchar2) return varchar2 is
begin
name := 'wjx';
return 'hello, have param';
end;
String noParamSql = "{? = call f_no_param}";
String haveParamSql = "{? = call f_have_param(?,?)}";
Connection connection = null;
CallableStatement cs1 = null;
CallableStatement cs2 = null;
try {
connection = super.dataSource.getConnection();
cs1 = connection.prepareCall(noParamSql);
cs1.registerOutParameter(1, Types.VARCHAR); -> 返回值是出參
cs1.execute();
String noParamVarchar = cs1.getString(1);
cs2 = connection.prepareCall(haveParamSql);
cs2.registerOutParameter(1, Types.VARCHAR); -> 返回值是出參
cs2.setInt(2, 10); -> id是入?yún)? cs2.registerOutParameter(3, Types.VARCHAR); -> name是出參
cs2.execute();
String haveParamVarchar = cs1.getString(1);
String haveParamName = cs1.getString(3);
} finally {
if(rs != null) rs.close();
if(ps != null) ps.close();
if(connection != null) connection.close();
}
SQL 執(zhí)行計(jì)劃
explain plan for select * from system_user where id = 1; -> 生成執(zhí)行計(jì)劃
select * from table(dbms_xplan.display); -> 查詢執(zhí)行計(jì)劃