postgresql数据库日志查看_java

 

----------------------------
 ----------plsql的语言基础
 -------------------------------一个基础的plsql块,衍生的对象有函数,存储过程,匿名块等
 << LABEL >> --(optional)可选
 DECLARE    -- Declarative part (optional)--可选
   -- Declarations of local types, variables, & subprogramsBEGIN      -- Executable part (required)--必须
   -- Statements (which can use items declared in declarative part)[EXCEPTION -- Exception-handling part (optional)--可选
   -- Exception handlers for exceptions (errors) raised in executable part]
 END;----开启屏幕输出显示
 SET SERVEROUTPUT ON;--一切从helloworld开始
 BEGIN
     DBMS_Output.Put_Line('hello world');
 END;----一个典型的FOR循环
 BEGIN
   FOR someone IN (
     SELECT * FROM employees
     WHERE empno < 7600
     ORDER BY empno
   )
   LOOP
     DBMS_OUTPUT.PUT_LINE('ename = ' || someone.ename ||
                          ', job = ' || someone.job);
   END LOOP;
 END;
 /--数据库不区分大小写,
 --同时引用的时候可以没有双引号
 --变量声明时可以没有引号,也可以有
 \set SQLTERM /
 DECLARE
     "hello" varchar2(10) := 'hello';
 BEGIN
     DBMS_Output.Put_Line("hello");
 END;
 /
 或者
 DECLARE
     hello varchar2(10) := 'hello';
 BEGIN
     DBMS_OUTPUT.PUT_LINE("HELLO");
 END;
 --结果:
 HELLO
 或者
 DECLARE
 "HELLO" varchar2(10) := 'hello';
 BEGIN
 DBMS_OUTPUT.PUT_LINE(HELLO);
 END;
 --下列语句oracle输出报错,为撒???????????
 --KES输出正确
 DECLARE
     "hello" varchar2(100) := 'hello';
 BEGIN
     DBMS_OUTPUT.PUT_LINE(hello);
 END;错误报告:
 ORA-06550: 第 4 行, 第 23 列: 
 PLS-00201: 必须声明标识符 'HELLO'
 ORA-06550: 第 4 行, 第 2 列: 
 PL/SQL: Statement ignored
 06550. 00000 -  "line %s, column %s:\n%s"
 *Cause:    Usually a PL/SQL compilation error.---用户定义的标识符可以是中文
 --这个例子运行正确
 \set SQLTERM /
 DECLARE
     你好 varchar2(10) := 'hello';
 BEGIN
     DBMS_Output.Put_Line(你好);
 END;
 /
 --结果:
 hello --双引号在手,天下我有,这个变量on/off switch在双引号下也是可以的
 --双引号下一些标识符的约束不管用了
 \set SQLTERM /
 DECLARE
     "on/off switch" varchar2(10) := 'hello';
 BEGIN
     DBMS_Output.Put_Line("on/off switch");
 END;
 /
 结果
 HELLO--数据库不区分大小写
 --下列语句oracle运行报错,为撒???????
 \set SQLTERM /
 DECLARE
   "HELLO" varchar2(100) := 'hello';
 BEGIN
   DBMS_Output.Put_Line("Hello");
 END;
 /
 --KES运行结果:
 hello----个人理解,定义时双引号时可选的,引用该变量时双引号也是可选的
