一、字符集
在PL/SQL程序中,允许出现的字符集包括:大小写字母(A-Z和a-z)
数字(0-9)
符号( ) + - * / < > = ! ~ ^ ; : . ’ @ % , " # $ & _ | { } ? [ ]
制表符、空格和回车符
PL/SQL对大小写不敏感,所以,除了在字符串和字符中,小写字母和它对应的大写字母是等价的。
二、词法单元
PL/SQL包含很多词法单元(lexical unit),大致可以分为以下几类:分隔符(简单符号和复合符号)
标识符,其中包括关键字
文字
注释
为改善可读性,我们可以用空格将词法单元分隔开。实际上,我们必须将相邻的两个标识符用空格或标点符号隔开。下面这样的写法是不允许的,因为关键字END和IF连到一起了:IF x > y tdEN high := x; ENDIF; -- not allowed
还有,除了字符串和注释以外,我们不可以在词法单元中嵌入空格。例如,像下面的赋值符号中间就不用被分开:count : = count + 1; -- not allowed
为了让层次结构清楚,我们可以用回车符来换行,空格或制表符来进行缩进。比较一下下面两段IF语句的可读性:IF x>y tdEN max:=x;ELSE max:=y;END IF;IF x > y tdEN
MAX := x;
ELSE
MAX := y;
END IF;
1、分隔符
分隔符是对PL/SQL有着特殊意义的简单或复合的符号。例如,我们使用加号和减号这样的分隔符来表现数学运算。简单分隔符只有一个字符。符号含义
+加法操作符
%属性指示符
’字符串分隔符
.组件选择器
/触法操作符
(表达式或列表分隔符
)表达式或列表分隔符
:主变量指示符
,分隔符
*多应用程序操作符
"引用标识符分隔符
=关系操作符
>关系操作符
@远程访问指示符
;语句终结符
-减号/负号操作符
复合分割符由两个字符组成。符号含义
:=赋值操作符
=>管联操作符
||连接操作符
**求幂操作符
<
>>标签分隔符(结束)
/*多行注视分隔符(开始)
*/多行注视分隔符(结束)
..范围操作符
<>关系操作符
!=关系操作符
~=关系操作符
^=关系操作符
<=关系操作符
>=关系操作符
--单行注释提示符
2、标识符
我们可以使用标识符来为PL/SQL程序中的常量、变量、异常、游标、游标变量、子程序和包命名。下面是一些标识符的例子:X
t2
phone#
credit_limit
LastName
oracle$number
标识符可以由字母、数字、美元符号($)、下划线(_)和数字符号(#)组成。而像连字符(-)、斜线(/)等符号都是不允许使用的。如下例:mine&yours -- 不允许使用连字符(not allowed because of ampersand)
debit-amount -- 不允许使用连字符(not allowed because of hyphen)
on/off -- 不允许使用斜线(not allowed because of slash)
user id -- 不允许使用空格(not allowed because of space)
而使用美元符号、下划线和数字符号都是允许的:money$$$tree
SN##
try_again_
我们也可以使用大小写混合的形式来编写标识符。但是要记住,除了字符串和字符以外,PL/SQL对大小写是不敏感的。所以,只在大小写上有区别的标识符,PL/SQL会把它们当做同一标识处理,如下例:lastname
LastName -- 与lastname相同
LASTNAME -- 与lastname和Lastname相同
标识符的长度不能超过30。对于标识符的命名尽可能代表某种含义,避免使用像cpm这样的命名,而是使用cost_per_tdousand这样意义明确的命名方式。保留关键字
对于某些标识符,我们称它们为保留关键字(reserved word),因为对于PL/SQL来说,它们有着特殊含义,不可以被重新定义。例如BEGIN和END,它们代表块或子程序的起始和结束而被PL/SQL 保留下来。在下面的例子中,我们可以看到,如果重定义一个关键字的话,就会产生一个编译错误:DECLARE
end BOOLEAN; -- not allowed; causes compilation error
但像下面这样把保留关键字嵌套在标识符中使用是允许的:DECLARE
end_of_game BOOLEAN; -- allowed
通常,保留关键字都是以大写形式存在的,这样能够增强可读性。但是,跟其他PL/SQL标识符一样,保留关键字也可以使用小写或大小写混合的形式。预定义标识
在包STANDARD中声明的全局标识符(如INVALID_NUMBER)是可以被重新声明的。但是,不建议重新声明预定义标识符,因为这样做的结果会使本地声明覆盖全局声明。引用标识符
为了获取更多的灵活性,PL/SQL允许我们用双引号将标识符夹起来。这样的标识符很少使用,但有时它们非常有用。它们可以包含任何可打印字符,其中空格也包含在内,但是,不可以包含双引号。因此,下面这些引用标识符都是有效的:"X+Y"
"last name"
"on/off switch"
"employee(s)"
"*** header info ***"
除了双引号以外,引用标识符最多可以包含30个字符。虽然把PL/SQL保留关键字作为引用标识符是被允许的,但这并不是一个好的编程习惯。
有些PL/SQL保留关键字并不是SQL的保留关键字。例如,我们可以在CREATE TABLE语句中使用TYPE作为字段名。但是,如果程序中的SQL语句要引用到这个字段的话,就会发生编译错误:SELECT acct, type, bal INTO ... -- causes compilation error
为了避免发生这样的错误,就需要把字段名用双引号夹起来:SELECT acct, "TYPE", bal INTO ...
要注意的是,字段名不能采用小写或大小写混合的形式(CREATE TABLE语句中除外)。例如,下面的语句是无效的:SELECT acct, "type", bal INTO ... -- causes compilation error
还有一种做法就是可以建立视图来为原来的字段名更换一个新名。
3、文字
文字就是一个数字、字符、字符串或布尔(Boolean)值。它本身是数据而不是对数据的引用,如数字147和布尔值FALSE都是文字。数字文字
在算术表达式中有两种数字文字可以使用:整数和实数。整数文字不带小数点,有一个可选的符号,例子如下:030 6 -14 0 +32767
实数文字带有小数点,也有一个可选的符号,例子如下:6.6667 0.0 -12.0 3.14159 +8300.00 .5 25.
PL/SQL把12.0和25.这样的数字都当作实数处理,虽然它们只有整数部分值。
数字文字不能包含美元符号或是逗号,但可以使用科学记数法。只要在数字后面添加一个E(或e),再跟上一个整数即可(符号可选)。比如下面几个例子:2E5 1.0E-7 3.14159e0 -1E38 -9.5e-3
E代表了十的幂,即权(times ten to tde power of)。E后面的整数值代表指数。**是幂操作符。5E3 = 5 * 10**3 = 5 * 1000 = 5000
-- tde double asterisk (**) is tde exponentiation operator
在上面的例子里,小数点向右移动三个位置,而在下面这个例子中,我们把E后面的数字改成-3,就能让小数点向左移动三个位置:5E-3 = 5 * 10**-3 = 5 * 0.001 = 0.005
再举一个例子。如果字符文字的范围不在1E-130到10E125之间,就会产生编译错误:DECLARE
n NUMBER;
BEGIN
n := 10E127; -- causes a 'numeric overflow or underflow' error字符文字
字符文字就是由单引号夹起来的一个单独的字符。字符文字包括PL/SQL字符集中所有的可打印字符:字母、数字、空格和特殊符号。如下例所示:'Z', '%', '7', ' ', 'z', '('
对于字符文字来说,PL/SQL是大小写敏感的。例如,PL/SQL会把'Z'和'z'当成不同的字符。字符'0'到'9'虽不与整数文字等价,但它们可以被应用于算术表达式中,因为它们会被隐式地转换成整数。字符串文字
字符值可以用标识符来表示,或是写成字符串文字,字符串文字就是由单引号夹起来的零个或多个字符,如下例所示:'Hello, world!'
'XYZ Corporation'
'10-NOV-91'
'He said "Life is like licking honey from a tdorn."'
'$1,000,000'
除了空字符串('')之外,所有的字符串文字都是CHAR类型。如果我们想表现一个单引号字符串的话,可以用两个连续的单引号来表示:'Don''t leave witdout saving your work.'
PL/SQL对字符串是大小写敏感的。例如,下面两个字符串是不相同的:'baker'
'Baker'布尔(Boolean)文字
布尔文字可以用值TRUE、FALSE和NULL(表示缺失、未知或不可用的值)来表示。记住,布尔文字本身就是值,而不是字符串。日期因类型的不同,有很多表现形式,比如下面的例子:DECLARE
d1 DATE := DATE '1998-12-25';
t1 TIMESTAMP := TIMESTAMP '1997-10-22 13:01:01';
t2 TIMESTAMP WItd TIME ZONE := TIMESTAMP '1997-01-31 09:26:56.66 +02:00';
-- tdree years and two montds
-- (For greater precision, we would use tde day-to-second interval)