PLSQL基本语法作者:gqk:1,什么是plsql: 是专⽤于Oracle服务器,在SQL基础之上,添加了⼀些过程化控制语句,叫PLSQL过程化包括有:类型定义,判断,循环,游标,异常或例外处理。
PLSQL强调过程2,Plsql语句块: PL/SQL程序都是以块(block)为基本单位,整个PL/SQL块分三部分:声明部分(⽤declare开头)执⾏部分(以 begin开头)其中执⾏部分是必须的,其他两个部分可选部分(以exception开头)结束:end--基本输出语句:BEGINdbms_output.put_line('hello,world');END;--基本输出语句BEGINdbms_output.put_line('hello,world');dbms_output.put_line(157);dbms_output.put_line(sysdate);dbms_output.put_line(true);--不能传⼊布尔值END;3,Plsql语句块分类: 匿名块:动态构造只执⾏⼀次(main)⼦程序:存储在数据库中的存储过程,函数及包等。
当在数据库建⽴好后可以在其他⼦程序中调⽤触发器:当数据库发⽣操作时,会触发⼀些事件,从⽽⾃动执⾏相应的程序4,Plsql中的变量类型:5,变量的使⽤: plsql中声明和执⾏部分要严格分开,在java中时先声明后写变量plsql中相反先声明在写数据类型: 变量在声明后没有赋值输出结果为空: 变量的声明和初始化:(boolean中只能声明不能输出)DECLAREi NUMBER(4) := 157;j NUMBER(6);c VARCHAR2(200) := 'HELLO,WORLD';d DATE := sysdate;b BOOLEAN := TRUE;BEGINj := 1000;--只能写在执⾏部分dbms_output.put_line('i=' || i);dbms_output.put_line('j=' || j);dbms_output.put_line('c=' || c);dbms_output.put_line('d=' || d);END;在声明快中对常量的声明: 变量名称【constant】 type 【not null】【:value】DECLAREc CONSTANT NUMBER(4) := 100;c2 NUMBER(4) NOT NULL := 101;BEGIN--c := 101; --常量不能重复赋值dbms_output.put_line('c=' || c);dbms_output.put_line('c2=' || c2);END; --空语句 NULL 执⾏语句中必须写东西DECLAREc CONSTANT NUMBER(4) := 100;c2 NUMBER(4) NOT NULL := 101;BEGINNULL;--空语句,作为占位符使⽤END; 6,PLSQL中使⽤sql: --更新100员⼯,⼯资增加1块钱 :(不能再执⾏块中直接输出select语句)声明变量:员⼯的编号声明变量:⼯资追加的钱数DECLAREv_empid BINARY_INTEGER := 100;v_money BINARY_INTEGER := 1;BEGINUPDATE employees SET salary=salary+v_moneyWHERE employee_id=v_empid;COMMIT;END;PLSQL中使⽤SQL语句的⼏种情况:DML或DCL语句:直接执⾏ 查询语句:SELECT...INTO 或者游标DDL语句:动态SQL执⾏ 7,SELECT...INTO...的使⽤:语法:SELECT 列1,列2,…… INTO 变量1,变量2,……--查询某个员⼯编号的姓名和⼯资:员⼯编号姓名⼯资 列和变量的顺序,个数必须保持⼀致(如果没有数据则会抛出异常,返回的结果超过⼀⾏也会有异常)DECLAREv_empid BINARY_INTEGER := 101;v_name VARCHAR2(50);v_salary NUMBER(8,2);BEGINSELECT last_name,salaryINTO v_name,v_salaryFROM employeesWHERE employee_id=v_empid;dbms_output.put_line(v_empid || ',' || v_name || ',' || v_salary);END;--查询某个员⼯编号的姓名,⼯资,⼊职⽇期,部门编号:(以上思路我们需要声明多个变量) DECLAREv_empid BINARY_INTEGER := 101;v_name VARCHAR2(50);v_salary NUMBER(8,2);v_hiredate DATE;v_deptid BINARY_INTEGER;BEGINSELECT last_name,salary,hire_date,department_idINTO v_name,v_salary,v_hiredate,v_deptidFROM employeesWHERE employee_id=v_empid;dbms_output.put_line(v_empid || ',' || v_name || ','|| v_salary || ',' || v_hiredate || ',' || v_deptid);END;java中处理多个数据我们可以封装为对象:plsql中可以声明记录类型:时把逻辑相关的数据作为⼀个单元存储起来:--记录类型record--查询某个员⼯编号的姓名,⼯资,⼊职⽇期,部门编号DECLARETYPE emp_record_type IS RECORD (empid BINARY_INTEGER := 102,ename VARCHAR2(50),salary NUMBER(8,2),hiredate DATE,deptid BINARY_INTEGER);e emp_record_type;BEGINSELECT employee_id,last_name,salary,hire_date,department_idINTO eFROM employeesWHERE employee_id=e.empid;dbms_output.put_line(e.empid);dbms_output.put_line(e.ename);dbms_output.put_line(e.salary);dbms_output.put_line(e.hiredate);dbms_output.put_line(e.deptid);END; --参照引⽤类型:参照已有的数据类型--参照引⽤类型--参照引⽤变量类型:变量名称%TYPE--参照引⽤表中的列类型:表名.列名%TYPE--参照引⽤表的记录类型:表名%ROWTYPE demo:DECLAREi NUMBER(4);j i%TYPE := 100;--参照i的类型k employees.employee_id%TYPE := 101;--参照员⼯表中员⼯编号的数据类型BEGINdbms_output.put_line('j=' || j);dbms_output.put_line('k=' || k);END;--查询某个员⼯编号的姓名,⼯资,⼊职⽇期,部门编号(参照类型)DECLARETYPE emp_record_type IS RECORD (empid employees.employee_id%TYPE := 102,ename st_name%TYPE,salary employees.salary%TYPE,hiredate employees.hire_date%TYPE,deptid employees.department_id%TYPE);e emp_record_type;BEGINSELECT employee_id,last_name,salary,hire_date,department_idINTO eFROM employeesWHERE employee_id=e.empid;dbms_output.put_line(e.empid);dbms_output.put_line(e.ename);dbms_output.put_line(e.salary);dbms_output.put_line(e.hiredate);dbms_output.put_line(e.deptid);END; --查询某个员⼯编号的姓名,⼯资,⼊职⽇期,部门编号(参照引⽤表的记录类型)DECLAREe employees%ROWTYPE;BEGINe.employee_id := 103;SELECT *INTO eFROM employeesWHERE employee_id=e.employee_id;dbms_output.put_line(e.employee_id);dbms_output.put_line(st_name);dbms_output.put_line(e.salary);dbms_output.put_line(to_char(e.hire_date,'yyyy-mm-dd'));dbms_output.put_line(e.department_id);END;--PLSQL表类型 /*TYPE ⾃定义类型名称 IS TABLE OF 元素类型INDEX BY BINARY_INTEGER;*/DECLARETYPE name_table_type IS TABLE OF VARCHAR2(50)INDEX BY BINARY_INTEGER;n name_table_type;BEGINn(-7) := 'tom';n(4) := 'jack';n(9) := 'rose';dbms_output.put_line('元素的长度:' || n.count);dbms_output.put_line(n(4));END; --表类型的常⽤属性DECLARETYPE name_table_type IS TABLE OF VARCHAR2(50)INDEX BY BINARY_INTEGER;n name_table_type;BEGIN--设置元素n(-5) := 'tom';n(3) := 'jack';n(17) := 'rose';n(23) := 'zhang';n(24) := 'wangwu';--删除指定下标的元素--n.delete(17);--删除⼀个范围的元素--n.delete(10,24);--删除所有元素--n.delete;--返回元素长度dbms_output.put_line('元素个数:' || n.count);--判断下标是否存在IF n.exists(17) THENdbms_output.put_line('true');ELSEdbms_output.put_line('false');END IF;--输出最⼩下标dbms_output.put_line(n.first);--输出最⼤下标dbms_output.put_line(st);--返回指定下标的元素dbms_output.put_line(n(3));--返回上⼀个或下⼀个存在的下标,如果没有,返回NULLdbms_output.put_line(n.next(10));dbms_output.put_line(n.prior(10));END;--BULK COLLECT INTO:把查询结果⼀次性赋给⼀个表类型的变量,下标⾃动从1开始递增 --查询所有的员⼯姓名,存储到⼀个表类型的变量中DECLARETYPE name_table_type IS TABLE OF VARCHAR2(50)INDEX BY BINARY_INTEGER;n name_table_type;BEGINSELECT last_name BULK COLLECT INTO nFROM employees;dbms_output.put_line('元素长度:' || n.count);dbms_output.put_line(n(2));END;--查询所有的员⼯信息,存储到⼀个表类型的变量中DECLARETYPE emp_table_type IS TABLE OF employees%ROWTYPEINDEX BY BINARY_INTEGER;e emp_table_type;BEGINSELECT * BULK COLLECT INTO eFROM employees;dbms_output.put_line('元素长度:' || e.count);dbms_output.put_line(e(2).last_name);dbms_output.put_line(e(3).salary);END; 8,DML语句返回值:--RETURNING语句:DML操作返回值赋给变量RETURN 列1,列2,... INTO 变量1,变量2,...--更新某个员⼯的⼯资,输出这个员⼯姓名,新⼯资DECLAREv_empid employees.employee_id%TYPE := 100;v_name st_name%TYPE;v_money employees.salary%TYPE := 1;v_salary employees.salary%TYPE;BEGINUPDATE employeesSET salary=salary+v_moneyWHERE employee_id=v_empidRETURNING last_name,salaryINTO v_name,v_salary;dbms_output.put_line('姓名:' || v_name);dbms_output.put_line('新⼯资:' || v_salary);END; --插⼊语句中使⽤RETURNING语句:DECLAREd dept%ROWTYPE;BEGININSERT INTO dept VALUES (50,'AA','BB')RETURN deptno,dname,loc INTO d;dbms_output.put_line(d.deptno);dbms_output.put_line(d.dname);dbms_output.put_line(d.loc);END; --删除语句中使⽤RETURNING语句DECLAREd dept%ROWTYPE;BEGINDELETE FROM deptWHERE deptno=50RETURN deptno,dname,loc INTO d;dbms_output.put_line(d.deptno);dbms_output.put_line(d.dname);dbms_output.put_line(d.loc);END; --DML操作返回多⾏数据--更新某个部门的员⼯的⼯资,返回被更新的员⼯姓名,新⼯资DECLARETYPE emp_record_type IS RECORD (ename st_name%TYPE,salary employees.salary%TYPE);TYPE emp_table_type IS TABLE OF emp_record_typeINDEX BY BINARY_INTEGER;e emp_table_type;BEGINUPDATE employeesSET salary=salary+1WHERE department_id=50RETURN last_name,salary BULK COLLECT INTO e; dbms_output.put_line('更新了' || e.count || '个员⼯'); dbms_output.put_line(e(1).ename || ',' || e(1).salary); END;。