• Oracle主机变量锚定、游标变量


    System Global varaibles.

    系统全局变量,只要sqlplus不断开连接,name这个变量会一直存在,切换用户会话对其无影响。

    1. SQL> -- 非plsql变量
    2. SQL>
    3. SQL> var name varchar2(20)
    4. SQL>
    5. SQL> var
    6. variable name
    7. datatype VARCHAR2(20)
    8. SQL>
    9. SQL> select :name from dual;
    10. :NAME
    11. --------------------------------------------------------------------------------------------------------------------------------
    12. SQL> select * from tab;
    13. TNAME TABTYPE CLUSTERID
    14. -------------------------------------------------------------------------------------------------------------------------------- ------------- ----------
    15. DEPARTMENTS TABLE
    16. EMPLOYEES TABLE
    17. SQL> conn scott/tiger@PDB1
    18. Connected.
    19. SQL>
    20. SQL> show user
    21. USER is "SCOTT"
    22. SQL>
    23. SQL> begin
    24. 2 select ename into :name from emp where empno=7839;
    25. 3 end;
    26. 4 /
    27. PL/SQL procedure successfully completed.
    28. SQL> select :name from dual;
    29. :NAME
    30. --------------------------------------------------------------------------------------------------------------------------------
    31. KING
    32. SQL>

     

    使用%type简化变量的声明, 使用%rowtype简化record(复合变量)的声明

    1. declare
    2. v_ename varchar2(20);
    3. v_hiredate date;
    4. BEGIN
    5. select ename,hiredate into v_ename,v_hiredate from emp where empno=7788;
    6. dbms_output.put_line(v_ename);
    7. end;
    8. /
    9. --锚定:
    10. /*简化变量的声明*/
    11. declare
    12. v_ename emp.ename%type;
    13. v_hiredate date;
    14. BEGIN
    15. select ename,hiredate into v_ename,v_hiredate from emp where empno=7788;
    16. dbms_output.put_line(v_ename);
    17. end;
    18. /
    19. 方法一:
    20. DECLARE
    21. /*标量*/
    22. v_deptno number;
    23. v_dname varchar2(10);
    24. v_loc varchar2(13);
    25. BEGIN
    26. select * into from dept where deptno=10;
    27. end;
    28. /
    29. 方法二
    30. DECLARE
    31. /*复合变量*/
    32. type dept_record is record
    33. (deptno number,
    34. dname varchar2(10),
    35. loc varchar2(13));
    36. r1 dept_record;
    37. BEGIN
    38. select * into r1 from dept where deptno=10;
    39. end;
    40. /
    41. 方法三
    42. /*简化记录的声明*/
    43. DECLARE
    44. r1 dept%ROWTYPE;
    45. BEGIN
    46. select * into r1 from dept where deptno=10;
    47. dbms_output.put_line(r1.deptno||' '||r1.dname);
    48. end;
    49. /

    Cursor variables

    1. 游标变量
    2. 使用游标变量
    3. --声明
    4. 声明: 初始化游标变量标示符,将游标变量标示符和一个子查询关联在一起。
    5. --打开
    6. 打开: 根据子查询取数据库中表中的数据填充内存上下文
    7. --获取
    8. 获取: 从游标内存上下文取值填充到record ,游标内存上下文中的值每取出一行就丢弃一行
    9. --关闭
    10. 关闭: 将游标内存上下文释放
    11. DECLARE
    12. cursor c1 is select * from dept; -- 声明
    13. r1 c1%ROWTYPE;
    14. BEGIN
    15. open c1; --打开
    16. fetch c1 into r1; -- 获取
    17. dbms_output.put_line(r1.deptno||' '||r1.dname||' '||r1.loc);
    18. close c1; -- 关闭
    19. END;
    20. /
    21. /*游标loop循环*/
    22. DECLARE
    23. cursor c1 is select * from dept; -- 声明
    24. r1 c1%ROWTYPE;
    25. BEGIN
    26. open c1; --打开
    27. LOOP
    28. fetch c1 into r1; -- 获取
    29. exit when c1%notfound;
    30. dbms_output.put_line(r1.deptno||' '||r1.dname||' '||r1.loc);
    31. end loop;
    32. close c1; -- 关闭
    33. END;
    34. /
    35. /*游标for循环*/
    36. DECLARE
    37. cursor c1 is select * from dept;
    38. BEGIN
    39. for r1 in c1
    40. loop
    41. dbms_output.put_line(r1.deptno||' '||r1.dname||' '||r1.loc);
    42. end loop;
    43. END;
    44. /
    45. /*隐式游标*/
    46. BEGIN
    47. for r1 in (elect * from dept)
    48. loop
    49. dbms_output.put_line(r1.deptno||' '||r1.dname||' '||r1.loc);
    50. end loop;
    51. END;
    52. /
    53. 游标属性:
    54. 游标名字 %rowcount : 从游标内存上下文获得的行的数量
    55. 游标名字 %found : 从游标内存上下文获得了行返回true
    56. 游标名字 %notfound : 从游标内存上下文取不到数据返回true
    57. 游标名字 %isopen : 游标如果打开返回true
    58. DECLARE
    59. cursor c1 is select * from dept; -- 声明
    60. r1 c1%ROWTYPE;
    61. BEGIN
    62. open c1; --打开
    63. LOOP
    64. fetch c1 into r1; -- 获取
    65. exit when c1%notfound;
    66. dbms_output.put_line(r1.deptno||' '||r1.dname||' '||r1.loc);
    67. end loop;
    68. close c1; -- 关闭
    69. END;
    70. /

    The cursor with parameter:

    1. SQL>
    2. SQL>
    3. SQL>
    4. SQL> declare
    5. 2 cursor c1 is select deptno from dept;
    6. 3 cursor c2 (p_deptno number) is select ename,sal,deptno from emp where deptno=p_deptno order by sal desc;
    7. 4 begin
    8. 5 for r1 in c1 loop
    9. 6 for r2 in c2 (r1.deptno) loop
    10. 7 exit when c2%rowcount>2;
    11. 8 dbms_output.put_line(chr(10)||r2.ename||' '||r2.sal||' '||r2.deptno);
    12. 9 end loop;
    13. 10 end loop;
    14. 11 end;
    15. 12 /
    16. KING 5000 10
    17. CLARK 2450 10
    18. SCOTT 3000 20
    19. FORD 3000 20
    20. BLAKE 2850 30
    21. ALLEN 1600 30
    22. PL/SQL procedure successfully completed.
    23. SQL>

    exception process:

    1.deal with predefine exception

    1. [root@oracle-db-19c ~]# su - oracle
    2. [oracle@oracle-db-19c ~]$
    3. [oracle@oracle-db-19c ~]$
    4. [oracle@oracle-db-19c ~]$ sqlplus / as sysdba
    5. SQL*Plus: Release 19.0.0.0.0 - Production on Sat Nov 19 13:43:23 2022
    6. Version 19.3.0.0.0
    7. Copyright (c) 1982, 2019, Oracle. All rights reserved.
    8. Connected to:
    9. Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
    10. Version 19.3.0.0.0
    11. SQL> alter session set container=PDB1;
    12. Session altered.
    13. SQL> set pagesize 200
    14. SQL> set linesize 200
    15. SQL>
    16. SQL> conn scot/tiger@PDB1
    17. ERROR:
    18. ORA-01017: invalid username/password; logon denied
    19. Warning: You are no longer connected to ORACLE.
    20. SQL> conn scott/tiger@PDB1;
    21. Connected.
    22. SQL>
    23. SQL>
    24. SQL> set serveroutput on
    25. SQL>
    26. SQL> declare
    27. 2 v_ename varchar2(10);
    28. 3 begin
    29. 4 select ename into v_ename from emp where empno=&p_empno;
    30. 5 dbms_output.put_line(v_ename);
    31. 6 exception
    32. 7 when no_data_found then
    33. 8 dbms_output.put_line('check out no this person');
    34. 9 end;
    35. 10 /
    36. Enter value for p_empno: 7788
    37. old 4: select ename into v_ename from emp where empno=&p_empno;
    38. new 4: select ename into v_ename from emp where empno=7788;
    39. SCOTT
    40. PL/SQL procedure successfully completed.
    41. SQL> /
    42. Enter value for p_empno: 111111
    43. old 4: select ename into v_ename from emp where empno=&p_empno;
    44. new 4: select ename into v_ename from emp where empno=111111;
    45. check out no this person
    46. PL/SQL procedure successfully completed.
    47. SQL>
    48. SQL> declare
    49. 2 v_ename varchar2(10);
    50. 3 begin
    51. 4 select ename into v_ename from emp where deptno=10;
    52. 5 dbms_output.put_line(v_ename);
    53. 6 exception
    54. 7 when no_data_found then
    55. 8 dbms_output.put_line('check out no this person');
    56. 9 when too_many_rows then
    57. 10 dbms_output.put_line('put into too many variables into scalar!');
    58. 11 end;
    59. 12 /
    60. put into too many variables into scalar!
    61. PL/SQL procedure successfully completed.
    62. SQL>
    1. SQL> declare
    2. 2 v_flag char(1);
    3. 3 v_deptno number:=&p_deptno;
    4. 4 begin
    5. 5 select 'A' into v_flag from dept where deptno = v_deptno;
    6. 6 dbms_output.put_line(v_deptno||' department exists');
    7. 7 exception
    8. 8 when no_data_found then
    9. 9 dbms_output.put_line(v_deptno||' department not exists');
    10. 10 end;
    11. 11 /
    12. Enter value for p_deptno: 10
    13. old 3: v_deptno number:=&p_deptno;
    14. new 3: v_deptno number:=10;
    15. 10 department exists
    16. PL/SQL procedure successfully completed.
    17. SQL> /
    18. Enter value for p_deptno: 1
    19. old 3: v_deptno number:=&p_deptno;
    20. new 3: v_deptno number:=1;
    21. 1 department not exists
    22. PL/SQL procedure successfully completed.
    23. SQL>

     

    2.catch oracle error

    1. SQL> declare
    2. 2 my_err exception;
    3. 3 pragma exception_init(my_err,-2291);
    4. 4 begin
    5. 5 update emp set deptno=80 where empno=7788;
    6. 6 exception
    7. 7 when my_err then
    8. 8 dbms_output.put_line('parent key not found');
    9. 9 end;
    10. 10 /
    11. parent key not found
    12. PL/SQL procedure successfully completed.
    13. SQL>

    2.2 use others to catch all of the EXCEPTIONS what we not considered
     

    DECLARE
      v_flag char(1);
      v_deptno number:=&p_deptno;
    BEGIN
      select 'A' into v_flag from dept where deptno=v_deptno;
    EXCEPTION
      when others THEN
        dbms_output.put_line(sqlcode||' ; '||SQLERRM);
    END;

     

    1. SQL>
    2. SQL>
    3. SQL> DECLARE
    4. 2 v_flag char(1);
    5. 3 v_deptno number:=&p_deptno;
    6. 4 BEGIN
    7. 5 select 'A' into v_flag from dept where deptno=v_deptno;
    8. 6 EXCEPTION
    9. 7 when others THEN
    10. 8 dbms_output.put_line(sqlcode||' ; '||SQLERRM);
    11. 9 END;
    12. 10 /
    13. Enter value for p_deptno: 10
    14. old 3: v_deptno number:=&p_deptno;
    15. new 3: v_deptno number:=10;
    16. PL/SQL procedure successfully completed.
    17. SQL>
    18. SQL> /
    19. Enter value for p_deptno: 11
    20. old 3: v_deptno number:=&p_deptno;
    21. new 3: v_deptno number:=11;
    22. 100 ; ORA-01403: no data found
    23. PL/SQL procedure successfully completed.
    24. SQL>

    3.custom exception ora-20000 ~ ora-20999

    DECLARE
      my_err EXCEPTION;
      PRAGMA exception_init(my_err,-20000);
    BEGIN
      if to_char(sysdate,'DY') IN ('SAT','SUN') THEN
        RAISE_APPLICATION_ERROR(-20000,'');
      ELSE
        UPDATE EMP SET SAL=SAL+100;
      END IF;
    EXCEPTION
      WHEN MY_ERR THEN
        dbms_output.put_line('salary can not be modified!');
    END;
    /

    1. SQL>
    2. SQL>
    3. SQL>
    4. SQL> DECLARE
    5. 2 my_err EXCEPTION;
    6. 3 PRAGMA exception_init(my_err,-20000);
    7. 4 BEGIN
    8. 5 if to_char(sysdate,'DY') IN ('SAT','SUN') THEN
    9. 6 RAISE_APPLICATION_ERROR(-20000,'');
    10. 7 ELSE
    11. 8 UPDATE EMP SET SAL=SAL+100;
    12. 9 END IF;
    13. 10 EXCEPTION
    14. 11 WHEN MY_ERR THEN
    15. 12 dbms_output.put_line('salary can not be modified!');
    16. 13 END;
    17. 14 /
    18. salary can not be modified!
    19. PL/SQL procedure successfully completed.
    20. SQL>

    4. Anonymous blocks translate into Name the block(procedure, function, package,trigger)

    1. SQL>
    2. SQL> create or replace procedure add_sal
    3. 2 is
    4. 3 begin
    5. 4 update emp set sal=sal*1.1;
    6. 5 end;
    7. 6 /
    8. Procedure created.
    9. SQL> select * from emp;
    10. EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
    11. ---------- ---------- --------- ---------- --------- ---------- ---------- ----------
    12. 7369 SMITH CLERK 7902 17-DEC-80 800 20
    13. 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
    14. 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
    15. 7566 JONES MANAGER 7839 02-APR-81 2975 20
    16. 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
    17. 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
    18. 7782 CLARK MANAGER 7839 09-JUN-81 2450 10
    19. 7788 SCOTT ANALYST 7566 24-JAN-87 3000 20
    20. 7839 KING PRESIDENT 17-NOV-81 5000 10
    21. 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
    22. 7876 ADAMS CLERK 7788 02-APR-87 1100 20
    23. 7900 JAMES CLERK 7698 03-DEC-81 950 30
    24. 7902 FORD ANALYST 7566 03-DEC-81 3000 20
    25. 7934 MILLER CLERK 7782 23-JAN-82 1300 10
    26. 14 rows selected.
    27. SQL> exec add_sal;
    28. PL/SQL procedure successfully completed.
    29. SQL> select * from emp;
    30. EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
    31. ---------- ---------- --------- ---------- --------- ---------- ---------- ----------
    32. 7369 SMITH CLERK 7902 17-DEC-80 880 20
    33. 7499 ALLEN SALESMAN 7698 20-FEB-81 1760 300 30
    34. 7521 WARD SALESMAN 7698 22-FEB-81 1375 500 30
    35. 7566 JONES MANAGER 7839 02-APR-81 3272.5 20
    36. 7654 MARTIN SALESMAN 7698 28-SEP-81 1375 1400 30
    37. 7698 BLAKE MANAGER 7839 01-MAY-81 3135 30
    38. 7782 CLARK MANAGER 7839 09-JUN-81 2695 10
    39. 7788 SCOTT ANALYST 7566 24-JAN-87 3300 20
    40. 7839 KING PRESIDENT 17-NOV-81 5500 10
    41. 7844 TURNER SALESMAN 7698 08-SEP-81 1650 0 30
    42. 7876 ADAMS CLERK 7788 02-APR-87 1210 20
    43. 7900 JAMES CLERK 7698 03-DEC-81 1045 30
    44. 7902 FORD ANALYST 7566 03-DEC-81 3300 20
    45. 7934 MILLER CLERK 7782 23-JAN-82 1430 10
    46. 14 rows selected.
    47. SQL> roll
    48. Rollback complete.
    49. SQL> select * from emp;
    50. EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
    51. ---------- ---------- --------- ---------- --------- ---------- ---------- ----------
    52. 7369 SMITH CLERK 7902 17-DEC-80 800 20
    53. 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
    54. 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
    55. 7566 JONES MANAGER 7839 02-APR-81 2975 20
    56. 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
    57. 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
    58. 7782 CLARK MANAGER 7839 09-JUN-81 2450 10
    59. 7788 SCOTT ANALYST 7566 24-JAN-87 3000 20
    60. 7839 KING PRESIDENT 17-NOV-81 5000 10
    61. 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
    62. 7876 ADAMS CLERK 7788 02-APR-87 1100 20
    63. 7900 JAMES CLERK 7698 03-DEC-81 950 30
    64. 7902 FORD ANALYST 7566 03-DEC-81 3000 20
    65. 7934 MILLER CLERK 7782 23-JAN-82 1300 10
    66. 14 rows selected.
    67. SQL>

    1. SQL>
    2. SQL> create or replace procedure add_sal2(p_empno in number, p_sal number) is
    3. 2 begin
    4. 3 update emp set sal = p_sal where empno = p_empno;
    5. 4 end;
    6. 5 /
    7. Procedure created.
    8. SQL> desc add_sal
    9. PROCEDURE add_sal
    10. SQL> desc add_sal2
    11. PROCEDURE add_sal2
    12. Argument Name Type In/Out Default?
    13. ------------------------------ ----------------------- ------ --------
    14. P_EMPNO NUMBER IN
    15. P_SAL NUMBER IN
    16. SQL>
    17. SQL> exec add_sal2(7369,1500);
    18. PL/SQL procedure successfully completed.
    19. SQL> select * from emp where empno=7369;
    20. EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
    21. ---------- ---------- --------- ---------- --------- ---------- ---------- ----------
    22. 7369 SMITH CLERK 7902 17-DEC-80 1500 20
    23. SQL> roll
    24. Rollback complete.
    25. SQL> select * from emp where empno=7369;
    26. EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
    27. ---------- ---------- --------- ---------- --------- ---------- ---------- ----------
    28. 7369 SMITH CLERK 7902 17-DEC-80 800 20
    29. SQL>
    1. SQL> create or replace procedure get_emp(p_empno in number,
    2. 2 v_ename out varchar2,
    3. 3 v_sal out number) is
    4. 4 begin
    5. 5 select ename, sal into v_ename, v_sal from emp where empno = p_empno;
    6. 6 end;
    7. 7 /
    8. Procedure created.
    9. SQL> desc get_emp;
    10. PROCEDURE get_emp
    11. Argument Name Type In/Out Default?
    12. ------------------------------ ----------------------- ------ --------
    13. P_EMPNO NUMBER IN
    14. V_ENAME VARCHAR2 OUT
    15. V_SAL NUMBER OUT
    16. SQL>
    17. SQL>
    18. SQL> declare
    19. 2 g_ename varchar2(20);
    20. 3 g_sal number;
    21. 4 begin
    22. 5 get_emp(7499,g_ename,g_sal);
    23. 6 dbms_output.put_line(g_ename||' '||g_sal);
    24. 7 end;
    25. 8 /
    26. PL/SQL procedure successfully completed.
    27. SQL> set serveroutput on
    28. SQL> /
    29. ALLEN 1600
    30. PL/SQL procedure successfully completed.
    31. SQL>
    1. SQL> create or replace procedure get_emp2(p_test in out number) is
    2. 2 begin
    3. 3 select sal into p_test from emp where empno = p_test;
    4. 4 end;
    5. 5 /
    6. Procedure created.
    7. SQL> var g_test number
    8. SQL> exec :g_test:=7566;
    9. PL/SQL procedure successfully completed.
    10. SQL> exec get_emp2(:g_test);
    11. PL/SQL procedure successfully completed.
    12. SQL>
  • 相关阅读:
    RabbitMQ如何实现延迟消息?
    打造个性化日历:Python编程实现,选择适合你的方式!
    CV攻城狮入门VIT(vision transformer)之旅——VIT代码实战篇
    前端研习录(30)——JavaScript 事件讲解及示例分析
    Web安全—Web漏扫工具NetSparker安装与使用
    分页功能实现
    【模型压缩】Distiller学习-初认识
    机器人运动规划:TOPP轨迹后处理开源方案基础版整理
    Android Studio支持预览Markdown文件
    让chatgpt编写一个微信小程序的对话页面,它是这么整的,我懵了
  • 原文地址:https://blog.csdn.net/u011868279/article/details/127934616