--保留字作为引用的用户定义标识符
 /*
 本例中第一个示例将保留字BEGIN加双引号后”BEGIN”,可以作为用户定义的标识符使用,引用该标识符时,不区分大小写;
 */
 \set SQLTERM /
 DECLARE
     "BEGIN" varchar2(15) := 'UPPERCASE';
 BEGIN
     DBMS_Output.Put_Line("BEGIN");
     DBMS_Output.Put_Line("Begin");
     DBMS_Output.Put_Line("begin");
     --DBMS_Output.Put_Line(bEgin); --关键字作为变量必须使用双引号
 END;
 /
 --结果:
 UPPERCASE
 UPPERCASE
 UPPERCASE--下列示例定义了”BEGIN”和”Begin”两个变量,但因为不区分大小写,所以认为是同一个变量,运行结果提示报错。
 \set SQLTERM /
 DECLARE
     "BEGIN" varchar2(15) := 'UPPERCASE';
     "Begin" varchar2(15) := 'Initial Capital';
 BEGIN
     DBMS_Output.Put_Line("BEGIN");
     DBMS_Output.Put_Line("Begin");
 END;
 /
 --结果:
 错误:  重复声明 在 ""Begin"" 或附近的----个人理解,关键字也可以作为变量,但是不建议这么做,但是关键字作为变量必须双引号
 --下列例子执行这是会换行的
 --PUT_LINE中换行,实际输出也跟着换行
 \set SQLTERM /
 BEGIN
     DBMS_OUTPUT.PUT_LINE('This string breaks
     here.');
 END;
 /
 --结果如下:
 This string breaks
 here.--如果上述例子不想换行,则使用字符串连接运算符(| |)构造字符串。
 --如下所示
 BEGIN
     DBMS_OUTPUT.PUT_LINE('This string breaks' || 
     ' here.');
 END;
 --结果如下:
 THIS STRING BREAKS HERE.--------注释功能-----------
 --单行注释
 --这个例子有4处单行注释。如下:
 \set SQLTERM /
 DECLARE
     howmany NUMBER;
     num_tables NUMBER;
 BEGIN
     -- Begin processing
     SELECT COUNT(*) INTO howmany   -- 没有分号,这个地方也可以注释
     FROM USER_OBJECTS
     WHERE OBJECT_TYPE = 'TABLE'; -- Check number of tables
     num_tables := howmany; -- Compute another value
 END;
 /--多行注释
 \set SQLTERM /
 DECLARE
     some_condition BOOLEAN;
     pi NUMBER := 3.1415926;  --pi
     radius NUMBER := 15;  --半径
     area NUMBER;  --可以存放浮点数
 BEGIN
     /* 执行简单的测试和赋值 */
     IF 2 + 2 = 4 THEN
         some_condition := TRUE;
         /* 我们期望THEN后的语句总是被执行 */
     END IF;
     /* 
      * 根据pi和半径计算圆的面积 
      * 并将结果转换成字符串,在PUT_LINE中输出显示
      * TO_CHAR()将结果转换成字符串
      * */
     area := pi* radius* radius;
     DBMS_OUTPUT.PUT_LINE('The area is: ' || TO_CHAR(area));
 END; 
 /
 --结果:
 The area is: 706.858335 --注意空格和排版换行等
 \set SQLTERM /
 DECLARE
     x NUMBER := 10;
     y NUMBER := 5;
     max NUMBER;
 BEGIN
     --IF x>y THEN max:=x;ELSE max:=y;END IF; -- 虽然正确,但是难以理解
     -- Easier to read:下面比较容易阅读
     IF x > y THEN
         max:=x;
     ELSE
         max:=y;
     END IF;
 END;
 /--声明变量,可以赋值,但是本例中未赋值,使用:=赋值
 \set SQLTERM /
 DECLARE
     part_number NUMBER(6); -- SQL data type
     part_name VARCHAR2(20); -- SQL data type
     in_stock BOOLEAN; -- PL/SQL-only data type
     part_price NUMBER(6,2); -- SQL data type
     part_description VARCHAR2(50); -- SQL data type
 BEGIN
     NULL;
 END;
 /----声明常量,常量需要添加关键字CONSTANT,常量必须初始化
 \set SQLTERM /
 DECLARE
     credit_limit CONSTANT REAL := 5000.00; -- SQL data type
     max_days_in_year CONSTANT INTEGER := 366; -- SQL data type
     URBAN_LEGEND CONSTANT BOOLEAN := FALSE; -- PL/SQL-only data type
   --urban_legend1 CONSTANT BOOLEAN; -- 常量必须初始化,不初始化会报错
 BEGIN
     NULL;
 END;
 / --变量在未赋值情况下
 \set SQLTERM /
 DECLARE
     counter INTEGER; -- 未赋值的情况下,初始值是NULL
 BEGIN
     counter := counter + 1; -- NULL + 1依然是 NULL
     IF counter IS NULL then  ---IS NULL 是个运算符
         DBMS_OUTPUT.PUT_LINE('counter is NULL.');
     END IF;
 END;
 /
 --结果:
 counter is NULL. ----------测试%TYPE属性------------
\set SQLTERM /
 drop table if exists user_profile;
 CREATE TABLE user_profile (
     id int NOT NULL,
     device_id int NOT NULL,
     gender varchar(14) NOT NULL,
     age int ,
     university varchar(32) NOT NULL,
     province varchar(32)  NOT null,
     gpa float
 );
 INSERT INTO user_profile VALUES(1,2138,'male',21,'北京大学','BeiJing',3.4);
 INSERT INTO user_profile VALUES(2,3214,'male',null,'复旦大学','Shanghai',4.0);
 INSERT INTO user_profile VALUES(3,6543,'female',20,'北京大学','BeiJing',3.2);
 INSERT INTO user_profile VALUES(4,2315,'female',23,'浙江大学','ZheJiang',3.6);
 INSERT INTO user_profile VALUES(5,5432,'male',25,'山东大学','Shandong',3.8);
 INSERT INTO user_profile VALUES(6,2131,'male',28,'北京师范大学','BeiJing',3.3);
 INSERT INTO USER_PROFILE VALUES(7,2240,'male',NULL,'清华大学','BeiJing',3.3);
 INSERT INTO user_profile VALUES(8,2241,'female',null,'北京大学','BeiJing',3.7);
 /
 SELECT * FROM USER_PROFILE;
 --
 \set SQLTERM /
 DECLARE
     id_test_TYPE user_profile.id%TYPE;
 begin
     DBMS_OUTPUT.PUT_LINE('id_test=' || id_test_TYPE);
 END;
 /
 --结果:
 id_test=     --实测结果为空--个人理解:id_test_TYPE的数据类型就是 user_profile表中id列的数据类型(%TYPE),即int;
 --比如下列这个就是能赋值,且正常输出123的例子
 \set SQLTERM /
 DECLARE
     id_test_TYPE user_profile.id%TYPE; --定义为表id_test_TYPE变量为user_profile表的id烈的数据类型
 begin
     id_test_TYPE := 123;
     DBMS_OUTPUT.PUT_LINE('id_test=' || id_test_TYPE);
 END;
 /
 --或者声明变量后直接赋值
 \set SQLTERM /
 DECLARE
     id_test_TYPE user_profile.id%type := 123;  --或者写成这样,
 begin
     DBMS_OUTPUT.PUT_LINE('id_test=' || id_test_TYPE);
 END;
 /
 --结果
 ID_TEST=123---NOT NULL约束,即必须初始化,不能为空
 DECLARE
   acct_id INTEGER(4) NOT NULL := 9999;
   a NATURALN                  := 9999;
   b POSITIVEN                 := 9999;
   c SIMPLE_INTEGER            := 9999;
 BEGIN
   NULL;
 END;
 /
 --声明的时候可以进行计算
 DECLARE
   hours_worked    INTEGER := 40;
   employee_count  INTEGER := 0;  pi     CONSTANT REAL := 3.14159;
   radius          REAL := 1;
   area            REAL := (pi * radius**2);
 BEGIN
   NULL;
 END;
 /-----------------------------------
 -----------作用域和可见性 --变量的可见性:全局均可见,但局部覆盖全局的变量
 --实际上和C语言是一样的
 -- 最外部块:
 DECLARE
   a CHAR;  -- Scope of a (CHAR) begins
   b REAL;    -- Scope of b begins
 BEGIN
   -- 可见变量: a (CHAR), b
   
   -- 第一个子块:
   DECLARE
     a INTEGER;  -- Scope of a (INTEGER) begins
     c REAL;       -- Scope of c begins
   BEGIN
     -- 可见变量: a (INTEGER), b, c,局部的变量将覆盖全局的
     NULL;
   END;          -- Scopes of a (INTEGER) and c end  -- 第二个子块:
   DECLARE
     d REAL;     -- Scope of d begins
   BEGIN
     -- 可见变量: a (CHAR), b, d
     NULL;
   END;          -- Scope of d ends-- 可见变量: a (CHAR), b
 END;            -- Scopes of a (CHAR) and b end
 /---这个案例说明,同名变量情况下局部的会覆盖全局的,
 \set SQLTERM /
 <<outer>>  -- label
 DECLARE
   birthdate DATE := TO_DATE('09-AUG-70', 'DD-MON-YY');
 BEGIN
   DECLARE
     birthdate DATE := TO_DATE('29-SEP-70', 'DD-MON-YY');
   BEGIN
     IF birthdate = outer.birthdate THEN
       DBMS_OUTPUT.PUT_LINE ('Same Birthday');
     ELSE
       DBMS_OUTPUT.PUT_LINE ('Different Birthday');
     END IF;
   END;
 END;
 /
 --结果:
 Different Birthday----不能在同一个作用域进行变量的重复声明,所有的数据库对象都有该限制,
 --PLS-00371: 'ID' 最多允许有一个声明\set SQLTERM /
 DECLARE
     id BOOLEAN;
     id VARCHAR2(5); -- duplicate identifier
 BEGIN
     id := FALSE;
 END;
 /
 --上述例子会报错--演示了存储过程的创建和调用,存储过程的声明,函数的调用
 --创建一个存储过程,接手一个参数,内部还创建了一个函数
 CREATE OR REPLACE PROCEDURE CHECK_CREDIT (CREDIT_LIMIT NUMBER) 
 AS
   rating NUMBER := 3;
   
   FUNCTION CHECK_RATING RETURN BOOLEAN --函数都是有返回值的吗?这里还处在存储过程的申明阶段
   IS --创建了一个函数,判断全局变量是否大于参数CREDIT_LIMIT,如果大于则局部赋值为CREDIT_LIMIT,且返回是否大于情况
     rating  NUMBER := 1;
     over_limit  BOOLEAN;
   BEGIN
     IF check_credit.rating <= credit_limit THEN  -- reference global variable引用全局变量
       over_limit := FALSE;
     ELSE
       OVER_LIMIT := TRUE;
       rating := credit_limit;                    -- reference local variable引用本地变量
     END IF;
     RETURN over_limit;
   END check_rating;
 BEGIN
   IF check_rating THEN  --判断函数的结果,直接使用函数名即可调用
     DBMS_OUTPUT.PUT_LINE
       ('Credit rating over limit (' || TO_CHAR(credit_limit) || ').  '
       || 'Rating: ' || TO_CHAR(RATING));
   ELSE  --全局小于传进来的数值则输出下列
     DBMS_OUTPUT.PUT_LINE
       ('Credit rating OK.  ' || 'Rating: ' || TO_CHAR(rating));
   END IF;
 END;
 /
 --执行存储过程需要包含下列三行
 BEGIN
   check_credit(8);
 END;
 /
 --如果想通过一行代码调用存储过程,可以用call
  CALL   CHECK_CREDIT(8); --不要再同一个作用域声明变量两次,下列会报错
 DECLARE
   id  BOOLEAN;
   id  VARCHAR2(5);  -- duplicate identifier
 BEGIN
   id := FALSE;
 END;
 /
 报错结果:
   id := FALSE;
   *
 ERROR at line 5:
 ORA-06550: line 5, column 3:
 PLS-00371: at most one declaration for 'ID' is permitted
 ORA-06550: line 5, column 3:
 PL/SQL: STATEMENT IGNORED---不同的子域中声明两次,是可以的
 DECLARE
   PROCEDURE p  --存储过程还可以这样创建???
   IS
     x VARCHAR2(1);
   BEGIN
     x := 'a';  -- Assign the value 'a' to x
     DBMS_OUTPUT.PUT_LINE('In procedure p, x = ' || x);
   END;
  
   PROCEDURE q
   IS
     x VARCHAR2(1);
   BEGIN
     x := 'b';  -- Assign the value 'b' to x
     DBMS_OUTPUT.PUT_LINE('In procedure q, x = ' || x);
   END;
  
 BEGIN
   p;
   q;
 END;
 /
 结果
 In procedure p, x = a
 IN PROCEDURE Q, X = B---在下面的例子中,echo即是块的名字,也是子模块的名字
 --显然通过民国结果来看,不管是变量还是模块名字,局部都是会覆盖全局的
 <<echo>>
 DECLARE
   x  NUMBER := 5;
   
   PROCEDURE echo AS
     x  NUMBER := 0;
   BEGIN
     DBMS_OUTPUT.PUT_LINE('x = ' || x);
     DBMS_OUTPUT.PUT_LINE('echo.x = ' || echo.x);
   END;
  
 BEGIN
   echo;
 END;
 /
 结果
 x = 0
 ECHO.X = 0--标签的局部覆盖:
 --
 <<COMPUTE_RATIO>>
 <<another_label>>--连个外部模块的标签
 DECLARE
   numerator   NUMBER := 22;
   denominator NUMBER := 7;
 BEGIN
   <<another_label>>
   DECLARE
     denominator NUMBER := 0;
   BEGIN
     DBMS_OUTPUT.PUT_LINE('Ratio with compute_ratio.denominator = ');
     DBMS_OUTPUT.PUT_LINE(numerator/compute_ratio.denominator);--这个是正确的的,因为它引用的是外部的denominator参数,这个值不是0
  
     DBMS_OUTPUT.PUT_LINE('Ratio with another_label.denominator = ');
     DBMS_OUTPUT.PUT_LINE(numerator/another_label.denominator);--这个会报错,因为引用的是内部的,这个值是0
  
   EXCEPTION
     WHEN ZERO_DIVIDE THEN
       DBMS_OUTPUT.PUT_LINE('Divide-by-zero error: can''t divide '
         || numerator || ' by ' || denominator);
     WHEN OTHERS THEN
       DBMS_OUTPUT.PUT_LINE('Unexpected error.');
   END another_label;
 END compute_ratio;
 /
 结果
 Ratio with compute_ratio.denominator =
 3.14285714285714285714285714285714285714
 RATIO WITH ANOTHER_LABEL.DENOMINATOR =
 Divide-by-zero error: cannot divide 22 by 0 ------------------------------------------
 -----给变量赋值的多种方式
 ------------------------------------------
 ---变量的赋值语句是:=
 DECLARE  -- You can assign initial values here,也可以在生命模块赋值
   wages          NUMBER;
   hours_worked   NUMBER := 40;
   hourly_salary  NUMBER := 22.50;
   bonus          NUMBER := 150;
   country        VARCHAR2(128);
   counter        NUMBER := 0;
   done           BOOLEAN;
   valid_id       BOOLEAN;
   emp_rec1       employees%ROWTYPE;
   emp_rec2       employees%ROWTYPE;
   TYPE commissions IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
   comm_tab       commissions;
  
 BEGIN  -- You can assign values here too也可以在执行语句模块赋值
   wages := (hours_worked * hourly_salary) + bonus;
   country := 'France';
   country := UPPER('Canada');
   done := (counter > 100);
   valid_id := TRUE;
   emp_rec1.first_name := 'Antonio';
   emp_rec1.last_name := 'Ortiz';
   emp_rec1 := emp_rec2;
   comm_tab(5) := 20000 * 0.15;
 END;
 //*
 --除了:=方式赋值,也可以使用下一种方式:即SELECT ......INTO....FROM.......
 SELECT select_item [, select_item ]... 
 INTO variable_name [, variable_name ]...
 FROM TABLE_NAME;
 */---例子:
 DECLARE
   bonus   NUMBER(8,2);
 BEGIN
   SELECT salary * 0.10 INTO bonus
   FROM employees
   WHERE employee_id = 100;
 END;DBMS_OUTPUT.PUT_LINE('bonus = ' || TO_CHAR(bonus));
 /
 上面这是ORACLE的例子,写一个自己的例子:
 DECLARE
   resultval   NUMBER(8,2);
 BEGIN
   SELECT gpa * 10 INTO resultval
   FROM USER_PROFILE
   WHERE GPA = 3.4;
   DBMS_OUTPUT.PUT_LINE('resultval = ' || TO_CHAR(RESULTVAL));
 END;
 --结果:
 bonus = 34 --将值作为子程序的参数分配给变量
 DECLARE
   emp_sal  NUMBER(8,2);
  
   PROCEDURE adjust_salary (  ---子程序adjust_salary的参数,用于调整薪水
     emp        NUMBER, 
     sal IN OUT NUMBER,
     adjustment NUMBER
   ) IS
   BEGIN
     sal := sal + adjustment;
   END;
  
 BEGIN
   SELECT sal INTO emp_sal
   FROM employees
   WHERE empno = 7369;
  
   DBMS_OUTPUT.PUT_LINE('Before invoking procedure, emp_sal: ' || emp_sal);  --引用子程序之后
  
   adjust_salary (7369, emp_sal, 1000); --内部调用存储过程
  
   DBMS_OUTPUT.PUT_LINE('After invoking procedure, emp_sal: ' || emp_sal);  --引用子程序之后
 END;
 /
 --select * from employees;--结果
 Before invoking procedure, emp_sal: 800
 AFTER invoking PROCEDURE, emp_sal: 1800-----------------------------
 -------给布尔变量赋值
 -----------------------------
 DECLARE
   done    BOOLEAN;              -- Initial value is NULL by default
   counter NUMBER := 0;
 BEGIN
   done := FALSE;                -- Assign literal value
   WHILE done != TRUE            -- Compare to literal value
     LOOP
       counter := counter + 1;
       done := (counter > 500);  -- Assign value of BOOLEAN expression
     END LOOP;
 END;
 / ------------------------------------------------------
 ------------------------------------------------------
 ---PLSQL控制语句-------------------------------------
 ------------------------------------------------------
 --------------------------------------------------------CASE的典型结构----根据选择器,
 --选择器是一个表达式(通常是单个变量)
 CASE selector
 WHEN selector_value_1 THEN statements_1
 WHEN selector_value_2 THEN statements_2
 ...
 WHEN selector_value_n THEN statements_n
 [ ELSE
   else_statements ]
 END CASE;] --一个简单的例子
 --根据值进行简单比较,即根据表达式的结果是否匹配进行比较
 DECLARE
   grade CHAR(1);
 BEGIN
   grade := 'A';  --注意在字符中,A和a是不一样的
   --
   CASE grade
     WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
     WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
     WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
     WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
     WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
     ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
   END CASE;
 END;
 /
 --The searched CASE statement(搜索CASE语句) runs the first statements for which condition is true. Remaining conditions are not evaluated. 
 --If no condition is true, the CASE statement runs else_statements if they exist and raises the predefined exception CASE_NOT_FOUND otherwise. 
 --(For complete syntax, see "CASE Statement".)
 --是根据when的布尔表达式来判断是否要执行当前语句
 CASE
 WHEN condition_1 THEN statements_1
 WHEN condition_2 THEN statements_2
 ...
 WHEN condition_n THEN statements_n
 [ ELSE
   else_statements ]
 END CASE;]--例子--根据搜索进行匹配
 set serveroutput on
 DECLARE
   grade CHAR(1);
 BEGIN
   grade := 'B';
   
   CASE
     WHEN grade = 'A' THEN 
       DBMS_OUTPUT.PUT_LINE('Excellent');
     WHEN grade = 'B' THEN 
       DBMS_OUTPUT.PUT_LINE('Very Good');
     WHEN grade = 'C' THEN 
       DBMS_OUTPUT.PUT_LINE('Good');
     WHEN grade = 'D' THEN 
       DBMS_OUTPUT.PUT_LINE('Fair');
     WHEN grade = 'F' THEN 
       DBMS_OUTPUT.PUT_LINE('Poor');
     ELSE 
       DBMS_OUTPUT.PUT_LINE('No such grade');
   END CASE;
 END;
 /
 ---用异常表达代替ELSE与语句
 DECLARE
   grade CHAR(1);
 BEGIN
   grade := 'G';
   
   CASE
     WHEN grade = 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
     WHEN grade = 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
     WHEN grade = 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
     WHEN grade = 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
     WHEN grade = 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
   END CASE;
 EXCEPTION
   WHEN CASE_NOT_FOUND THEN
     DBMS_OUTPUT.PUT_LINE('No such grade');
 END;
 /------------------------------------------
 ------------FOR循环------------------------
 ------------------------------------------
 --下列例子说明,迭代i是不能在可见域进行值得修改的,即迭代变量不可修改。
 BEGIN
   FOR i IN 1..3 LOOP
     IF i < 3 THEN
       DBMS_OUTPUT.PUT_LINE (TO_CHAR(i));
     ELSE
       i := 2;
     END IF;
   END LOOP;
 END;--这个语句就是试图在FOR循环外边进行i索引的引用,然后会报错
 BEGIN
   FOR i IN 1..3 LOOP
     DBMS_OUTPUT.PUT_LINE ('Inside loop, i is ' || TO_CHAR(i));
   END LOOP;
   
   DBMS_OUTPUT.PUT_LINE ('Outside loop, i is ' || TO_CHAR(i));
 END;
 / 
 --If the index of a FOR LOOP statement has the same name as a variable declared in an enclosing block, 
 --the local implicit declaration hides the other declaration, as this example shows.DECLARE
   i NUMBER := 5;
 BEGIN
   FOR i IN 1..3 LOOP
     DBMS_OUTPUT.PUT_LINE ('Inside loop, i is ' || TO_CHAR(i));
   END LOOP;
   
   DBMS_OUTPUT.PUT_LINE ('Outside loop, i is ' || TO_CHAR(i));
 END;
 /--要想在循环体中引用外部的i可以使用标签
 <<main>>  -- Label block.
 DECLARE
   i NUMBER := 5;
 BEGIN
   FOR i IN 1..3 LOOP
     DBMS_OUTPUT.PUT_LINE ('local: ' || TO_CHAR(i) || ', global: ' || TO_CHAR(MAIN.i)  -- Qualify reference with block label.
     );
   END LOOP;
 END MAIN;
 /
 --使用标签了区分内部和外部相同的迭代i(循环体前是可以打标签的)
 BEGIN
   <<outer_loop>>
   FOR i IN 1..3 LOOP
     <<inner_loop>>
     FOR i IN 1..3 LOOP
       IF outer_loop.i = 2 THEN
         DBMS_OUTPUT.PUT_LINE
           ('outer: ' || TO_CHAR(outer_loop.i) || ' inner: '
            || TO_CHAR(inner_loop.i));
       END IF;
     END LOOP inner_loop;
   END LOOP outer_loop;
 END;
 /--结果
 outer: 2 inner: 1
 OUTER: 2 INNER: 2
 outer: 2 inner: 3 /
 /
 ------------------------------------------------------
 ------------------------------------------------------
 ---清理实验表等数据-------------------------------------
 ------------------------------------------------------
 ------------------------------------------------------
 ----创建实验表user_profile
 \set SQLTERM /
 drop table if exists user_profile;
 CREATE TABLE user_profile (
     id int NOT NULL,
     device_id int NOT NULL,
     gender varchar(14) NOT NULL,
     age int ,
     university varchar(32) NOT NULL,
     province varchar(32)  NOT null,
     gpa float
 );
 INSERT INTO user_profile VALUES(1,2138,'male',21,'北京大学','BeiJing',3.4);
 INSERT INTO user_profile VALUES(2,3214,'male',null,'复旦大学','Shanghai',4.0);
 INSERT INTO user_profile VALUES(3,6543,'female',20,'北京大学','BeiJing',3.2);
 INSERT INTO user_profile VALUES(4,2315,'female',23,'浙江大学','ZheJiang',3.6);
 INSERT INTO user_profile VALUES(5,5432,'male',25,'山东大学','Shandong',3.8);
 INSERT INTO user_profile VALUES(6,2131,'male',28,'北京师范大学','BeiJing',3.3);
 INSERT INTO USER_PROFILE VALUES(7,2240,'male',NULL,'清华大学','BeiJing',3.3);
 INSERT INTO USER_PROFILE VALUES(8,2241,'female',NULL,'北京大学','BeiJing',3.7);
 /---创建实验表(oracle和KES实测通过)
