SQL(Structure Query Language)的含义是结构化查询语句,最早由Boyce和Chambedin在1974年提出,称为SEQUEL语言。1976年,IBM公司的San Jose研究所在研制关系数据库管理系统System R时修改为SEQUEL2,即目前的SQL语言。1976年,SQL开始在商品化关系数据库管理系统中应用。1982年美国国家标准化组织ANSI确认SQL为数据库系统的工业标准。目前,许多关系型数据库供应商都在自己的数据库中支持SQL语言,如:Access、Sybase、SQL Server、Infomix、DB2等。
PL/SQL也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL)。PL/SQL是Oracle数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编程语言的特点,所以PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。
用PL/SQL编制的程序代码如下所示:
DECLARE
xm varchar2(8):=’丽丽’;
zym varchar2(10):=’计算机’;
zxf number(2):=45;
A integer:=1;
BEGIN
UPDATE XS
SET zxf=zx
WHERE xm=xm; /*更新学生表*/
IF SQL%NOTFOUND THEN /*检查记录是否存在,如果不存在就插入记录*/
INSERT INTO XS(XH,XM,ZYM,ZXF)
VALUES(1,xm,zym,zxf);
END IF;
END;
合法字符:
在使用PL/SQL进行程序设计时,可以使用的有效字符包
括以下3类:
(1)所有的大写和小写英文字母;
(2)数字0~9;
(3)符号() + - * / <> = ! ~ ;:. ` @ % , " # ^ & _ { } ? [ ]。
PL/SQL标识符的最大长度为30个字符,不区分大小写,但是适当地使用大小写可以提高程序的可读性。
PL/SQL中变量声明格式:
(1) 变量必须以字母(A~Z)开头
(2) 其后跟可选的一个或多个字母、数字(0~9)或特殊字符$、# 或_
(3) 变量长度不超过30个字符
(4) 变量名中不能有空格
常用数据类型:
(1)VARCHAR类型:
语法格式:
var_field VARCHAR(n);
其中长度值n是本变量的最大长度且必须是正整数,例如:
var_field VARCHAR(11);
在定义变量时,可以同时对其进行初始化,例如:
var_field VARCHAR(11):=’Hello world’;
(2)NUMBER类型:
NUMBER数据类型可用来表示所有的数值类型。
语法格式:
num_field NUMBER(precision,scale);
其中precision表示总的位数;scale表示小数的位数,scale缺省表示小
数位为0。如果实际数据超出设定精度则出现错误。例如:
num_field NUMBER(10,2);
num_field是一个整数部分最多使8位,小数部分最多是2的变量。
declare
v_no number:=10;
begin
v_no:=v_no/0;
dbms_output.put_line(v_no);
exception
when others then
dbms_output.put_line('分母不能为0');
end;
(3)DATE类型:
用来存放日期时间类型数据,用7个字节分别描述年、月、日、时、
分、秒。
语法格式:
date_field DATE;
日期缺省格式为DD-MON-YY,分别对应日、月、年,例如17-JUN-
2002。注意,月份的表达要用英文单词的缩写格式。日期的格式可
以设置为中文格式,例如17-六月-2002。
(4)BOOLEAN类型:
逻辑型(布尔型)变量的值只有true(真)或false(假)。逻辑型变量一般用
于判断状态,然后根据其值是“真”或是“假”来决定程序执行分支。关
系表达式的值就是一个逻辑值。
注意:boolean类型变量不能直接通过 dbms_output.put_line(参数);直接输出,如果想输出,必须通过if判断;
条件判断语句:
IF逻辑结构
IF逻辑结构有3种表达式。
(1) IF-THEN
语法格式:
IF Boolean_expression THEN /*条件表达式*/
Run_expression /*条件表达式为真时执行*/
END IF
(2) IF-THEN-ELSE
语法格式:
IF Boolean_expression THEN /*条件表达式*/
Run_expression /*条件表达式为真时执行*/
ELSE
Run_expression /*条件表达式为假时执行*/
END IF;
(3) IF-THEN-ELSIF-THEN-ELSE
语法格式:
IF Boolean_expression1 THEN
Run_expression1
ELSIF Boolean_expression2 THEN
Run_expression2
ELSE
Run_expression3
END IF;
declare
i number:=10;
begin
if i<=0
then
dbms_output.put_line('分母不能为0');
else
dbms_output.put_line('分母不能为2');
end if;
end;
declare
v_no number:=1000;
begin
if v_no>1000 then
dbms_output.put_line('1');
elsif v_no=1000 then
dbms_output.put_line('2');
else
dbms_output.put_line('3');
end if;
end;
循环操作语句:
(1) LOOP-EXIT-END循环
语法格式:
LOOP
Run_expression /*执行循环体*/
IF Boolean_expression THEN /*测试Boolean_expression是否符合退出条件*/
EXIT; /*满足退出条件,退出循环*/
END IF;
END LOOP;
declare
i number;
begin
for i in 1..10
loop
dbms_output.put_line(i);
end loop;
end;
declare
i number;
sum1 number:=0;
begin
for i in 1..10
loop
sum1:=sum1 +i;
end loop;
dbms_output.put_line(sum1);
end;
--例:求10的阶乘。
DECLARE
n NUMBER:=1;
count1 NUMBER:=2;
BEGIN
LOOP
n:=n*count1;
count1:=count1+1;
IF count1>10THEN
EXIT;
ENDIF;
ENDLOOP;
dbms_output.put_line(to_char(n));
END;
(2)LOOP-EXIT-WHEN-END循环
除退出条件检测有所区别外,此结构与前一个循环结构
类似。
语法格式:
LOOP
Run_expression /*执行循环体*/
EXIT WHEN Boolean_expression /*测试是否符合退出条件*/
END LOOP;
--例:求10的阶乘。
DECLARE
n NUMBER:=1;
count1 NUMBER:=2;
BEGIN
LOOP
n:=n*count1;
count1:=count1+1;
EXITWHEN count1=11;
ENDLOOP;
dbms_output.put_line(to_char(n));
END;
(3)WHILE-LOOP-END循环
语法格式:
WHILE Boolean_expression /*测试Boolean_expression是否符合退出条件*/
LOOP
Run_expression /*执行循环体*/
END LOOP;
--例:用WHILE-LOOP-END循环结构求10的阶层。
DECLARE
n NUMBER:=1;
count1 NUMBER:=2;
BEGIN
WHILE count1<=10
LOOP
n:=n*count1;
count1:=count1+1;
ENDLOOP;
dbms_output.put_line(to_char(n));
END;
(4) FOR-IN-LOOP-END循环
语法格式:
FOR count IN count_1..count_n /*定义跟踪循环的变量*/
LOOP
Run_expression /*执行循环体*/
END LOOP;
--例:用FOR-IN-LOOP-END循环结构求10的阶层。
DECLARE
n NUMBER:=1;
count1 NUMBER;
BEGIN
FOR count1 IN2..10
LOOP
n:=n*count1;
ENDLOOP;
dbms_output.put_line(to_char(n));
END;
逻辑判断语句:
1. CASE语句
CASE语句是在Oracle9i才引入的。
语法格式:
CASE input_name
WHEN expression1 THEN result_expression1
WHEN expression2 THEN result_expression2
…
WHEN expressionN THEN result_expression
[ELSE result_expressionN]
END;
例如:
DECLARE
ename_1 varchar2(20);
empno_1 varchar2(16);
v_Result varchar2(20);
BEGIN
SELECT empno,ename
INTO empno_1,ename_1
FROM emp
WHERE empno='7369';
CASE length(ename_1)/*判断v_kch的值,并给出结果 */
WHEN1THEN v_Result:='名字有1个字符';
WHEN2THEN v_Result:='名字有2个字符';
WHEN3THEN v_Result:='名字有3个字符';
WHEN4THEN v_Result:='名字有4个字符';
when5then v_result:='名字有5个字符';
ELSE
v_Result:='Nothing';
ENDCASE;
dbms_output.put_line(v_result||':'||ename_1);
END;
(5)使用%TYPE
%TYPE属性提供了变量和数据库列的数据类型。
my_xh XS.XH%TYPE;即:变量名 表名.列名%TYPE; 表示该属性为某个表中的某个列的类型一致;
使用%TYPE声明具有以下两个优点:
① 不必知道XH列的确切的数据类型;
② 如果改变了XH列的数据库定义,my_xh的数据类型在运行时会自动进行修改。
例如:
-- Created on 2017/10/19 by ADMINISTRATOR
declare
employeeNO emp.empno%type;--声明employeeNO 属性类型为emp表的empno列类型一致;
employeeName emp.ename%type;
deptNO number(5);
deptName varchar2(20);
i char(1):=2;
begin
if i=1then--注意比较通过一个=号
select deptno,dName into deptNO,deptName from dept where deptno=20;
dbms_output.put_line('查询部门20的编号以及部门名称:'||deptno||':'||deptName);
else
select empno,ename into employeeNO ,employeeName from emp where empno=7369;
dbms_output.put_line('查询7369员工编号以及姓名:'||employeeNO||':'||employeeName);
endif;
end;
(6) E emp%ROWTYPE
可以使用%ROWTYPE属性声明描述表的行数据的记录;
例如:
-- Created on 2017/10/19 by ADMINISTRATOR
declare
employee emp%rowtype;--声明employee 属性类型为emp表行类型一致;
department dept%rowType;--声明deptartment变量为dept行类型;
i number(5):=2;
begin
if i=1then--注意比较通过一个=号
select deptno,dName into department.deptno,department.dname from dept where deptno=20;--可以直接将某列赋值给该变量中的某个字段
dbms_output.put_line('查询部门20的编号以及部门名称:'||department.deptno||':'||department.dname);
else
select emp.*into employee from emp where empno=7369;--可以直接将正行赋值给该变量
dbms_output.put_line('查询7369员工编号以及姓名:'||employee.empno||':'||employee.ename||':'||employee.hiredate);
endif;
end;
(7)数组类型:数据是具有相同数据类型的一组成员的集合。在PL/SQL中,数组数据类型是VARRAY。 定义VARRY数据类型语法如:
TYPE varray_name IS VARRAY(size) OF element_type [NOT NULL
例如:
DECLARE
--定义一个最多保存5个VARCHAR(25)数据类型成员的VARRAY数据类型
TYPE reg_varray_type ISVARRAY(5)OFVARCHAR(25);
--声明一个该VARRAY数据类型的变量
v_reg_varray REG_VARRAY_TYPE;
BEGIN
--用构造函数语法赋予初值
v_reg_varray := reg_varray_type ('中国','美国','英国','日本','法国');
DBMS_OUTPUT.PUT_LINE('地区名称:'||v_reg_varray(1)||'、'
||v_reg_varray(2)||'、'
||v_reg_varray(3)||'、'
||v_reg_varray(4));
DBMS_OUTPUT.PUT_LINE('赋予初值NULL的第5个成员的值:'||v_reg_varray(5));
--用构造函数语法赋予初值后就可以这样对成员赋值
v_reg_varray(5):='法国';
DBMS_OUTPUT.PUT_LINE('第5个成员的值:'||v_reg_varray(5));
END;
(8)record用户定义的记录,必须声明自己的域。记录包含唯一的命名域,具有不同的数据类型。
DECLARE
TYPE TimeRec IS RECORD(HH number(2),MM number(2));
TYPE MeetingTyp IS RECORD
(
Meeting_Date date,
Meeting_Time TimeRec,
Meeting_Addr varchar2(20),
Meeting_Purpose varchar2(50)
)
例如:
declare
--type声明一种自定义类型, is record表示该类型中包含有哪些属性
TYPE TimeRec ISRECORD(empno number(10),deptno number(5));
a timeRec;--a变量为我们声明timeRec类型
begin
select empno,deptno into a from emp where empno=7369;--into 表示赋值,注意一条语句中只能使用一次 且返回结果不能多条记录
dbms_output.put_line(a.empno);--表示输出
end;