联 系 我 们
售前咨询
售后咨询
微信关注:星环科技服务号
更多联系方式 >
6.8.12.3 基础知识
更新时间:7/30/2024, 6:22:55 AM
声明

在 PL/SQL 中,可以用常量和变量存储值,在程序运行过程中,变量的值可以改变。
可以在任何 PL/SQL 语句块,子过程,包等的声明部分去声明一个常量或者变量。

变量

PL/SQL 中,可以声明一个字符串,整数等类型的变量。PL/SQL 语句块或子程序运行时,变量都会被初始化,默认情况下,也就是变量没有被赋初值的时候,变量会被初始化成 NULL 值。

例 36. 变量的声明
!set plsqlUseSlash true
DECLARE
   V1 STRING
   V2 STRING:='字符串变量'
   V3 INT
   V4 INT:=100
   V5 BOOLEAN
   V6 BOOLEAN:='TRUE'
BEGIN
   DBMS_OUTPUT.PUT_LINE(V1)
   DBMS_OUTPUT.PUT_LINE(V2)
   DBMS_OUTPUT.PUT_LINE(V3)
   DBMS_OUTPUT.PUT_LINE(V4)
   DBMS_OUTPUT.PUT_LINE(V5)
   DBMS_OUTPUT.PUT_LINE(V6)
END;
/
复制

输出结果为:

output

null

字符串变量

null

100

null

TRUE

常量

声明一个常量,只需在特定的数据类型前加一个关键字“CONSTANT”。PL/SQL 语句块或子程序运行时,常量都会被初始化,默认情况下,也就是常量没有被赋初值的时候,此时常量会被初始化成 NULL 值。

例 37. 常量的声明
!set plsqlUseSlash true
DECLARE
   P1  CONSTANT STRING
   P2  CONSTANT STRING := '字符串常量'
   P3  CONSTANT INT
   P4  CONSTANT INT:=100
   P5  CONSTANT BOOLEAN
   P6  CONSTANT BOOLEAN:='TRUE'
BEGIN
   DBMS_OUTPUT.PUT_LINE(P1)
   DBMS_OUTPUT.PUT_LINE(P2)
   DBMS_OUTPUT.PUT_LINE(P3)
   DBMS_OUTPUT.PUT_LINE(P4)
   DBMS_OUTPUT.PUT_LINE(P5)
   DBMS_OUTPUT.PUT_LINE(P6)
END;
/
复制

输出结果为:

output

null

字符串常量

null

100

null

TRUE

DEFAULT

初始化变量时,可以使用关键字“DEFAULT”来赋值,作用与赋值操作符“ := ”完全相同,关键字“DEFAULT”会使变量在声明的过程中,会使有一个初始值,但是在程序体中可以对该变量进行再一次的赋值。

例 38. 用关键字“DEFAULT”给变量赋默认值
!set plsqlUseSlash true
DECLARE
   -- 声明一个字符串类型的变量 V1,并附初始值为 HELLO。
   V1 STRING DEFAULT 'HELLO' 
   V2 INT DEFAULT 100
   V3 BOOLEAN DEFAULT FALSE
BEGIN
   -- 在程序体内对变量 V1,进行再一次的赋值,再次打印变量 V1 的值,会发现此时变量 V1 的值为 hello world。
   V1 :='hello world' 
   DBMS_OUTPUT.PUT_LINE(V1)
   DBMS_OUTPUT.PUT_LINE(V2)
   DBMS_OUTPUT.PUT_LINE(V3)
END;
/
复制
  • 声明一个字符串类型的变量 V1,并附初始值为 HELLO。

  • 在程序体内对变量 V1,进行再一次的赋值,再次打印变量 V1 的值,会发现此时变量 V1 的值为 hello world。

输出结果为:

output

hello world

100

FALSE

命名规则

在 PL/SQL 中的常量,变量,游标,游标变量,异常,过程,函数,包均使用相同的命名规格,可以直接在语句块的部分创建或声明,也可以在包内直接声明。

  • 直接创建一个名为 proc1 的过程,参数名为 V1,参数属性为 IN,参数的数据类型为 STRING。

    CREATE OR REPLACE  proc1(V1  IN STRING)
    IS
    BEGIN
    ...
    END;
    复制
  • 在包内声明一个名为 proc2 的存储过程,参数名为 test_name,参数属性为 OUT,参数的数据类型为 DOUBLE。

    !set plsqlUseSlash true
    CREATE OR REPLACE PACKAGE test
    IS
       PROCEDURE proc2( test_name OUT DOUBLE)
    END;
    /
    复制
重复命名

在相同的作用域内,所有声明的标识符都必须是唯一的。即Inceptor 不允许在相同作用域内重复命名。即使数据类型不同,变量和参数的名字也不能相同。

例 39. 同时声明两个变量,变量名相同,数据类型不相同
!set plsqlUseSlash true
DECLARE
   V1 BOOLEAN
   V1 INT
BEGIN
   V1:= FALSE
END;
/
复制

输出结果为:

