• pl/sql小结


      1 /*
      2  * PL/SQL - 
      3  *  是Oracle数据库特定的数据库编程语法.
      4  * 所有的数据库存储过程/函数/触发器开发,都是数据库特定的语法.
      5  * 第一代: 机器语言
      6  * 第二代: 面向过程的语言
      7  * 第三代: 面向对象的语言
      8  * 第四代语言: 面向结果的语言. 语言编写完毕后,只要求结果正确.
      9  * 
     10  * PL/SQL是在Oracle数据库管理系统中开发的语法.
     11  * 是将有逻辑的SQL语句,固化在Oracle的DBMS中,可以重复调用的方式.
     12  * 如: to_date()  to_char()  replace()  substring()  max()  min()  avg()  upper()
     13  */
     14 
     15 /*
     16  * Oracle数据库为了提高执行效率.默认是关闭手工输出流的.
     17  * 开启手工输出:
     18  * set serveroutput on;
     19  * 关闭手工输出:
     20  * set serveroutput off;
     21  */
     22 -- hello world
     23 /*
     24  * 执行存储过程/函数的方式
     25  * 1. execute - 执行
     26  * 2. call - 调用, call命令可能有缓存. 结果输出不是每次都能看到的.
     27  *  必须刷新缓存或缓存空间不足的时候,才能看到结果
     28  * 3. 匿名代码块, 只能执行唯一一次的存储过程/函数.
     29  */
     30 execute dbms_output.put_line('hello world');
     31 call dbms_output.put_line('hello world with call');
     32 begin
     33     dbms_output.put_line('hello world with block');
     34 end;
     35 /
     36 
     37 /*
     38  * 匿名代码块结构及常用语法
     39  * declare 
     40  *     定义变量
     41  *     变量定义语法
     42  *     变量名 变量类型;
     43  *     变量定义并初始化语法  , := 赋值, = 比较等值  , > < >= <= != <>
     44  *     变量名 变量类型 := 变量数据;
     45  * begin
     46  *     定义代码逻辑
     47  *     变量赋值 -   变量名 := 值;
     48  *     执行语法 -   语法;
     49  * end;
     50  */
     51 -- 循环 loop
     52 -- 1. loop循环, 天生就是无限循环
     53 declare
     54     v_i number := 1;
     55 begin
     56     loop -- 开始循环
     57         dbms_output.put_line(v_i);
     58         v_i := v_i + 1;
     59         exit when v_i > 10; -- 当条件满足的时候,执行exit命令. 
     60     end loop; -- 结束循环
     61 end ;
     62 /
     63 
     64 -- while loop循环
     65 declare
     66     v_i number := 1;
     67 begin
     68     while v_i < 11 loop -- 当条件满足的时候,循环
     69         dbms_output.put_line(v_i);
     70         v_i := v_i + 1;
     71     end loop; -- 结束循环
     72 end ;
     73 /
     74 
     75 -- for循环
     76 begin
     77     for v_i in reverse 1..10 loop -- 当变量v_i在范围1到10之间的时候,循环. for循环数据自增1
     78         dbms_output.put_line(v_i);
     79     end loop;
     80 end ;
     81 /
     82 
     83 /*
     84  * PL/SQL中的CRUD
     85  */
     86 -- insert
     87 declare
     88     v_id number := 2;
     89     str varchar(32) := 'bbb';
     90     age number := 30;
     91 begin
     92     -- insert into tb_temp(id, v_str, v_age) values(1, 'aaa', 20);
     93     insert into tb_temp(id, v_str, v_age) values(v_id, str, age);
     94     commit;
     95 end ;
     96 /
     97 
     98 -- update
     99 begin
    100     update tb_temp
    101     set v_str = 'ccc', v_age = 40
    102     where id = 1;
    103     commit;
    104 end ;
    105 /
    106 
    107 -- delete
    108 begin
    109     delete from tb_temp where id = 2;
    110     commit;
    111 end ;
    112 /
    113 
    114 -- select, 要求将查询结果保存在变量中. 因为PL/SQL没有自动输出. 查询结果无保存单元.
    115 -- 限制为只能查询一条数据
    116 declare
    117     v_id number;
    118     str varchar2(32);
    119     age number;
    120 begin
    121     select id, v_str, v_age into v_id, str, age from tb_temp;
    122     dbms_output.put_line('id = ' || v_id || ', str = ' || str || ', age = ' || age);
    123 end ;
    124 /
    125 
    126 -- cursor 游标, 用于处理查询的PL/SQL语法结构.
    127 -- 类似java中的ResultSet. 在Oracle中是用来定位查询语句结果内存的一个引用.
    128 /*
    129  * 游标定义方式
    130  *  cursor 游标命名 is 查询语法;
    131  * 游标属性
    132  *  游标命名%found -- 最近一次fetch是否有结果, 无结果返回false,有结果返回true
    133  *  游标命名%notfound -- 最近一次fetch是否有结果, 有结果返回false,无结果返回true
    134  *  游标命名%isopen -- 是否开启. 已开启返回true
    135  */
    136 declare
    137     cursor c_temp is select * from tb_temp;
    138 begin
    139     for v_temp in c_temp loop -- 变量v_temp的类型就是游标中的一行数据的类型.
    140         dbms_output.put_line(v_temp.id || ' , ' || v_temp.v_str || ' , ' || v_temp.v_age);
    141     end loop;
    142 end ;
    143 /
    144 
    145 declare
    146     cursor c_temp is select * from tb_temp;
    147     v_temp tb_temp%rowtype; -- 变量v_temp和表格tb_temp中的一行数据的类型一样
    148 begin
    149     -- 开启游标
    150     open c_temp;
    151     
    152     -- 循环游标
    153     loop
    154         fetch c_temp into v_temp; -- 迭代游标中的一行数据到变量v_temp中.
    155         exit when c_temp%notfound; -- %notfound是游标的属性,代表最近一次fetch是否有新的数据.
    156         dbms_output.put_line(v_temp.id || ' , ' || v_temp.v_str || ' , ' || v_temp.v_age);
    157     end loop;
    158     
    159     -- 关闭游标
    160     close c_temp;
    161 end ;
    162 /
    163 
    164 declare
    165     cursor c_temp is select * from tb_temp;
    166     v_temp tb_temp%rowtype; -- 变量v_temp和表格tb_temp中的一行数据的类型一样
    167 begin
    168     -- 开启游标
    169     open c_temp;
    170         
    171     fetch c_temp into v_temp; -- 迭代游标中的一行数据到变量v_temp中.
    172     
    173     -- 循环游标
    174     while c_temp%found loop
    175         dbms_output.put_line(v_temp.id || ' , ' || v_temp.v_str || ' , ' || v_temp.v_age);
    176         fetch c_temp into v_temp; -- 迭代游标中的一行数据到变量v_temp中.
    177     end loop;
    178     
    179     -- 关闭游标
    180     close c_temp;
    181 end ;
    182 /
    183 
    184 /*
    185  * 判断语法
    186  * if xxx then
    187  * end if;
    188  * if xxx then
    189  * end if;
    190  * if xxx then
    191  * elsif xxx then
    192  * else
    193  * end if;
    194  */
    195 declare
    196     v_i number := 0;
    197 begin
    198     -- v_i > 0 输出正数, <0 输出负数, == 0输出零
    199     if v_i > 0 then
    200         dbms_output.put_line('正数');
    201     elsif v_i < 0 then
    202         dbms_output.put_line('负数');
    203     else
    204         dbms_output.put_line('零');
    205     end if;
    206 end ;
    207 /
    208 
    209 /*
    210  * 存储过程 - procedure
    211  * 创建存储过程,语法和创建表类似
    212  * 存储定义逻辑和匿名代码块类似
    213  * 没有返回值.
    214  */
    215 -- 定义
    216 create procedure print(v_str varchar2) -- ()中定义参数, 参数只定义类型,不定义长度.
    217 as -- 代替declare, as或is关键字不可少.
    218 begin
    219     dbms_output.put_line(v_str);
    220 end;
    221 /
    222 
    223 -- 定义+重置
    224 create or replace procedure print(v_str varchar2) -- ()中定义参数, 参数只定义类型,不定义长度.
    225 as -- 代替declare, as或is关键字不可少.
    226 begin
    227     dbms_output.put_line(v_str);
    228 end;
    229 /
    230 
    231 /*
    232  * 查看存储过程定义的编译错误: show errors;
    233  * 
    234  * 存储过程中的参数
    235  * 在存储过程中,参数除有类型外,还有传递方向.
    236  * 方向分为三种
    237  * 1. 输入参数 - 默认参数方向, 代表参数数据只能读,不能写. 定义语法 : 参数名 [in] 参数类型
    238  * 2. 输出参数 - 可以作为返回值的参数. 可写. 特性为, 第一次在存储过程中使用参数,格式化. 在使用的时候有要求
    239  *   要求是,传入的输出参数必须是一个可复制的变量.不能是常量. 定义语法: 参数名 out 参数类型
    240  * 3. 输入输出参数 - 可读可写. 不会格式化.语法: 参数名 in out 参数类型. 最不常用的参数方向.
    241  *   数据库是一个弱类型的数据存储管理工具. 容易造成参数转化错误
    242  */
    243 
    244 create or replace procedure helloWorld(v_name in out varchar2)
    245 as
    246 begin
    247     v_name := 'hello ' || v_name;
    248     print(v_name);
    249 end ;
    250 /
    251 
    252 create or replace procedure helloWorld(v_name out varchar2)
    253 as
    254 begin
    255     v_name := 'hello ' || v_name;
    256     print(v_name);
    257 end ;
    258 /
    259 
    260 declare
    261     v_name date := sysdate;
    262 begin
    263     print('调用helloWorld之前: ' || v_name);
    264     helloWorld(v_name);
    265     print('调用helloWorld之后: ' || v_name);
    266 end ;
    267 /
    268 
    269 declare
    270     v_name varchar2(32) := 'world';
    271 begin
    272     print('调用helloWorld之前: ' || v_name);
    273     helloWorld(v_name);
    274     print('调用helloWorld之后: ' || v_name);
    275 end ;
    276 /
    277 
    278 create or replace procedure print(v_str in varchar2) -- ()中定义参数, 参数只定义类型,不定义长度.
    279 as -- 代替declare, as或is关键字不可少.
    280 begin
    281     -- v_str := 'hello ' || v_str;
    282     dbms_output.put_line(v_str);
    283 end;
    284 /
    285 
    286 
    287 /*
    288  * 函数 function
    289  * 和存储过程之间的区别有:
    290  * 1. 关键字不同
    291  * 2. 有返回值
    292  * 3. 调用函数和调用存储过程方式不同.
    293  *    调用函数可以在SQL语法的DQL语句中使用.存储过程不能在DQL语句中使用.
    294  *    函数调用的时候,可以使用变量接收函数的返回值. 存储过程不能.
    295  */
    296 create or replace function f_test(v_str varchar2)
    297 return varchar2
    298 as
    299 begin
    300     return 'hello ' || v_str;
    301 end ;
    302 /
    303 
    304 declare
    305     v_str varchar2(32);
    306 begin
    307     -- v_str := f_test('zhangsan');
    308     -- print(v_str);
    309     print(f_test('lisi'));
    310 end ;
    311 /
    312 
    313 /*
    314  * 触发器, trigger. 不推荐使用. 影响数据库管理系统的执行效率
    315  * 触发器都是为表格提供的. 类似java中的监听器. 当某条件满足的时候,自动执行.
    316  * 对表格的CUD操作.
    317  * 通常触发器用于表中数据的保护.
    318  * 如: ERP系统中的用户数据保护. 用户为系统持有者. 如: 京东.京东用户是京东的员工. 
    319  */
    320     
    321 create or replace trigger ti_test1 before update on tb_temp
    322 for each row -- 行级触发器. 当表中每行数据有CUD操作时触发.
    323 when (old.id < 100) -- 当更新数据的id小于100的时候,触发器执行.
    324 begin
    325     dbms_output.put_line('before update触发器执行');
    326     
    327     -- :old : 旧的数据.在更新和删除的时候存在.
    328     dbms_output.put_line(:old.id || ' , ' || :old.v_str || ' , ' || :old.v_age);
    329     
    330     -- :new : 新的数据.在新增和更新的时候存在.
    331     dbms_output.put_line(:new.id || ' , ' || :new.v_str || ' , ' || :new.v_age);
    332 end ;
    333 /
    334 
    335 create or replace trigger ti_test2 after update on tb_temp
    336 begin
    337     dbms_output.put_line('after update触发器执行');
    338 end ;
    339 /
    340 
    341 
    342 -- 网络查询JDBC中的CallableStatement  call xxxx();
    343 
    344 
    345 
    346 
    347 
    348 
    349 
    350 
    351 
    352 
    353 create table tb_temp(
    354     id number(8) primary key,
    355     v_str varchar2(32),
    356     v_age number(3)
    357 );
  • 相关阅读:
    HTML5
    js实现查找字符串中最多的字符的个数
    get和post的区别
    第十七篇 类的特殊成员
    第十八篇 面向对象修饰符
    MariaDB+Keepalived双主高可用配置MySQL-HA
    linux命令详解——crontab
    Java的内存泄漏
    jvm监控工具jconsole进行远程监控配置
    loadrunner执行场景时报Error -27040: Data Format Extension: Init: Internal error问题解决
  • 原文地址:https://www.cnblogs.com/zzuzhenlei/p/7569698.html
Copyright © 2020-2023  润新知