PLSQL
简介
PL / SQL是一种过程语言,专门用于在其语法中包含SQL语句。PL / SQL程序单元由Oracle数据库服务器编译并存储在数据库中。在运行时,PL / SQL和SQL都在同一服务器进程中运行,从而带来最佳效率。PL / SQL自动继承Oracle数据库的健壮性,安全性和可移植性。
为什么要使用PLSQL
bryn liewellyn的解释:
型软件系统必须由模块构建。模块将其实现隐藏在暴露其功能的接口后面。这是计算机科学最着名的原则。对于使用Oracle数据库的应用程序,数据库当然是其中一个模块。实现细节是表和操作它们的SQL语句。它们隐藏在PL / SQL接口之后。这是厚数据库范例:仅从数据库PL / SQL发出选择,插入,更新,删除,合并,提交和回滚。以这种方式构建的应用程序的开发人员和最终用户对其正确性,可维护性,安全性和性能感到满意。但是当开发人员遵循NoPlsql范例时,他们的应用程序在每个领域都存在问题,最终用户也会受到影响。本次会议为PL / SQL奉献者提供了无懈可击的论据,以捍卫他们对怀疑论者的攻击的信念; 出席的怀疑论者会看到光明。
参考白皮书:
结构
PL / SQL块由关键字DECLARE,BEGIN,EXCEPTION和END定义,它们将块分为三个部分:
- 声明性:声明变量,常量和其他代码元素的语句,然后可以在该块中使用
- 可执行部分:执行块时运行的语句
- 异常处理:一个特殊结构化的部分,可用于“捕获”或捕获可执行部分运行时引发的任何异常
其中可执行部分是必须的,块中也可以嵌套块。
使用
一个最简单的PLSQL
begindbms_output.put_line('Hello Wolrd!');end;/
如果你能看到PLSQL执行过程已完成的提示,证明成功了。
执行的时候如果使用SQL PLUS执行功能,可能没看到hellO world.原因是输出开发是关闭的。
打开输出开关
set serveroutput on;
此时就能看到输出的结果啦。
声明变量与赋值
前面提过,PLSQL三部分组成,第一部分声明部分是可选的,这个部分可以用于声明我们要用的所有的变量,常量等等。
declare v_name varchar2(32);beginv_name := '菲菲';dbms_output.put_line(v_name);end;/
前面的代码是声明后,在begin区域当中赋值,也可以声明的时候直接赋值。
declare v_name varchar2(32) := '王菲';begindbms_output.put_line(v_name);end;/
程序的解释
declare:表明这是一个声明的区块。
v_name 是一个变量名,varchar2(32)是变量的数据类型,数据类型也是一个大的话题,大家可以自行了解下,对于PLSQL额外支持一些特殊的数据类型
- %type : 引用某个表里面的某列数据类型
- $rowtype : 引用某个表里面的某行
此外还支持大数据类型 lob
dbms_output.put_line:用于输出,类似java的System.out.println();
注意
语句都是以分好结束的,语法规定。
嵌套使用
declare v_name varchar2(32) := '王菲';begin declare v_age number(3) := 23; begin dbms_output.put_line(v_age); end;dbms_output.put_line(v_name);end;/
连接字符串
declare v_name varchar2(32) := '王菲';begindbms_output.put_line(v_name || 'love');end;/
|| 可以将王菲与love连接输出。
命名块
前面所使用这些代码,执行的时候需要我们重新键入,如果这些东西我经常要用呢,是否可以存储起来,下次直接调用即可。
PL / SQL支持命名的代码块的定义,也称为子程序,可以是程序也可以是函数。
create or replace procedurehello_worldisbegin dbms_output.put_line('Hello World!');end;/
- create or replace: 创建或者替换,如果该过程没有,则创建,如果已经存在,则替换。
- hello_world: 给过程取个名字
- is: 语法规定,描述后面的内容是过程的具体内容。
- 剩下的内容就是我们写的代码块了。
使用命名块
如果调用已经定义好的块呢?
beginhello_world;end;/
在块当中直接编写名字就是调用了。
入参
刚才我们输出文字的程序是固定输出hello world,这样就很不灵活。
create or replace procedurehello_world (msg in varchar2)isbegin dbms_output.put_line('Hello :' || msg);end;/
测试:
begin hello_world('韩雪');end;
入参多个
create or replace procedurehello_world (msg in varchar2,age number)isbegin dbms_output.put_line('Hello :' || msg || age);end;/
测试
begin hello_world('韩雪',32);end;
解释:
msg in varchar2
msg:入参名称
in:参数模式,in为只读
varchar2: 数据类型
返回值(函数的使用)
前面的程序能处理的问题,但是有时候我们需要程序处理一个结果然后将其返还给调用者,比如我要计算两个数的乘法值,不是直接打印,而是得到之后再参与其它计算。
create or replace functionf_cal_multiplication (n1 in number,n2 in number )return numberisbegin return n1 * n2;end;/
测试
declare v_num number;begin v_num := f_cal_multiplication(3,5); dbms_output.put_line(v_num);end;//*结果为15*/
在insert语句当中使用
create table t_1( id number, age number);
declare v_num number;begin insert into t_1 values(1,f_cal_multiplication(2,3)); commit;end;/
查询所有的函数或者存储过程
SELECT * FROM ALL_OBJECTS WHERE OBJECT_TYPE IN ('FUNCTION','PROCEDURE','PACKAGE')
标识符
- PLSQL默认不区分大小写
- hello
- Hello
- HELLLO
他们是一样的。
- 最大长度为30
- 第一个字符必须为字母
- 非第一个字符可以是字母下划线数字_$#
- 如果期望是字符大小写敏感的, 可以将其用双引号引起来
"ab" "AB"
%Type的使用
declare v_age t_1.age%type;begin v_age := 3; dbms_output.put_line(v_age);end;/
%rowtype的使用
declare v_row t_1%rowtype;begin select * into v_row from t_1 where id = 1; dbms_output.put_line(v_row.id || v_row.age);end;/
将整个一行看做一个行类型,可以使用select xxx into 语法。