1、背景
此处简单的记录一下在 oracle中如何使用plsql语法,记录一些简单的例子,防止以后忘记。
2、变量的声明
| declare |
| |
| v_name varchar2(20); |
| |
| v_man_sex number; |
| |
| v_sex student.sex%TYPE; |
| |
| v_row student%rowtype; |
| |
| v_addr varchar2(100) := '湖北省'; |
| |
| v_date date := sysdate; |
| |
| |
| type STUDENT_INFO is record |
| ( |
| student_id student.student_id%TYPE, |
| student_name student.student_name%TYPE |
| ); |
| |
| type nested_student_info is table of STUDENT_INFO; |
| |
| student_list nested_student_info; |
| |
| begin |
| |
| v_name := '直接赋值'; |
| v_date := to_date('2023-12-12', 'yyyy-mm-dd'); |
| |
| select count(*) into v_man_sex from student where sex = 1; |
| |
| select student_name,sex into v_name,v_sex from student where student_id = 'S003'; |
| |
| select student_id,student_name,sex,CREATE_TIME into v_row from student where student_id = 'S002'; |
| |
| DBMS_OUTPUT.PUT_LINE('日期:' || v_date || '姓名:' || v_name || ',' || v_row.STUDENT_NAME || ' 男生人数:' || v_man_sex || ' 地址:' || v_addr ); |
| end; |
| |
3、if 判断
统计总共有多少个学生,并进行if判断。
| declare |
| |
| v_student_count number; |
| begin |
| |
| select count(*) into v_student_count from student; |
| |
| |
| |
| if v_student_count > 3 then |
| DBMS_OUTPUT.PUT_LINE('当前学生数为: [' || v_student_count || ']>3'); |
| elsif v_student_count >=2 then |
| DBMS_OUTPUT.PUT_LINE('当前学生数为: [' || v_student_count || '] in [2,3]'); |
| else |
| DBMS_OUTPUT.PUT_LINE('当前学生数为: [' || v_student_count || ']<2'); |
| end if; |
| end; |
4、case
| |
| declare |
| |
| v_student_count number; |
| begin |
| |
| select count(*) into v_student_count from student; |
| |
| |
| |
| case when v_student_count > 3 then |
| DBMS_OUTPUT.PUT_LINE('当前学生数为: [' || v_student_count || ']>3'); |
| when v_student_count >=2 then |
| DBMS_OUTPUT.PUT_LINE('当前学生数为: [' || v_student_count || '] in [2,3]'); |
| else |
| DBMS_OUTPUT.PUT_LINE('当前学生数为: [' || v_student_count || ']<2'); |
| end case; |
| end; |
5、循环
输出1到100
1、loop 循环
| declare |
| |
| v_count number := 1; |
| begin |
| loop |
| |
| exit when v_count > 100; |
| DBMS_OUTPUT.PUT_LINE('当前 count = ' || v_count); |
| |
| v_count := v_count + 1; |
| end loop; |
| end; |
2、while 循环
| |
| declare |
| |
| v_count number := 1; |
| begin |
| while v_count <= 100 loop |
| DBMS_OUTPUT.PUT_LINE('当前 count = ' || v_count); |
| |
| v_count := v_count + 1; |
| end loop; |
| end; |
3、for循环
| |
| declare |
| |
| v_count number; |
| begin |
| for v_count in 1..100 loop |
| DBMS_OUTPUT.PUT_LINE('当前 count = ' || v_count); |
| end loop; |
| end; |
6、游标
1、无参数的游标
| |
| declare |
| |
| cursor cur_student is select student_id,student_name,sex from student; |
| |
| row_cur_student cur_student%rowtype; |
| begin |
| |
| open cur_student; |
| |
| |
| loop |
| |
| fetch cur_student into row_cur_student; |
| |
| exit when cur_student%NOTFOUND; |
| |
| DBMS_OUTPUT.PUT_LINE('studentId:' || row_cur_student.STUDENT_ID || ' studentName:' || row_cur_student.STUDENT_NAME); |
| |
| end loop; |
| |
| |
| close cur_student; |
| end; |
2、带参数的游标
| declare |
| |
| cursor cur_student(v_student_id student.student_id%TYPE) is |
| select student_id,student_name,sex from student where student_id = v_student_id; |
| |
| row_cur_student cur_student%rowtype; |
| |
| v_query_student_id student.student_id%TYPE; |
| begin |
| |
| |
| |
| |
| select 'S001' into v_query_student_id from dual; |
| open cur_student(v_query_student_id); |
| |
| |
| loop |
| |
| fetch cur_student into row_cur_student; |
| |
| exit when cur_student%NOTFOUND; |
| |
| DBMS_OUTPUT.PUT_LINE('studentId:' || row_cur_student.STUDENT_ID || ' studentName:' || row_cur_student.STUDENT_NAME); |
| |
| end loop; |
| |
| |
| close cur_student; |
| end; |
| |
7、执行ddl dml
需要放到 execute immediate
中执行,否则会报错。
| declare |
| v_table_name varchar2(20) := 'student_bak'; |
| |
| v_sql varchar2(100); |
| begin |
| execute immediate 'create table student_bak as select * from student'; |
| execute immediate 'alter table student_bak add new_cloumn varchar2(20)'; |
| |
| |
| v_sql := 'drop table ' || v_table_name; |
| execute immediate v_sql; |
| |
| end; |
8、存储过程
1、无参数的存储过程
| |
| create or replace procedure sp_print_all_student |
| is |
| |
| cursor c_all_student is select student_id,student_name from student; |
| |
| row_student c_all_student%rowtype; |
| begin |
| |
| for row_student in c_all_student loop |
| DBMS_OUTPUT.PUT_LINE(row_student.STUDENT_ID || ' ' || row_student.STUDENT_NAME); |
| end loop; |
| end; |
| |
| begin |
| SP_PRINT_ALL_STUDENT(); |
| end; |
2、有输入输出参数的存储过程
| |
| create or replace procedure sp_find_student( i_student_id in student.student_id%TYPE, |
| o_student_name out student.student_name%TYPE) |
| IS |
| |
| v_student_id varchar2(64) := i_student_id; |
| begin |
| DBMS_OUTPUT.PUT_LINE('v_student_id:' || v_student_id); |
| |
| select student_name into o_student_name from student where student_id = i_student_id; |
| end; |
| |
| declare |
| |
| output_student_name student.student_name%TYPE; |
| begin |
| sp_find_student('S001', output_student_name); |
| |
| DBMS_OUTPUT.PUT_LINE(output_student_name); |
| end; |
3、merge into 的使用
存在更新,不存在插入。
| create or replace procedure sp_merge_into(i_student_id in varchar2) |
| IS |
| begin |
| |
| merge into STUDENT_BAK t |
| using (select * from student where student_id = i_student_id) s |
| on ( t.student_id = s.student_id ) |
| when matched then update set |
| |
| t.STUDENT_NAME = s.STUDENT_NAME, |
| t.SEX = s.SEX, |
| t.CREATE_TIME = s.CREATE_TIME |
| when not matched then insert(student_id, student_name, create_time) values ( |
| s.STUDENT_ID, |
| s.STUDENT_NAME, |
| s.CREATE_TIME |
| ); |
| commit ; |
| end; |
| |
4、测试异常
| create or replace procedure sp_error |
| IS |
| v_num number; |
| begin |
| DBMS_OUTPUT.PUT_LINE('测试异常'); |
| |
| |
| v_num := 1 / 0; |
| |
| exception |
| when too_many_rows then |
| dbms_output.put_line('返回值多于1行'); |
| when others then |
| |
| rollback; |
| dbms_output.put_line('错误码:' ||sqlcode); |
| dbms_output.put_line('异常信息:' || substr(sqlerrm, 1, 512)); |
| end; |
| |
| begin |
| sp_error(); |
| end; |
5、bulk into & record
1、select into 中使用 bulk into & record
| create or replace procedure sp_bulk_collect_01 |
| IS |
| |
| type STUDENT_INFO is record |
| ( |
| student_id student.student_id%TYPE, |
| student_name student.student_name%TYPE |
| ); |
| |
| |
| type nested_student_info is table of STUDENT_INFO; |
| |
| student_list nested_student_info; |
| begin |
| |
| select student_id,student_name bulk collect into student_list from student; |
| |
| |
| for i in student_list.first .. student_list.last loop |
| DBMS_OUTPUT.PUT_LINE('studentId:' || student_list(i).student_id || ' studentName:' || student_list(i).student_name); |
| end loop; |
| end; |
| |
| begin |
| sp_bulk_collect_01; |
| end; |
2、fetch into 中使用 bulk into & forall
| |
| |
| create or replace procedure sp_bulk_collect_02 |
| IS |
| |
| cursor cur_student is select student_id,student_name,sex,create_time from student; |
| |
| type nested_student_info is table of cur_student%rowtype; |
| |
| student_list nested_student_info; |
| begin |
| |
| open cur_student; |
| loop |
| |
| fetch cur_student bulk collect into student_list limit 2; |
| |
| |
| exit when student_list.count = 0; |
| |
| |
| for i in student_list.first .. student_list.last loop |
| DBMS_OUTPUT.PUT_LINE('studentId:' || student_list(i).student_id || ' studentName:' || student_list(i).student_name); |
| end loop; |
| |
| |
| forall i in student_list.first .. student_list.last |
| update student set student_name = student_list(i).STUDENT_NAME || '_update' where student_id = student_list(i).STUDENT_ID; |
| commit ; |
| end loop; |
| |
| |
| close cur_student; |
| end; |
| |
| begin |
| sp_bulk_collect_02; |
| end; |
6、接收数组参数
| |
| create or replace type StudentIdList as varray(4) of varchar2(20); |
| |
| |
| create or replace procedure sp_param_list(studentIdList in StudentIdList) |
| is |
| begin |
| for i in 1..studentIdList.COUNT loop |
| DBMS_OUTPUT.PUT_LINE('studentId:' || studentIdList(i)); |
| end loop; |
| end; |
| declare |
| begin |
| sp_param_list(STUDENTIDLIST('d','c','S001','S0021222222222233')); |
| end; |
7、接收数组对象,并将数组对象转换成表使用
| |
| create or replace type StudentInfo is object( |
| studentId varchar2(64), |
| studentName varchar2(64) |
| ); |
| |
| create or replace type StudentInfoArr as table of StudentInfo; |
| |
| |
| create or replace procedure sp_param_list_02(arr in StudentInfoArr) |
| is |
| |
| v_student_count number := 0; |
| begin |
| |
| select count(*) into v_student_count from table(cast(arr AS StudentInfoArr)) |
| where studentId like 'S%'; |
| DBMS_OUTPUT.PUT_LINE('传递进来学生学号以S开头的学生有: ' || v_student_count || '个'); |
| |
| |
| for i in 1..arr.COUNT loop |
| DBMS_OUTPUT.PUT_LINE('studentId:' || arr(i).studentId || ' studentName:' || arr(i).studentName); |
| end loop; |
| end; |
| |
| declare |
| begin |
| sp_param_list_02(arr => StudentInfoArr(StudentInfo('S001','张三'),StudentInfo('S002','李四'))); |
| end; |
8、返回多个参数
| create or replace procedure sp_return_value(stuInfoList out Sys_Refcursor) |
| IS |
| begin |
| open stuInfoList for select STUDENT_ID,STUDENT_NAME,SEX from STUDENT; |
| end; |
| |
| declare |
| stu Sys_Refcursor; |
| v_student_id STUDENT.STUDENT_ID%TYPE; |
| v_student_name STUDENT.STUDENT_NAME%TYPE; |
| v_sex STUDENT.SEX%TYPE; |
| begin |
| SP_RETURN_VALUE( stu); |
| loop |
| fetch stu into v_student_id,v_student_name,v_sex; |
| exit when stu%notfound; |
| DBMS_OUTPUT.PUT_LINE('studentId:' || v_student_id || ' studentName: ' || v_student_name); |
| end loop; |
| end; |
9、程序包 package
1、定义包头
包头
可以简单的理解java
中的接口。
| create or replace package pkg_huan as |
| v_pkg_name varchar2(30) := 'pkg_huan'; |
| function add(param1 in number, param2 in number) return number; |
| procedure sp_pkg_01; |
| procedure sp_pkg_02(param1 in varchar2); |
| end pkg_huan; |
2、实现包体
包体
可以简单的理解java
中的实现接口
的类。
| create or replace package body pkg_huan as |
| |
| function add(param1 in number, param2 in number) return number IS |
| begin |
| return param1 + param2; |
| end; |
| |
| procedure sp_pkg_01 as |
| begin |
| DBMS_OUTPUT.PUT_LINE('package name:' || v_pkg_name || 'procedure name: sp_pkg_01'); |
| end; |
| |
| procedure sp_pkg_02(param1 in varchar2) as |
| begin |
| DBMS_OUTPUT.PUT_LINE('param1:' || param1); |
| end; |
| end; |
3、调用包中的方法或存储过程
| begin |
| |
| DBMS_OUTPUT.PUT_LINE('1+2=' || PKG_HUAN.add(1,2)); |
| |
| PKG_HUAN.sp_pkg_01(); |
| |
| PKG_HUAN.sp_pkg_02(12); |
| end; |
10、参考链接
1、http://www.cis.famu.edu/support/10g/Oracle_Database_10g/doc/appdev.102/b14261/objects.htm
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结
2022-05-13 drools session理解