-------------------------------------------------------------------------------------------------------
- --Lerning Content :Oracle 12C PL/SQL新特性(下半部分)
- --Author :600团队
- --Description :PL/SQL Lanaguage Reference 关于Change in This Release For Oracle Database PLSQL
Language Reference有具体描述的特性清单
- --Remark :
-------------------------------------------------------------------------------------------------------
1.对于部分12c的PL/SQL新特性改进如下:
1.1调用者权限函数结果集缓存技术
1.2Oracle PL/SQL特有的更多数据类型可以跨越PL/SQL到SQL的接口子句
1.3ACCESSIBLE BY新特性
1.4FETCH FIRST新特性
1.5可将角色授予PL/SQL包和独立子程序
1.6更多的数据类型在SQL和PL/SQL中具有相同的最大大小
1.7可插拔数据库上的触发器设置
1.8library可定义为directory对象,并可带有credential子句
1.9隐式语句结果集
1.10BEQUEATH CURRENT_USER视图
1.11INHERIT PRIVILEGES 和INHERIT ANY PRIVILEGES
1.12不可见列
1.13如何在sql中运行PL/SQL
1.14预定义的查询命令:$$PLSQL_UNIT_OWNER和$$PLSQL_UNIT_TYPE
1.15编译参数PLSQL_DEBUG弃用
-------------------------------------------------------------------------------------------------------
10.ref cursor结果集在12c中应用
10.1我们都知道,在12c之前,sql的查询结果通过ref cursor输出的参数利用PL/SQL子程序返回结果,这里
的技术细节是调用的程序必须绑定ref cursor并明确提取结果集,即使用pipelined也是同样的,无非代码封装更简单而已,
这里的ref cursor由dbms_sql的两个子程序retunrn_result和get_next_result来代替,这样可以隐式的返回结果集,看
下面这个例子:
DECLARE
BEGIN
SELECT * FROM SOCTT.EMP;
SELECT * FROM SCOTT.DEPT;
END ;
/
如果我们想同时查询两个表的结果集如何实现呢?来看12c的新特性如何做到的
CREATE OR REPLACE PROCEDURE PROC_SHOW_INFO IS
V_CURSOR SYS_REFCURSOR;
BEGIN
OPEN V_CURSOR FOR
SELECT * FROM SCOTT.EMP ORDER BY EMPNO;
DBMS_SQL.RETURN_RESULT(V_CURSOR);
OPEN V_CURSOR FOR
SELECT * FROM SCOTT.DEPT ORDER BY SCOTT.DEPT.DEPTNO;
DBMS_SQL.RETURN_RESULT(V_CURSOR);
END;
/
SQL> conn scott/oracle@pdb;
已连接。
SQL> show con_name;
CON_NAME
------------------------------
PDBORACLE
SQL> set serveroutput on;
SQL> exec proc_show_info;
PL/SQL 过程已成功完成。
ResultSet #1
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------------- ---------- ----------
DEPTNO
----------
7369 SMITHS CLERK 7902 17-12月-80 800
20
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300
30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500
30
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------------- ---------- ----------
DEPTNO
----------
7566 JONES MANAGER 7839 02-4月 -81 2975
20
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400
30
7698 BLAKE MANAGER 7839 01-5月 -81 2850
30
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 09-6月 -81 2450
10
7788 SCOTT ANALYST 7566 19-4月 -87 3000
20
7839 KING PRESIDENT 17-11月-81 5000
10
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------------- ---------- ----------
DEPTNO
----------
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0
30
7876 ADAMS CLERK 7788 23-5月 -87 1100
20
7900 JAMES CLERK 7698 03-12月-81 950
30
EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------------- ---------- ----------
DEPTNO
----------
7902 FORD ANALYST 7566 03-12月-81 3000
20
7934 MILLER CLERK 7782 23-1月 -82 1300
10
已选择 14 行。
ResultSet #2
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
99 Small
10.2隐式语句导致Oracle数据库12c版本1 (12.1)(DBMS_SQL)。RETURN_RESULT和DBMS_SQL.GET_NEXT_RESULT),
隐式语句结果将简化存储过程从其他数据库引擎迁移到Oracle 12c的过程,DBMS_SQL包中的RETURN_RESULT
过程允许隐式地传递参数,而不是定义显式的ref游标参数
10.3来看类似案例1的操作,再次回忆一下该新特性:
DROP TABLE T_600_DATA CASCADE CONSTRAINT PURGE;
/
CREATE TABLE T_600_DATA(
ID NUMBER,
DESCRIPTION VARCHAR2(50 CHAR),
TIMESTAMPS DATE
)
SEGMENT CREATION IMMEDIATE
NOLOGGING
;
/
BEGIN
INSERT INTO T_600_DATA VALUES(5,'DESCRIPTION 5',SYSDATE-4);
INSERT INTO T_600_DATA VALUES(4,'DESCRIPTION 4',SYSDATE-3);
INSERT INTO T_600_DATA VALUES(3,'DESCRIPTION 3',SYSDATE-2);
INSERT INTO T_600_DATA VALUES(2,'DESCRIPTION 2',SYSDATE-1);
INSERT INTO T_600_DATA VALUES(1,'DESCRIPTION 1',SYSDATE);
COMMIT;
END ;
/
CREATE OR REPLACE PROCEDURE PROC_GET_RESULTS(P_ID IN NUMBER DEFAULT NULL) IS
V_CURSOR_1 SYS_REFCURSOR;
V_CURSOR_2 SYS_REFCURSOR;
BEGIN
IF P_ID IS NOT NULL THEN
OPEN V_CURSOR_1 FOR
SELECT DESCRIPTIONS, TIMESTAMPS FROM T_600_DATA WHERE ID = P_ID;
DBMS_SQL.RETURN_RESULT(V_CURSOR_1);
END IF;
OPEN V_CURSOR_2 FOR
SELECT COUNT(*) FROM T_600_DATA DBMS_SQL.RETURN_RESULT(V_CURSOR_2);
END;
/
SQL> show user;
USER 为 "SCOTT"
SQL> show con_name;
CON_NAME
------------------------------
PDBORACLE
SQL> exec proc_get_results(5);
PL/SQL 过程已成功完成。
ResultSet #1
DESCRIPTION
--------------------------------------------------------------------------------
TIMESTAMPS
--------------
DESCRIPTION 5
20-7月 -18
ResultSet #2
COUNT(*)
----------
5
SQL> exec proc_get_results;
PL/SQL 过程已成功完成。
ResultSet #1
COUNT(*)
----------
5
10.4通常,我们希望这些结果集由客户端编程语言(如Java或c#)处理,但是可以使用DBMS_SQL包中的GET_NEXT_RESULT
过程在PL/SQL中处理它们。下面的代码示例使用DBMS_SQL包执行过程。由于过程可以返回具有不同记录结构的多个结果
集(不同的结果集),所以我们必须描述resultset,以了解如何处理它。决策是基于resultset中的列数做出的
,后期通过一篇单独的文档详细描述,这里就不写代码了。
-------------------------------------------------------------------------------------------------------
11.我们都知道使用CREATE VIEW语句定义一个视图,它是基于一个或多个表或视图的逻辑表。视图本身不包含任何数据。
视图所基于的表称为基表。我们还可以在现有视图机制之上创建支持lob、对象类型、REF数据类型、嵌套表或varray类型
的对象视图或关系视图。对象视图是用户定义类型的视图,其中每一行都包含对象,每个对象都有一个惟一的对象标识符
11.1在Oracle数据库12c版本1(12.1)中控制调用者权限(传递CURRENT_USER)
在数据库的以前版本中,在视图中调用invoker权限函数使函数在视图所有者的上下文中运行,实质上破坏了invoker
权限功能。Oracle 12c第1版首次引入了对调用程序权限函数调用的适当支持
11.2关于在视图中使用invoker权限的主要注意事项是它不会影响基本视图的工作方式。它只影响视图工作中调用的
调用权限函数。在下面的示例中,将遗留的定义器(默认值)和遗留的CURRENT_USER子句添加到查询USER_VIEWS视图的
基本视图中。当从视图所有者查询两个视图时,它们都会产生相同的输出,显示创建的两个视图。
CREATE OR REPLACE VIEW V_VIEW1
BEQUEATH DEFINER
AS
SELECT VIEW_NAME,BEQUEATH FROM USER_VIEWS
ORDER BY VIEW_NAME;
/
CREATE OR REPLACE VIEW V_VIEW2
BEQUEATH DEFINER
AS
SELECT VIEW_NAME,BEQUEATH FROM USER_VIEWS
ORDER BY VIEW_NAME;
/
GRANT SELECT ON V_VIEW1 TO SCOTT;
GRANT SELECT ON V_VIEW2 TO SCOTT;
11.3包含Invoker权限函数的Invoker权限视图
要查看操作中的功能,我们需要创建一个invoker权限函数。下面的函数返回有关调用用户的信息。
注意AUTHID CURRENT_USER子句,表示它是一个invoker权限函数
CREATE OR REPLACE FUNCTION FUNC_INVOKE RETURN VARCHAR2 AUTHID CURRENT_USER AS
V_RESULT VARCHAR2(200);
BEGIN
SELECT ORA_INVOKING_USER || ' : ' || ORA_INVOKING_USERID
INTO V_RESULT
FROM DUAL;
RETURN V_RESULT;
END;
/
CREATE OR REPLACE VIEW V_GET_INVOKING
BEQUEATH DEFINER
AS
SELECT SCOTT.FUNC_INVOKE FROM DUAL;
/
CREATE OR REPLACE VIEW V_INVOKING_USER
BEQUEATH CURRENT_USER
AS
SELECT SCOTT.FUNC_INVOKE FROM DUAL;
/
ALTER VIEW V_GET_INVOKING COMPILE;
ALTER VIEW V_INVOKING_USER COMPILE;
/
GRANT SELECT ON V_INVOKING TO SCOTT;
GRANT SELECT ON V_INVOKING_USER TO SCOTT;
/
SQL> show con_name;
CON_NAME
------------------------------
PDBORACLE
SQL> grant select on scott.V_GET_INVOKING to scott;
授权成功。
SQL> grant select on scott.V_INVOKING_USER to scott;
授权成功。
SQL> set linesize 150;
SQL> set serveroutput on;
SQL> select * from scott.v_get_invoking;
FUNC_INVOKE
------------------------------------------------------------------------------------------------------------------------------------------------------
SCOTT : 109
SQL> select * from scott.v_invoking_user;
select * from scott.v_invoking_user
*
第 1 行出现错误:
ORA-06598: INHERIT PRIVILEGES 权限不足
-------------------------------------------------------------------------------------------------------
12.INHERIT PRIVILEGES和INHERIT ANY PRIVIEGES
12.1从12c开始只有当调用者权限的所有权具有INHERIT PRIVILEGES或者INHERIT ANY PRIVILEGES权限时,该单元
才会以调用者权限执行,例如在oracle 12c之前版本,假设用户A把一个函数func_demo创建为一个调用者权限,并
把对它执行的权限授予正好有比用户A更多权限的用户B,然后当用户B运行该自定义函数func_demo时,该函数将以
用户B的权限运行,这可能会执行用户A也许没有权限执行的操作,在12c中,情况不同了,需要明确通过INHERIT
PRIVILIEGES或者是INHERIT ANY PRIVILEGES权限来指定
12.2我们来看一个投机取巧的案例,如何利用invoker权限来升级一个DBA权限
SQL> show user;
USER 为 "SYS"
SQL> show con_name;
CON_NAME
------------------------------
PDBORACLE
SQL> create user demo_developer identified by demo_developer default tablespace tbs_oracle;
用户已创建。
SQL> grant create session ,create procedure to demo_developer;<------注意,新建立的demo_developer只有登录和创建存储过程权限
授权成功。
SQL> create user demo2_developer identified by demo2_developer default tablespace tbs_oracle;
用户已创建。
SQL> grant create session to demo2_developer;<------注意,新建立的demo2_developer只有登录权限
授权成功。
SQL> create user demo3_developer identified by demo3_developer default tablespace tbs_oracle;
用户已创建。
SQL> grant create session ,dba to demo3_developer;<------注意,新建立的dem3_developer有登录和DBA权限
授权成功。
注意:首先我们创建一个正常的自定义函数,通过三个新建立的用户去执行
SQL> conn demo_developer/demo_developer@pdb;
已连接。
SQL> show user;
USER 为 "DEMO_DEVELOPER"
SQL> create or replace function func_add_number(p1 in number,p2 in number)
2 return number authid current_user
3 as
4 begin
5 return(p1+p2);
6 end;
7 /
函数已创建。
SQL> grant execute on func_add_number to public;
授权成功。
注意:普通用户可以运行此函数调用结果集
SQL> conn demo2_developer/demo2_developer@pdb;
已连接。
SQL> show user;
USER 为 "DEMO2_DEVELOPER"
SQL> select demo_developer.func_add_number(1,2) from dual;
DEMO_DEVELOPER.FUNC_ADD_NUMBER(1,2)
-----------------------------------
3
注意:DBA用户可以调用demo_developer的函数调用结果集
SQL> conn demo3_developer/demo3_developer@pdb;
已连接。
SQL> show user;
USER 为 "DEMO3_DEVELOPER"
SQL> select demo_developer.func_add_number(1,2) from dual;
DEMO_DEVELOPER.FUNC_ADD_NUMBER(1,2)
-----------------------------------
3
注意:检查DBA角色用户没有发生变化
SQL> set linesize 150;
SQL> conn @pdb as sysdba;
已连接。
SQL> show user;
USER 为 "SYS"
SQL> select grantee from dba_role_privs
2 where granted_role='DBA'
3 order by grantee;
GRANTEE
--------------------------------------------------------------------------------------------------------------------------------
DEMO3_DEVELOPER
OUTLN
ROBERT
SYS
SYSTEM
已选择 5 行。
注意:我们创建了一个带有自治事务并且利用动态sql手动授权的存储过程,并在func_add_number中调用它
SQL> conn demo_developer/demo_developer@pdb;
已连接。
SQL> show user;
USER 为 "DEMO_DEVELOPER"
SQL> create or replace procedure proc_make_dba
2 authid current_user
3 as
4 pragma autonomous_transaction;<------自治事务
5 begin
6 execute immediate'grant dba to demo_developer';<------动态sql授予dba权限
7 exception
8 when others then
9 null;
10 end;
11 /
过程已创建。
SQL> create or replace function func_add_number(p1 in number,p2 in number)
2 return number authid current_user
3 as
4 begin
5 proc_make_dba;<------在自定义函数中引用刚才创建好的存储过程
6 return(p1+p2);
7 end;
8 /
函数已创建。
SQL> conn demo2_developer/demo2_developer@pdb;
已连接。
SQL> show user;
USER 为 "DEMO2_DEVELOPER"
SQL> select demo_developer.func_add_number(1,2) from dual;
DEMO_DEVELOPER.FUNC_ADD_NUMBER(1,2)
-----------------------------------
3
SQL> conn demo3_developer/demo3_developer@pdb;
已连接。
SQL> show user;
USER 为 "DEMO3_DEVELOPER"
SQL> select grantee
2 from dba_role_privs
3 where granted_role='DBA'
4 order by grantee;
GRANTEE
--------------------------------------------------------------------------------------------------------------------------------
DEMO3_DEVELOPER
OUTLN
ROBERT
SCOTT
SCOTT_DEMO
SYS
SYSTEM
已选择 7 行。
注意:当代码由DBA用户运行时结果就不一样了,demo_developer会自动获得DBA权限
SQL> select demo_developer.func_add_number(1,2) from dual;
DEMO_DEVELOPER.FUNC_ADD_NUMBER(1,2)
-----------------------------------
3
SQL> select grantee from dba_role_privs
2 where granted_role='DBA'
3 order by grantee;
GRANTEE
--------------------------------------------------------------------------------------------------------------------------------
DEMO3_DEVELOPER
DEMO_DEVELOPER <------注意,demo_developer已经获得了DBA权限,是不是很可怕
OUTLN
ROBERT
SCOTT
SCOTT_DEMO
SYS
SYSTEM
已选择 8 行。
注:这是一个比较严重的安全漏洞,为了解决类似问题发生,Oracle12c推出新的权限控制策略。
12.3为了填补这个安全漏洞,Oracle12c INHERIT [ANY] PRIVILEGES privileges。为了向后兼容性,对所有新用户
或升级用户执行以下授予如果想要选择谁可以从特定用户继承特权,就不需要INHERIT PRIVILEGES ON USER username
TO PUBLIC。为了保证权限控制,无故的DBA权限,我们可以执行以下操作
SQL> conn @pdb as sysdba;
已连接。
SQL> revoke dba from demo_developer;
撤销成功。
SQL> conn @pdb as sysdba;
已连接。
SQL> revoke inherit privileges on user demo3_developer from public;
撤销成功。
SQL> conn demo3_developer/demo3_developer@pdb;
已连接。
SQL> show user;
USER 为 "DEMO3_DEVELOPER"
SQL> select grantee from dba_role_privs
2 where granted_role='DBA'
3 order by grantee;
GRANTEE
--------------------------------------------------------------------------------------------------------------------------------
DEMO3_DEVELOPER
OUTLN
ROBERT
SCOTT
SCOTT_DEMO
SYS
SYSTEM
已选择 7 行。
SQL> select demo_developer.func_add_number(4,5) from dual;
select demo_developer.func_add_number(4,5) from dual
*
第 1 行出现错误:
ORA-06598: INHERIT PRIVILEGES 权限不足
ORA-06512: 在 "DEMO_DEVELOPER.FUNC_ADD_NUMBER", line 1
SQL> select grantee from dba_role_privs
2 where granted_role='DBA'
3 order by grantee;
GRANTEE
--------------------------------------------------------------------------------------------------------------------------------
DEMO3_DEVELOPER
OUTLN
ROBERT
SCOTT
SCOTT_DEMO
SYS
SYSTEM
已选择 7 行。
SQL> grant inherit privileges on user demo3_developer to demo_developer;
授权成功。
SQL> select demo_developer.func_add_number(1,2) from dual;
DEMO_DEVELOPER.FUNC_ADD_NUMBER(1,2)
-----------------------------------
3
SQL> select grantee from dba_role_privs
2 where granted_role='DBA'
3 order by grantee;
GRANTEE
--------------------------------------------------------------------------------------------------------------------------------
DEMO3_DEVELOPER
DEMO_DEVELOPER
OUTLN
ROBERT
SCOTT
SCOTT_DEMO
SYS
SYSTEM
已选择 8 行。
SQL> revoke inherit privileges on user demo3_developer from demo_developer;
撤销成功。
SQL> select grantee from dba_role_privs where granted_role='DBA' ;
GRANTEE
--------------------------------------------------------------------------------------------------------------------------------
ROBERT
DEMO3_DEVELOPER
OUTLN
DEMO_DEVELOPER
SCOTT
SCOTT_DEMO
SYSTEM
SYS
已选择 8 行。
SQL> revoke inherit privileges on user demo_developer from public;
撤销成功。
SQL> show user;
USER 为 "DEMO3_DEVELOPER"
SQL> select demo_developer.func_add_number(1,2) from dual;
select demo_developer.func_add_number(1,2) from dual
*
第 1 行出现错误:
ORA-06598: INHERIT PRIVILEGES 权限不足
ORA-06512: 在 "DEMO_DEVELOPER.FUNC_ADD_NUMBER", line 1
SQL> select grantee from dba_role_privs where granted_role='DBA';
GRANTEE
--------------------------------------------------------------------------------------------------------------------------------
ROBERT
DEMO3_DEVELOPER
OUTLN
DEMO_DEVELOPER
SCOTT
SCOTT_DEMO
SYSTEM
SYS
已选择 8 行。
-------------------------------------------------------------------------------------------------------
13.不可见列
13.1我们使用不可见列来更改表,而不会中断使用该表的应用程序,可以使单个列不可见,表的任何通用访问不会
显示表中的不可见列,例如,如下操作不会在输出结果集中显示不可见列:
13.1.1select * from table的操作
13.1.2sqlplus 中的describe命令
13.1.3PL/SQL中rowtype%属性声明
13.1.4oracle call interface(OCI)中。
注意:只有在列表明确指定不可见列时,才能使用select语句显示不可见列的输出结果,同样的,只有在insert
语句的列表中显示指定的不可见列,才能将value插入到不可见列。
13.2以下限制适用于不可见列:
13.2.1external table外部表
13.2.2cluster table聚簇表
13.2.3temporary table临时表
13.2.4用户定义类型的属性
注意:虚拟列可以是不可见的,此外还可以在创建表时使用不可见列作为分区键
13.3不可见列和列排序
13.3.1数据库通常按照create table语句中列出的顺序存储列,如果向表中添加新列,则新列将成为表的
列顺序中最后一列
13.3.2当表包含一个或者多个不可见列时,不可见列不包含在表的列顺序中,访问表中的所有列时,列排序
就显得尤为重要了,例如select * from 语句中显示表的列顺序,由于不可见列不包含在此类表通用访问中,
刚才我们描述过了,因此他们不包含在列顺序中。
13.3.3在显示不可见列时,该列将作为最后一列包含在表的列顺序中,如果使可见列不可见,那么不可见列
不会包含在列顺序中,并且可能会重新排列表中的可见列顺序。
13.4以下包括错误的代码演示,和正常的不可见列代码:
SQL> conn scott/oracle@pdb;
已连接。
SQL> show user;
USER 为 "SCOTT"
SQL> show con_name;
CON_NAME
------------------------------
PDBORACLE
SQL> drop table t_600_demo cascade constraints purge;
表已删除。
SQL> create table t_600_demo(col1 number,col2 varchar2(10));
表已创建。
SQL> desc t_600_demo;
名称 是否为空? 类型
----------------------------------------------------------------------------------- -------- --------------------------------------------------------
COL1 NUMBER
COL2 VARCHAR2(10)
SQL> insert into t_600_demo values(1,'a');
已创建 1 行。
SQL> insert into t_600_demo values(2,'b');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from t_600_demo;
COL1 COL2
---------- ----------
1 a
2 b
SQL> alter table t_600_demo add(col3 number insisible);
alter table t_600_demo add(col3 number insisible)
*
第 1 行出现错误:
ORA-00907: 缺失右括号
SQL> alter table t_600_demo add(col3 number invisible);
表已更改。
SQL> desc t_600_demo;
名称 是否为空? 类型
----------------------------------------------------------------------------------- -------- --------------------------------------------------------
COL1 NUMBER
COL2 VARCHAR2(10)
SQL> set colinvisible on ;
SQL> desc t_600_demo;
名称 是否为空? 类型
----------------------------------------------------------------------------------- -------- --------------------------------------------------------
COL1 NUMBER
COL2 VARCHAR2(10)
COL3 (INVISIBLE) NUMBER
SQL> select * from t_600_demo;
COL1 COL2
---------- ----------
1 a
2 b
SQL> insert into t_600_demo values(3,'c');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from t_600_demo;
COL1 COL2
---------- ----------
1 a
2 b
3 c
SQL> insert into t_600_demo values(4,'c',1);
insert into t_600_demo values(4,'c',1)
*
第 1 行出现错误:
ORA-00913: 值过多
SQL> desc t_600_demo;
名称 是否为空? 类型
----------------------------------------------------------------------------------- -------- --------------------------------------------------------
COL1 NUMBER
COL2 VARCHAR2(10)
COL3 (INVISIBLE) NUMBER
SQL> alter table t_600_demo modify col3 visible;
表已更改。
SQL> insert into t_600_demo values(4,'c',1);
已创建 1 行。
SQL> commit;
提交完成。
SQL> drop table t)600_demo purge;
drop table t)600_demo purge
*
第 1 行出现错误:
ORA-00933: SQL 命令未正确结束
SQL> drop table t_600_demo purge;
表已删除。
SQL> create table t_600_demo(col1 number,col2 number invisible);
表已创建。
SQL> begin
2 insert into t_600_demo(col1,col2)
3 values(1,2);
4 commit;
5 end;
6 /
PL/SQL 过程已成功完成。
SQL> create or replace package pkg_invisible
2 aithid definer
3 is
4 cursor cur_data
5 is
6 select * from t_600_demo;
7 cursor cur_data2
8 is
9 select col1,col2 from t_600_demo;
10 end;
11 /
警告: 创建的包带有编译错误。
SQL> create or replace package pkg_invisible
2 authid definer
3 is
4 cursor cur1_data
5 is
6 select * from t_600_demo;
7 cursor cur2_data
8 is
9 select col1,col2 from t_600_demo;
10 end;
11 /
程序包已创建。
SQL> declare
2 rec t_600_demo%rowtype;
3 begin
4 select * into rec from t_600_demo
5 where rownum <2;
6 dbms_output.put_line('invisible='||rec.col2);
7 end;
8 /
dbms_output.put_line('invisible='||rec.col2);
*
第 6 行出现错误:
ORA-06550: 第 6 行, 第 40 列:
PLS-00302: 必须声明 'COL2' 组件
ORA-06550: 第 6 行, 第 1 列:
PL/SQL: Statement ignored
SQL> declare
2 ;
3 /
;
*
第 2 行出现错误:
ORA-06550: 第 2 行, 第 1 列:
PLS-00103: 出现符号 ";"在需要下列之一时:
begin function pragma
procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior
SQL> declare
2 rec t_600_demo%rowtype;
3 begin
4 open cur_data;
5 fetch pkg_invisible.cur2_data into rec;
6 close pkg_invisible.cur2_data;
7 dbms_output.put_line('invisible='||rec.col2);
8 end;
9 /
open cur_data;
*
第 4 行出现错误:
ORA-06550: 第 4 行, 第 6 列:
PLS-00201: 必须声明标识符 'CUR_DATA'
ORA-06550: 第 4 行, 第 1 列:
PL/SQL: SQL Statement ignored
ORA-06550: 第 5 行, 第 1 列:
PLS-00394: 在 FETCH 语句的 INTO 列表中值数量出现错误
ORA-06550: 第 5 行, 第 1 列:
PL/SQL: SQL Statement ignored
ORA-06550: 第 7 行, 第 40 列:
PLS-00302: 必须声明 'COL2' 组件
ORA-06550: 第 7 行, 第 1 列:
PL/SQL: Statement ignored
-------------------------------------------------------------------------------------------------------
14.如何在sql中使用PL/SQL代码,在本文中不做实例演示,后期通过一个真实的案例来说明此功能
-------------------------------------------------------------------------------------------------------
总结:整体的12c PL/SQL新特性就介绍到这里,部分功能后期会通过单独详细的文档,案例去描述,后期关注600团队更多
文章,帮助学习、实践。
-------------------------------------------------------------------------------------------------------