DROP TABLE DEPT;
 CREATE TABLE DEPT(
   DEPTNO NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY,
     DNAME VARCHAR2(14) ,
     LOC VARCHAR2(13) 
 );
 INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK');
 INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');
 INSERT INTO DEPT VALUES (30,'SALES','CHICAGO');
 INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON');
 --查询该表
 SELECT * FROM dept;
 --创建表EMP
 DROP TABLE employees;
 CREATE TABLE employees(
   EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY,
     ENAME VARCHAR2(10),
     JOB VARCHAR2(9),
     MGR NUMBER(4),
     HIREDATE DATE,
     SAL NUMBER(7,2),
     COMM NUMBER(7,2),
     DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES DEPT
 );
   
 INSERT INTO employees VALUES (7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);
 INSERT INTO employees VALUES (7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
 INSERT INTO employees VALUES (7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
 INSERT INTO employees VALUES (7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);
 INSERT INTO employees VALUES (7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);
 INSERT INTO employees VALUES (7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30);
 INSERT INTO employees VALUES (7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10);
 INSERT INTO employees VALUES (7788,'SCOTT','ANALYST',7566,to_date('13-1-1987','dd-mm-yyyy'),3000,NULL,20);
 INSERT INTO employees VALUES (7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10);
 INSERT INTO employees VALUES (7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);
 INSERT INTO employees VALUES (7876,'ADAMS','CLERK',7788,to_date('13-4-1987','dd-mm-yyyy'),1100,NULL,20);
 INSERT INTO employees VALUES (7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30);
 INSERT INTO employees VALUES (7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20);
 INSERT INTO employees VALUES (7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);
 SELECT * FROM employees; DROP TABLE BONUS;
 CREATE TABLE BONUS
     (
     ENAME VARCHAR2(10)    ,
     JOB VARCHAR2(9)  ,
     SAL NUMBER,
     COMM NUMBER
     ) ;
 SELECT * FROM BONUS;DROP TABLE SALGRADE;
 CREATE TABLE SALGRADE( 
   GRADE NUMBER,
     LOSAL NUMBER,
     HISAL NUMBER 
 );
 INSERT INTO SALGRADE VALUES (1,700,1200);
 INSERT INTO SALGRADE VALUES (2,1201,1400);
 INSERT INTO SALGRADE VALUES (3,1401,2000);
 INSERT INTO SALGRADE VALUES (4,2001,3000);
 INSERT INTO SALGRADE VALUES (5,3001,9999);
 SELECT * FROM SALGRADE;