PLSQL

Posted 沙漠皇帝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PLSQL相关的知识,希望对你有一定的参考价值。

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奉献者提供了无懈可击的论据,以捍卫他们对怀疑论者的攻击的信念;?出席的怀疑论者会看到光明。


参考白皮书:https://cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/File/6900012af83fa0f8eb8224513713fb55/why_use_plsql_whitepaper_10.pdf

结构

PL / SQL块由关键字DECLARE,BEGIN,EXCEPTION和END定义,它们将块分为三个部分:

  1. 声明性:声明变量,常量和其他代码元素的语句,然后可以在该块中使用
  2. 可执行部分:执行块时运行的语句
  3. 异常处理:一个特殊结构化的部分,可用于“捕获”或捕获可执行部分运行时引发的任何异常

其中可执行部分是必须的,块中也可以嵌套块。

使用

一个最简单的PLSQL

begin
dbms_output.put_line('Hello Wolrd!');
end;
/

如果你能看到PLSQL执行过程已完成的提示,证明成功了。

执行的时候如果使用SQL PLUS执行功能,可能没看到hellO world.原因是输出开发是关闭的。

打开输出开关

set serveroutput on;

此时就能看到输出的结果啦。

声明变量与赋值

? 前面提过,PLSQL三部分组成,第一部分声明部分是可选的,这个部分可以用于声明我们要用的所有的变量,常量等等。

declare
    v_name varchar2(32);
begin
v_name := '菲菲';
dbms_output.put_line(v_name);
end;
/

前面的代码是声明后,在begin区域当中赋值,也可以声明的时候直接赋值。

declare
    v_name varchar2(32) := '王菲';
begin
dbms_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) := '王菲';
begin
dbms_output.put_line(v_name || 'love');
end;
/

|| 可以将王菲与love连接输出。

命名块

? 前面所使用这些代码,执行的时候需要我们重新键入,如果这些东西我经常要用呢,是否可以存储起来,下次直接调用即可。

PL / SQL支持命名的代码块的定义,也称为子程序,可以是程序也可以是函数。

create or replace procedure
hello_world
is
begin
    dbms_output.put_line('Hello World!');
end;
/
  • create or replace: 创建或者替换,如果该过程没有,则创建,如果已经存在,则替换。
  • hello_world: 给过程取个名字
  • is: 语法规定,描述后面的内容是过程的具体内容。
  • 剩下的内容就是我们写的代码块了。

使用命名块

? 如果调用已经定义好的块呢?

begin
hello_world;
end;
/

在块当中直接编写名字就是调用了。

入参

? 刚才我们输出文字的程序是固定输出hello world,这样就很不灵活。

create or replace procedure
hello_world (msg in varchar2)
is
begin
    dbms_output.put_line('Hello :' || msg);
end;
/

测试:

begin
    hello_world('韩雪');
end;

入参多个

create or replace procedure
hello_world (msg in varchar2,age number)
is
begin
    dbms_output.put_line('Hello :' || msg || age);
end;
/

测试

begin
    hello_world('韩雪',32);
end;

解释:

msg in varchar2

msg:入参名称

in:参数模式,in为只读

varchar2: 数据类型

返回值(函数的使用)

? 前面的程序能处理的问题,但是有时候我们需要程序处理一个结果然后将其返还给调用者,比如我要计算两个数的乘法值,不是直接打印,而是得到之后再参与其它计算。

create or replace function
f_cal_multiplication (n1 in number,n2 in number )
return number
is
begin
    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 语法。

以上是关于PLSQL的主要内容,如果未能解决你的问题,请参考以下文章

SQL记录-PLSQL-DBMS输出

需要 Oracle PLSQL 函数的输出帮助

在 Oracle PLSQL 函数的输出过程中出现逗号问题

如何在 SQL Developer 上远程调试 PLSQL 代码?

循环遍历多个表的 plsql 代码

使用 PLSQL 更新 Excel 单元格