大型数据库 | Oracle 12 c | demo
数据库DDL、DCL、DML语句
- DDL,Data Definition Language,数据库定义语言
- 用于定义和管理数据库所有对象的语言
- 包括:CREATE,ALERT,DROP,TRUNCATE
- DML,Data Manipulation Language,数据库操作语言
- SQL中处理数据等操作
- 包括:SELECT,INSERT,UPDATE,DELETE,CALL,EXPLAIN PLAN,LOCK
- DCL,Data Control Language,数据库控制语言
- 用来授予或回收访问数据库和某种特权并控制数据库操纵事务发生的时间及效果,对数据库实行监控
- 包括:COMMIT,SAVEPOINT,ROLLBACK,SET TRANSACTION
https://blog.csdn.net/u011848397/article/details/88951979
5-PLSQL
数据类基本:
SET serveroutput ON --显示服务器输出信息 DECLARE SUBTYPE name IS CHAR(20); --定义了一个name类型 SUBTYPE MESSAGE IS VARCHAR2(100); --定义了一个MESSAGE类型 salutation name;--定义了一个name类型的变量 greetings MESSAGE;--定义了一个MESSAGE类型的变量 BEGIN salutation := 'Reader'; greetings := 'Welcome to the World of PL/SQL'; dbms_output.put_line('Hello ' || salutation || greetings); END;
数据类型type:
SET serveroutput ON DECLARE type emp_type IS record --声明record类型emp_type ( var_ename VARCHAR2(20), --定义字段/成员变量 var_job VARCHAR2(20), var_sal NUMBER ); empinfo emp_type; --定义变量 BEGIN SELECT ename, job, sal INTO empinfo FROM emp WHERE empno=7369; /*输出雇员信息*/ dbms_output.put_line('雇员 '||empinfo.var_ename||' 的职务是 '||empinfo.var_job|| ' 工资是 '||empinfo.var_sal); END;
数据类型%rowtype:
DECLARE rowVar_emp emp%rowtype; BEGIN SELECT * INTO rowVar_emp FROM emp WHERE empno=7369; dbms_output.put_line('雇员'||rowVar_emp.ename||'的编号是'||rowVar_emp.empno||', 职务是'||rowVar_emp.job); END;
DECLARE v_emp emp%rowtype; BEGIN select * into v_emp from emp where empno=&eno; --&表示接受输入 dbms_output.put_line('员工名字:'||v_emp.ename); dbms_output.put_line('员工工资:'||v_emp.sal); dbms_output.put_line('员工职位'||v_emp.job); END;
循环while:
SET serveroutput ON ; DECLARE numbers integer default 1; BEGIN LOOP dbms_output.put_line('hello'); EXIT WHEN numbers>3; numbers:=numbers+1; END LOOP; END;
SET serveroutput ON DECLARE sum_i INT:= 0; i INT:= 0; BEGIN WHILE i<=99 LOOP i:=i +1; sum_i:= sum_i+i; END LOOP; dbms_output.put_line('前100个自然数的和是:'||sum_i); END;
循环for:
SET serveroutput ON DECLARE sum_i INT:= 0; --定义整数变量,存储整数和 BEGIN FOR i IN reverse 1..100 LOOP IF mod(i,2)=0 THEN --判断是否为偶数 sum_i := sum_i+i; END IF; END LOOP; dbms_output.put_line('前100个自然数中偶数之和是:'||sum_i); END;
set serveroutput on declare sum_i int:= 0; begin for i in 1..100 loop if mod(i,2)=0 then sum_i:=sum_i+i; end if; end loop; dbms_output.put_line('前100个自然数中偶数之和是:'||sum_i); end;
set serveroutput on ; declare v_num int:= #--接受用户输入 v_pro int:=1; begin if v_num =0 then v_pro:=1; else for i in 1.. v_num loop v_pro:= v_pro*i; end loop; end if; dbms_output.put_line(v_pro); END;
循环goto:
set serveroutput on ; declare v_i number:=0; v_s number:=0; begin <<label_1>> v_i := v_i+1; if v_i<=100 then v_s:=v_s+v_i; goto label_1; end if; dbms_output.put_line(v_s); end;
异常处理:
DECLARE v_zero NUMBER:=0; v_result NUMBER; BEGIN v_result:=100/v_zero; EXCEPTION when ZERO_DIVIDE then dbms_output.put_line('除数为0'); END;
SET serveroutput ON ; DECLARE var_empno NUMBER; --定义变量,存储雇员编号 var_ename VARCHAR2(50); --定义变量,存储雇员名称 BEGIN SELECT empno,ename INTO var_empno,var_ename FROM emp WHERE deptno=10; IF sql%found THEN dbms_output.put_line('雇员编号'||var_empno||';雇员名称'||var_ename); END IF; EXCEPTION --捕获异常 WHEN too_many_rows THEN --若SELECT INTO语句的返回记录超过一行 dbms_output.put_line('返回记录超过一行'); WHEN no_data_found THEN --若SELECT INTO语句的返回记录为0行 dbms_output.put_line('无数据记录'); END; -- 用户为scott
SET serveroutput ON DECLARE e_overnum EXCEPTION; /*定义异常处理变量*/ v_num NUMBER; max_num NUMBER :=5; /*定义最大允许学生数变量*/ BEGIN SELECT COUNT(*) INTO v_num FROM emp; IF max_num<v_num THEN RAISE e_overnum; END IF; EXCEPTION WHEN e_overnum THEN dbms_output.put_line( '现在的员工数是:'|| v_num||' 而最大允数是' ||max_num ); END;
DECLARE null_exception EXCEPTION; --声明一个exception类型的异常变量 dept_row dept%rowtype; --声明rowtype类型的变量dept_row BEGIN dept_row.deptno := 66; --给部门编号变量赋值 dept_row.dname := '公关部'; /* 向dept表中插入一条记录*/ INSERT INTO dept VALUES ( dept_row.deptno, dept_row.dname, dept_row.loc ); IF dept_row.loc IS NULL THEN raise null_exception; END IF; EXCEPTION WHEN null_exception THEN --当raise引发的异常是null_exception时 dbms_output.put_line('loc字段的值不许为null'); --输出异常提示信息 ROLLBACK; END;
游标:
create table stu ( s_id number(3), s_xm varchar2(30) ); ALTER TABLE stu ADD CONSTRAINT pk_stu_id PRIMARY KEY(s_id); INSERT INTO stu (s_id, s_xm ) VALUES (1, 'Tom'); INSERT INTO stu (s_id, s_xm ) VALUES (2, 'Jerry' ); DECLARE CURSOR cur_stu IS SELECT * FROM stu; -- 步骤1: 声明游标 v_stu cur_stu%ROWTYPE; -- 定义一个变量存放游标指示的内容 BEGIN OPEN cur_stu; -- 步骤2: 打开游标 LOOP FETCH cur_stu INTO v_stu; -- 步骤3: 提取数据 EXIT WHEN cur_stu%notfound; dbms_output.put_line(v_stu.s_id ||' : '||v_stu.s_xm); END LOOP; CLOSE cur_stu;-- 步骤4: 关闭游标 EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || sqlerrm); dbms_output.put_line(dbms_utility.format_error_backtrace); END;
DECLARE v_name dept.dname%TYPE; v_loc dept.loc%TYPE; CURSOR c1(v_deptno NUMBER DEFAULT 2) is SELECT dname,loc FROM dept WHERE deptno<= v_deptno ; BEGIN OPEN c1; loop FETCH c1 INTO v_dname, v_loc; EXIT WHEN c1%NOTFOUND; DBMS_OUTPUT.PUT_LINE(v_dname||'---'||v_loc); END LOOP; close c1; exception when others then rollback; end;
set serveroutput on; DECLARE v_count NUMBER; BEGIN INSERT INTO stu (s_id, s_xm ) VALUES (3, 'Micky' ); IF SQL%FOUND THEN dbms_output.put_line('插入成功!'); END IF; UPDATE stu SET stu.s_xm= 'Donald' WHERE stu.s_id = 3; IF SQL%FOUND THEN dbms_output.put_line('更新成功!'); end if; DELETE FROM stu t WHERE t.s_id = 3; IF SQL%FOUND THEN dbms_output.put_line('删除成功!'); END IF; SELECT COUNT(*) INTO v_count FROM stu; IF SQL%FOUND THEN dbms_output.put_line('总记录为: '||v_count); END IF; IF sql%isopen THEN --对于隐式游标而言永远为FALSE dbms_output.put_line('隐式游标已打开'); ELSE dbms_output.put_line('隐式游标未打开'); END IF; EXCEPTION WHEN OTHERS THEN ROLLBACK; END;
SET serveroutput ON; DECLARE v_stu stu%ROWTYPE; TYPE cur_stu_type IS REF CURSOR RETURN stu%ROWTYPE; cur_stu cur_stu_type; BEGIN OPEN cur_stu FOR SELECT s_id, s_xm FROM stu; LOOP FETCH cur_stu INTO v_stu; --v_id, v_xm; EXIT WHEN cur_stu%NOTFOUND; dbms_output.put_line('序号:' || v_stu.s_id || chr(10) || '姓名:' || v_stu.s_xm); END LOOP; CLOSE cur_stu; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM); dbms_output.put_line(dbms_utility.format_error_backtrace); END;
存储过程:
--创建过程 CREATE OR REPLACE PROCEDURE EMP_COUNT AS V_TOTAL NUMBER(10); BEGIN SELECT COUNT(*) INTO V_TOTAL FROM EMP; DBMS_OUTPUT.PUT_LINE('雇员总人数为:'||V_TOTAL); END; --执行过程 SET serveroutput ON EXECUTE EMP_COUNT;
函数:
--创建函数 CREATE OR REPLACE FUNCTION get_sal(empname IN VARCHAR2) RETURN NUMBER IS Result NUMBER; BEGIN SELECT sal INTO Result FROM emp WHERE ename=empname; RETURN(Result); END get_sal; --调用函数 BEGIN DBMS_OUTPUT.PUT_LINE('Scott的薪水为:'||get_sal('SCOTT')); END;
触发器:
--创建触发器 CREATE OR REPLACE TRIGGER REM_DEPT AFTER INSERT ON DEPT FOR EACH ROW --对表的每一行触发器执行一次 BEGIN DBMS_OUTPUT.PUT_LINE('您向DEPT表中插入了一条新数据!'); END; --测试触发器 INSERT INTO DEPT (DEPTNO,DNAME,LOC ) VALUES (05,'HR','BEIJING' ); INSERT INTO DEPT (DEPTNO,DNAME,LOC ) VALUES (06,'MARKET','SHANGHAI' ); INSERT INTO DEPT (DEPTNO,DNAME,LOC ) VALUES (07,'COMPANY','LONDON' );
CREATE OR REPLACE TRIGGER my_trigger BEFORE INSERT OR UPDATE OR DELETE ON emp BEGIN IF(TO_CHAR (SYSDATE,'day') IN('星期六','星期日')) OR (TO_CHAR(SYSDATE,'HH24') NOT BETWEEN 8 AND 18) THEN RAISE_APPLICATION_ERROR(-20001,'不是上班时间,不能修改emp表'); END IF; END;
CREATE TABLE dept_log( OPERATOR VARCHAR2(20), TIME DATE ); Create Or Replace Trigger Tri_Dept Before Insert Or Delete Or Update On Dept Declare Var_Tag Varchar2(20); Begin If Inserting Then Var_Tag:='插入'; Elsif Updating Then Var_Tag:='修改'; Elsif Deleting Then Var_Tag:='删除'; End If; Insert Into Dept_Log Values (Var_Tag,Sysdate); End Tri_Dept; INSERT INTO dept VALUES(0,'HR','lao'); UPDATE dept SET loc='beijing' WHERE deptno = 0; DELETE FROM dept WHERE deptno = 0; select * from dept_log;
程序包:
CREATE [OR REPLACE] PACKAGE package_name IS 变量、常量及数据类型定义; 游标声明; 函数、过程声明 END [package_name]; 包体部分: CREATE [OR REPLACE] PACKAGE BODY package_name AS 游标、函数、过程的具体定义 END [package_name];
6-Oracle控制与安全
回滚事务savepoint:
--【示例1】HR模式中,演示使用保存点回滚事务。 SELECT * FROM dept; --4条记录 INSERT INTO dept VALUES (15, 'MARKET', 'BEIJING' ); SAVEPOINT sp01; INSERT INTO dept VALUES (25, 'HR', 'SHANGHAI' ); SAVEPOINT sp02; SELECT * FROM dept;--6条记录 DELETE FROM dept WHERE deptno = 15; SELECT * FROM dept; --5条记录 ROLLBACK TO sp02; SELECT * FROM dept; --6条记录 ROLLBACK TO sp01; SELECT * FROM dept; --5条记录 ROLLBACK; SELECT * FROM dept;--4条记录