conn / as sysdba;
select username from dba_users;
drop user robot cascade;
create user robot identified by robot;
select username FROM dba_users where username='ROBOT';
grant connect TO robot with admin option;
grant resource to robot;
select * from dba_role_privs where grantee='ROBOT';
create table student(
s_no varchar2(10),
s_name varchar2(50),
s_sex varchar2(4),
s_birthday date,
s_addr varchar2(100),
class_no varchar2(8)
);
desc student;
alter table student
add constraint 约束名
primary key(s_no); //主键约束
alter table 表名
modify 列名 not null;
alter table class
add constraint uni_class_name
unique(class_name);
alter table student
add constraint c_sex
check(s_sex in ('男','女'));
desc后发现
user_constraints是表约束的视图,描述的是约束类型(constraint_type)是什么,属于那个表(table_name),如果约束的类型为R(外键)的话,那么r_constraint_name放置的就是被引用主表中的主键约束名。
USER_CONS_COLUMNS是表约束字段的视图,说明表中的和约束相关的列参与了哪些约束。这些约束有主键约束,外键约束,索引约束。
也算是从表里看东西
constraint_name//约束名称
constraint_type //约束类型
column_name//属性名称
select constraint_name, constraint_type
from user_constraints
where table_name='STUDENT';
在没有添加约束的时候显示的是未选定行,添加了一些约束显示出来了
select a.column_name, a.table_name,a.constraint_name, b.constraint_type
from user_cons_columns a, user_constraints b
where a.table_name = b.table_name
and a.table_name='DEPARTMENT'
and a.constraint_name = b.constraint_name;
//上下作用相同,只不过改变了一下别名
select user_cons_columns.column_name, user_cons_columns.table_name,user_cons_columns.constraint_name, user_constraints.constraint_type
from user_cons_columns, user_constraints
where user_cons_columns.table_name = user_constraints.table_name
and user_cons_columns.table_name='DEPARTMENT'
and user_cons_columns.constraint_name = user_constraints.constraint_name;
alter table student
add constraint stu_fk_class
foreign key(class_no)
references class(class_no);
select * from role_sys_privs
where role in (select granted_role from user_role_privs)
and privilege ='CREATE SEQUENCE';
//创建一个叫add_title_no_plan_sequence的序列
create sequence add_title_no_plan_sequence
minvalue 1 maxvalue 99
//INCREMENT BY 1 -- 每次加几个
//START WITH 1 -- 从1开始计数
start with 1 increment by 1 cache 10;
select * from user_sequences;
在一个表中定义了行级的触发器,那当这个表中一行数据发生变化的时候,比如删除了一行记录,那触发器也会被自动执行了
//触发器语法
create [or replace] tigger 触发器名 触发时间 触发事件
on 表名
[for each row]
begin
pl/sql语句
end
触发器名:触发器对象的名称。由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
触发时间:指明触发器何时执行,该值可取:
before:表示在数据库动作之前触发器执行;
after:表示在数据库动作之后触发器执行。
触发事件:指明哪些数据库动作会触发此触发器:
insert:数据库插入会触发此触发器;
update:数据库修改会触发此触发器;
delete:数据库删除会触发此触发器。
表 名:数据库触发器所在的表。
for each row:对表的每一行触发器执行一次。如果没有这一选项,则只对整个表执行一次
//创建名字叫add_title_no_plan的触发器
create or replace trigger add_title_no_plan
//在插入title表之前
before insert on title
//执行一次,当title_no是null
for each row when (new.title_no is null)
begin
//查找 add_title_no_plan_sequence序列的下一个是多少
select add_title_no_plan_sequence.nextval
//放在title_no中
into :new.title_no from dual;
end add_teache_no_plan;
/
insert into department(dept_no, dept_name)
values('1','软件工程系');
insert into course(course_no, course_name)
values('300715XI12R6','ORACLE');
insert into class(class_no, class_name,dept_no)
values('17300907','软件17-1','1');
insert into student(s_no, s_name,s_sex,s_birthday,s_addr,class_no)
values('1730090714','屈一鸣','男',to_date('2000-12-1','yyyy-mm-dd'),'黑龙江','17300907');
insert into choice(s_no,course_no,score)
values('1730090714','300715XI12R6',70);
insert into title(title_name)
values('助教');
insert into teacher(t_name, t_sex, t_birthday,title_no, dept_no)
values('于谦','女',to_date('11-04-1978','dd-mm-yyyy'),1,'1');
insert into teaching(t_no, course_no)
values(1,'300715XI12R6');
DBA_ROLES 视图提供具有 NOLOGIN 属性的所有角色(组)的信息
create role m_robot;
select * from dba_roles;
grant create session;
select * from role_sys_privs
where role='M_ROBOT';
相乘
日期的比较
代码:
SELECT S_NO,S_NAME,S_BIRTHDAY
from STUDENT
WHERE S_BIRTHDAY>to_date('2000.8.5 ',‘yyyy.mm.dd’);
变换时间格式,进行的比较
代码:
SELECT S_NO,S_NAME,S_BIRTHDAY
from STUDENT
WHERE S_BIRTHDAY>to_date(‘2000.8.5 12:00:00’,‘yyyy.mm.dd hh24:mi:ss’);
实际上就是个别名,实现再不同数据库用户之间的交互
公有同义词一般由DBA创建,普通用户如果希望创建同义词,则需要CREATE PUBLIC SYNONYM这个系统权限。
作用:
运行CREATE SYNONYM, 时当前用户要有该权限
CREATE SYNONYM TEST FOR robot.表名
赋予权限,在system下
GRANT CREATE SYNONYM TO robot;
两个用户下,robot robot2用户下,robot已经有了现在创建robot2,并附权限
create user robot1 identified by robot1;
grant connect to robot with admin option;
grant connect to robot1 with admin option;
GRANT CREATE public SYNONYM TO robot; //创建同义词权限
create table class1(
class_no varchar2(8),
class_name varchar2(10),
dept_no varchar2(5)
);
insert into class1(class_no, class_name,dept_no)
values('17300907','软件17-1','1');
让robot获得robot1的查询权限
grant select on class1 to robot;
使用robot链接使用同义词
connect robot/robot;
create or replace public synonym robot_1 for robot1.class1;
select * from robot_1;
给同义词
CREATE PUBLIC SYNONYM syn_emp FOR SCOTT.emp;
查看同义词
SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME IN ( 'SYSN_TEST','PUBLIC_TEST');
select s_no as "学号", s_name as "姓名",
extract(year from sysdate)-extract(year from s_birthday) as "年龄"
from robot_students
where extract(year from sysdate)-extract(year from s_birthday) between 16 and 21
order by s_no, extract(year from sysdate)-extract(year from s_birthday);
索引的高度越高,访问索引需要读取的数据块数越多,效率越差
索引的关键在于通过一组排序后的索引键来取代默认的全表扫描检索方式,从而提高检索效率
//创建索引
create unique index index_students_id
on robot.students(s_no);
create or replace view students_view as select * from students;
grant select on students_view to robot1;
select students.s_name ,teachings.course_no,teachings.s_no from students join teachings on students.s_no = teachings.s_no ;
只要左边右边相等的全都查询了出来
select students.s_name ,teachings.course_no,teachings.s_no from students right join teachings on students.s_no = teachings.s_no ;
在使用聚合函数的情况下,加条件筛选时不能用where,要用having
案例,筛选出不止选了一门课的学生的学号,统计总数,求和
select s_no,count(*)
from teachings
group by s_no
having count(*)>1
统计s_no各分组下,每个分组下成绩的和是多少
select s_no,sum(score)
from teachings
group by s_no;
实现传入一个成绩然后传出这个成绩
create or replace function add_score(value in number)
return number as
remain_score teachings.score%type;
begin
select score into remain_score from teachings where score=value;
dbms_output.put_line('输出为:'||remain_score);
return (remain_score);
end;
/
select add_score('64') from dual;
实现传入一个成绩,在表中看是否有这个,有的话输出是否合格,不合格的话循环加5直到60分为止
create or replace function add_score(value in number)
return number as
remain_score teachings.score%type;
begin
select score into remain_score from teachings where score=value;
if (remain_score)>60 then
dbms_output.put_line('合格:'||remain_score);
else dbms_output.put_line('不合格');
end if;
while (remain_score<60) loop
remain_score:=remain_score+5;
dbms_output.put_line('加5:'||remain_score);
end loop;
return (remain_score);
end;
/
select add_score('50') from dual;
/*自定义函数传入数值*/
create or replace function add_score(value in number)
return number as
remain_score teachings.score%type;
/*自定义表*/
type teachings_tab_type is table of
teachings%rowtype index by binary_integer ;
teachings_tab teachings_tab_type;
begin
select score into remain_score from teachings where score=value;
/*把所有符号信息的放在teachings_tab这里边*/
select * into teachings_tab(999) from teachings where score=value;
/*把所有符号信息的放在teachings_tab的学号这里边*/
dbms_output.put_line('学生学号:'||teachings_tab(999).s_no);
/*判断结构*/
if (remain_score)>60 then
dbms_output.put_line('合格:'||remain_score);
else dbms_output.put_line('不合格');
end if;
/*循环结构*/
while (remain_score<60) loop
remain_score:=remain_score+5;
dbms_output.put_line('加5:'||remain_score);
end loop;
return (remain_score);
end;
/
select add_score('64') from dual;
改写了代码,主要作用是判断权限的问题.其中包含游标 动态sql
set serveroutput on;
DECLARE
user_name dba_users.username%type;
role_privs dba_role_privs%rowtype;
/*存储了ROBOT1所有权限*/
CURSOR role_privs_cur is
select * from dba_role_privs where grantee='ROBOT1';
BEGIN
/*打开游标*/
open role_privs_cur;
select dba_users.username into user_name from dba_users where dba_users.username='ROBOT1';
if(user_name='ROBOT1') then
dbms_output.put_line('用户名:'||user_name);
EXECUTE IMMEDIATE 'drop user robot1 cascade';
/*再建立表*/
EXECUTE IMMEDIATE 'create user robot1 identified by robot1';
select username into user_name FROM all_users where username='ROBOT1';
dbms_output.put_line('当前用户名:'||user_name);
EXECUTE IMMEDIATE 'grant connect,resource TO robot1 with admin option';
/*游标使用*/
loop
fetch role_privs_cur into role_privs;
exit when role_privs_cur%notfound;
DBMS_OUTPUT.put_line('权限:'||role_privs.GRANTED_ROLE);
END LOOP;
CLOSE role_privs_cur;
dbms_output.put_line('当前用户名:'||user_name);
end if;
END;
set serveroutput on;
DECLARE
user_name dba_users.username%type;
role_privs dba_role_privs%rowtype;
judge number:=0;
/*存储了ROBOT1所有权限*/
CURSOR role_privs_cur is
select * from dba_role_privs where grantee='ROBOT1';
BEGIN
/*打开游标*/
open role_privs_cur;
select dba_users.username into user_name from dba_users where dba_users.username='ROBOT1';
if(user_name='ROBOT1') then
dbms_output.put_line('用户名:'||user_name);
EXECUTE IMMEDIATE 'drop user robot1 cascade';
/*再建立表*/
EXECUTE IMMEDIATE 'create user robot1 identified by robot1';
select username into user_name FROM all_users where username='ROBOT1';
dbms_output.put_line('当前用户名:'||user_name);
EXECUTE IMMEDIATE 'grant connect,resource TO robot1 with admin option';
/*游标使用*/
loop
fetch role_privs_cur into role_privs;
exit when role_privs_cur%notfound;
DBMS_OUTPUT.put_line('权限:'||role_privs.GRANTED_ROLE);
if(role_privs.GRANTED_ROLE='CONNECT' or role_privs.GRANTED_ROLE='RESOURCE' ) then judge:=judge+1;
dbms_output.put_line('judge:'||judge);
if(judge=2) then
EXECUTE IMMEDIATE 'grant create view to robot1';
dbms_output.put_line('给robot1授权创建视图');
end if;
end if;
END LOOP;
CLOSE role_privs_cur;
dbms_output.put_line('当前用户名:'||user_name);
end if;
END;
过程和函数 ,使用了游标完成学生姓名的输出
create or replace procedure with_out_student_name
as
student robot.students%rowtype;
CURSOR student_cur is select * from robot.students ;
begin
open student_cur;
loop
fetch student_cur into student;
exit when student_cur%notfound;
DBMS_OUTPUT.put_line('学生姓名:'||student.s_name);
end loop;
CLOSE student_cur;
end;
execute with_out_student_name;
函数
create or replace function with_out_student_name_fc
RETURN VARCHAR2
is
student robot.students%rowtype;
CURSOR student_cur is select * from robot.students ;
begin
open student_cur;
loop
fetch student_cur into student;
exit when student_cur%notfound;
DBMS_OUTPUT.put_line('学生姓名:'||student.s_name);
end loop;
CLOSE student_cur;
RETURN '测试';
end;
SELECT with_out_student_name_fc FROM DUAL;
包的规范
create or replace package huangzhihang_package is
function with_out_student_name_fc
return VARCHAR2;
procedure with_out_student_name;
end huangzhihang_package;
包体
create or replace package body huangzhihang_package is
procedure with_out_student_name
as
student robot.students%rowtype;
CURSOR student_cur is select * from robot.students ;
begin
open student_cur;
loop
fetch student_cur into student;
exit when student_cur%notfound;
DBMS_OUTPUT.put_line('学生姓名:'||student.s_name);
end loop;
CLOSE student_cur;
end with_out_student_name;
function with_out_student_name_fc
return VARCHAR2
is
student robot.students%rowtype;
CURSOR student_cur is select * from robot.students ;
begin
open student_cur;
loop
fetch student_cur into student;
exit when student_cur%notfound;
DBMS_OUTPUT.put_line('学生姓名:'||student.s_name);
end loop;
CLOSE student_cur;
RETURN '测试';
end with_out_student_name_fc;
begin
Initialization_code;
end huangzhihang_package;
调用包中函数
exec huangzhihang_package.with_out_student_name_fc()
触发器
CREATE TABLE TB_A (ID NUMBER, COL VARCHAR2(20) NOT NULL);
CREATE TABLE TB_B (ID NUMBER, COL VARCHAR2(20) NOT NULL);
CREATE OR REPLACE VIEW V_AB
AS SELECT A.ID, A.COL COLA, B.COL COLB FROM TB_A A, TB_B B
WHERE A.ID = B.ID;
CREATE OR REPLACE TRIGGER trig_tb_a
instead OF insert ON V_AB
FOR EACH ROW
DECLARE
BEGIN
insert into TB_A values(:new.ID,:new.COLA);
insert into TB_B values(:new.ID,:new.COLB);
END;
insert into V_AB (ID, COLA, COLB) values (1,'cola','colb');
commit;