Oracle学习笔记 part2
在Oracle中有一个很重要的语言PL/SQL,在这一部分里,我们主要聊聊这个语言
DECLARE --声明部分: 在此声明PL/SQL用到的变量,类型及游标,以及局部的存储过程和函数 BEGIN -- 执行部分: 过程及SQL 语句 , 即程序的主要部分 EXCEPTION -- 执行异常部分: 错误处理 END;
我们通过这个PL/SQL结构的语法来写一个小例子
declare --声明一个名字叫V_MyName的变量并把其赋值为'Sora',变量的类型为varchar(20) 其中 := 代表赋值语句 V_MyName varchar(20) := 'Sora' ; --声明一个名字叫V_InsertName的变量,并指定类型为hls_test_sora表中的test_name列类型 V_InsertName hls_test_sora.test_name%type; begin --通过dbms输出V_MyName的值,其中||表示连接字符串,相当于System.out.println(V_MyName) dbms_output.put_line('V_MyName的值为'||V_MyName); --插入一条数据,其中vw_test_sora为自定义视图(注意这里没有写分号,这个语句还没有完毕) insert into vw_test_sora values ('Venti', 17, 'male', sysdate) --将插入的值中的test_name列中的值注入到V_InsertName变量中 returning test_name into V_InsertName; --输出V_InsertName的值 dbms_output.put_line('插入值后V_InsertName的值为'||V_InsertName); end;
以上这个小例子实现了数据插入并显示到dbms上 ,当然这个使用了returning这个关键词,这个关键词只能用在DML语句中,如果希望在DQL中使用则直接将into写在DQL语句中,如下所示
declare v_name varchar2(20); v_age number; begin select test_name, test_age into v_name, v_age from hls_test_sora where test_id = 5; dbms_output.put_line(v_name) dbms_output.put_line(v_age) end;
上面的Demo是不是很容易?接下来,我们把他们几个步骤拆开逐步分析
Declare
用来声明变量的,上面也说了,%type可以指定关键词,或者自己定义,也可以初值赋值。接下来我们聊聊一些别的类型的数据
记录类型
declare --声明一个自定义record类型,命名为my_record type my_record is record( v_name varchar2(20), v_age number, v_gender varchar2(10) ); --声明一个类型为my_record类型的变量,命名为v_my_record v_my_record my_record; begin --将查询到的数据注入到v_my_record变量中,由于是注入,只能查询一条数据 select test_name, test_age, test_gender into v_my_record from hls_test_sora where test_id = 5; dbms_output.put_line(v_my_record.v_name || v_my_record.v_age || v_my_record.v_gender); end;
行类型
--此处表示v_bx_app_notice_list变量继承了表bx_app_notice_list中的所有字段
v_bx_app_notice_list bx_app_notice_list%rowtype
Begin
if语句
其实这个和一般的if语句一样,同case...when...then,下面举个例子,一看就会的(当然后面也可以加elif,这点有点像python)
declare v_age hls_test_sora.TEST_AGE%type; begin select test_age into v_age from hls_test_sora where test_id = 5; --如果大于10就输出age>10,如果不是就输出v_age<=10 if v_age > 10 then dbms_output.put_line(v_age||'>10'); else dbms_output.put_line(v_age||'<=10'); end if; end;
小Tips:if每个语句后需要加分号,when...then不能加分号
关于循环
废话不多说直接上例子,三种利用循环输出1-100的方法
--loop循环 declare v_num number := 1; begin loop dbms_output.put_line(v_num); v_num := v_num + 1; exit when v_num > 100; end loop; end; --while+loop循环 declare v_num number := 1; begin while v_num <= 100 loop dbms_output.put_line(v_num); v_num := v_num + 1; end loop; end; --for循环 begin --..表示范围运算符,承接两个参数,表示100-1的参数,reverse表示倒置,即从1-100 for num in reverse 100..1 loop dbms_output.put_line(num); end loop; end;
看到上面三种循环的方式,选哪个就不用我多说了吧?那肯定是for循环写的最少啊,不过对于那种不知道循环几次的需求就不要用for循环了。说起来for循环的操作方式真有点像python中的for i in range(100)。我感觉for循环最大的优势在于不需要自变量就可以循环,而且条件也写的比较方便(也可能是因为我这个例子比较简单)
下面是一些复杂的循环(算法)
--输出100以内的所有质数 -- 首先我们创建个函数... -我不会函数啊我靠! -函数也就那样的,早点用函数早点少敲代码(笑) --create or replace 英文字面意思,后面就是函数名以及函数参数的定义 CREATE OR REPLACE function IsPrime(v_num number) --返回值的定义,返回值不需要写长度 return number is --这里本来是可以自定义声明变量的,但是因为我们这个例子过于简单就不需要了。(在这里就可以看出函数和一般的pl/sql结构是一样的) begin --循环2到目标开根范围以内的值,如果该数能整除循环的数,就返回0,如果循环完了都没有返回,就返回1 --需要注意的就是打分号,这个没提示的太不人性,基本上看半天才看出来(也可能是js敲多了不习惯敲分号) for i in 2..(sqrt(v_num)) loop if v_num mod i = 0 then return(0); end if; end loop; return(1); end IsPrime; --接下来就很简单了,调用这个函数即可,应该不需要注释吧? begin for i in 2..100 loop if IsPrime(i) = 1 then dbms_output.put_line(i); end if; end loop; end;
关于goto,这里只是提一嘴,感觉不大能用的上,例子如下
--判断是否为合数 CREATE OR REPLACE function IsTotal(v_num number) return number is begin for i in 2..(sqrt(v_num)) loop if v_num mod i = 0 then goto total; end if; end loop; return (0); <<total>> return (1); end;
跳出循环的一些关键词
--EXIT:跳出本循环转而执行本循环的上一级循环的下一次循环。
--CONTINUE:本次循环后面的代码部分不再执行,转而执行本循环的下一次循环。

浙公网安备 33010602011771号