COMPILE FAILED: Semantic error: [Error 11108]
ANONYMOUS BLOCK (LINE 3, COLUMN 0, TEXT \"V1 INT\"): Existing variable v1
复制

可以看到,如果在相同作用域内重复命名两个标识符,Inceptor 会报错。

大小写敏感性

PL/SQL中,对于所有的标识符,如常量,变量,参数都是不区分大小写的。所以在命名时,不可以通过改变标识符大小写的方式来命名多个不同的标识符。

例 40. 同时声明两个变量,变量名字母的大小写形式不同
!set plsqlUseSlash true
DECLARE
   zip_code INT
   ZIP_CODE INT
BEGIN
   zip_code:= 90120
END;
/
复制

输出结果为:

COMPILE FAILED: Semantic error: [Error 11108]
ANONYMOUS BLOCK (LINE 3, COLUMN 0, TEXT \"ZIP_CODE INT\"): Existing variable zip_code
复制

可以看到,尽管变量名的大小写形式不同,Inceptor 仍然识别为相同的变量名。

命名解析

在 PL/SQL 中,变量名优先于数据库中表的列名,例如,在WHERE子句中如果变量名和表的列名相同,Inceptor 会认为两个都是变量名。

例 41. 删除 zara 表中某个存在的 gpa
!set plsqlUseSlash true
DECLARE
gpa DOUBLE default 4.5 
BEGIN
   DELETE FROM zara WHERE gpa=gpa 
   DBMS_OUTPUT.PUT_LINE('Deleted ' || SQL%ROWCOUNT || ' rows.') 
END;
/
复制

声明一个 DOUBLE 类型的变量 gpa,赋初值为 4.5,且表中存在一条记录的 gpa 为 4.5。

删除表 zara 中,列 gpa 的值为变量 gpa 的值,此处列名和变量名相同,Inceptor 会认为两个都是变量名,也就是说此时 where 条件为 4.5=4.5。

打印出执行上述 SQL 语句,一共删除了表 zara 中多少行的数据,由于 DELETE 语句中的 where 条件为 true,此处应该删除 zara 表中的全部记录。

输出结果为:

output

Deleted 7 rows.

例 42. 删除 zara 表中某个不存在的 gpa
!set plsqlUseSlash true
DECLARE
gpa DOUBLE default 2.0 
BEGIN
   DELETE FROM zara WHERE gpa=gpa 
   DBMS_OUTPUT.PUT_LINE('Deleted ' || SQL%ROWCOUNT || ' rows.') 
END;
/
复制

声明一个 DOUBLE 类型的变量 gpa,赋初值为 2.0,且表中不存在 gpa 为 4.5 的记录。

删除表 zara 中,列 gpa 的值为变量 gpa 的值,此处列名和变量名相同,Inceptor 会认为两个都是变量名,也就是说此时where条件为2.0=2.0。

打印出执行上述 SQL 语句,一共删除了表 zara 中多少行的数据,由于 DELETE 语句中的 where 条件为 true,此处应该删除 zara 表中的全部记录。

嵌套命名

Inceptor 中如果在相同作用域内重复命名,会出错,但是可以在两个不同的作用域去声明两个相同的变量名,改变其中一个变量的值,不会影响另一个。即 Inceptor 中支持嵌套命名。

例 43. 嵌套命名
!set plsqlUseSlash true
DECLARE
   V1 STRING  -- 声明一个字符串类型的变量,名为 V1。
   V2 INT 
BEGIN
   V1 := 'HELLO' -- 给变量 V1 赋值。
   V2 := 123  
   DBMS_OUTPUT.PUT_LINE(V1)
   DBMS_OUTPUT.PUT_LINE(V2)

   DECLARE
     V1 BOOLEAN  -- 声明一个布尔值类型的变量,名为 V1。
     V3 DOUBLE
   BEGIN
     V1 := FALSE  -- 给变量 V1 赋值。
     V3 := 12.13
     DBMS_OUTPUT.PUT_LINE(V1)
     DBMS_OUTPUT.PUT_LINE(V3)
  END

DECLARE
   V4 STRING
BEGIN
   V4 := 'World'
   DBMS_OUTPUT.PUT_LINE(V4)
END
END;
/
复制

输出结果为:

output

HELLO

123

FALSE

12.13

World

赋值

在 PL/SQL 中,可以在声明变量的同时赋予初始值,也可以在声明变量之后,对变量进行赋值。在语句块或者子程序运行的时候,变量会被初始化,默认状况,即没有给变量赋值的情况下,变量会被初始化成 NULL 值。

例 44. 声明三个不同类型的变量
!set plsqlUseSlash true
DECLARE
   name STRING := 'ZHANGSAN'
   age INT
   grade DOUBLE
BEGIN
   age := 23
   DBMS_OUTPUT.PUT_LINE(name)
   DBMS_OUTPUT.PUT_LINE(age)
IF grade IS NULL THEN
   DBMS_OUTPUT.PUT_LINE('grade is NULL.')
END IF
END;
/
复制

输出结果为:

output

ZHANGSAN

23

grade is NULL.

赋予变量逻辑值

对于一个布尔值类型的变量,只能赋予其 FALSE,TRUE,或者 NULL 值。

例 45. 将逻辑值赋值给变量
!set plsqlUseSlash true
DECLARE
   done BOOLEAN
   counter INT:= 0
BEGIN
   done := FALSE
WHILE done != TRUE
LOOP
   counter := counter + 1
   done := (counter > 500)
END LOOP;
DBMS_OUTPUT.put_line ( 'the counter is:' || counter)
END;
/
复制

输出结果为:

output

the counter is:501

赋予变量查询结果

在 Inceptor 中可以使用 select into 语句将查询结果赋值给变量。

例 46. 将查询结果赋值给变量
!set plsqlUseSlash true
DECLARE
   id STRING
   time STRING
BEGIN
   SELECT trans_id,trans_time
      INTO id,time
      FROM transactions
      WHERE price=12.13;
   DBMS_OUTPUT.PUT_LINE('the id is:'||id)
   DBMS_OUTPUT.PUT_LINE('the time is:'||time)
END;
/
复制

输出结果为:

output

the id is:943197522

the time is:20140105100520