问题描述
用户 user_view 查询视图,提示视图不存在。
obclient [USER_VIEW]> select * from sys.v_t1;
ORA-00942: table or view does not exist
sys 用户查询视图,视图却是存在的。
obclient [SYS]> select view_name,TEXT from all_views where owner='SYS' and view_name ='V_T1';
输出结果如下。
+-----------+------------------------------------------------------------------------+
| VIEW_NAME | TEXT |
+-----------+------------------------------------------------------------------------+
| V_T1 | select "SYS"."T1"."ID" AS "ID","SYS"."T1"."R1" AS "R1" from "SYS"."T1" |
+-----------+------------------------------------------------------------------------+
1 row in set (0.012 sec)
问题原因
create or replace 的实现是先 drop 旧对象再 create 新对象,新创建的对象没有维护对象权限。视图、触发器、序列等同时支持对象权限和 create or replace 语法的对象都存在此类问题。 具体参考如下案例过程。
sys 用户创建视图、创建用户 user_view、赋予用户 user_view 查询视图 v_t1 的读权限。
使用 sys 用户登录到集群的 oracle 租户。
[root@xxx admin]# obclient -usys@oracle -p'root' -P 2883 -h 127.1 -cA输出内容如下。
Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 32 Server version: OceanBase 3.2.3.0 (r20220429172811-141f0018b07e9f8d269bb5f6dbd020cd419eb3fc) (Built Apr 29 2022 17:39:23) Copyright (c) 2000, 2018, OB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.创建视图。
obclient [SYS]> create or replace view v_t1 as select * from t1; Query OK, 0 rows affected (0.073 sec)查询视图。
obclient [SYS]> select * from v_t1;输出内容如下。
+-----+------+ | ID | R1 | +-----+------+ | 967 | 11 | +-----+------+ 1 row in set (0.035 sec)创建用户。
obclient [SYS]> create user user_view identified by root; Query OK, 0 rows affected (0.090 sec)授予用户 user_view 拥有查询 sys 用户下 v_t1 视图的权限。
obclient [SYS]> grant select on sys.v_t1 to user_view; Query OK, 0 rows affected (0.074 sec)授予 user_view 用户在服务器上拥有创建 session 会话连接数据库权限。
obclient [SYS]> grant create session to user_view; Query OK, 0 rows affected (0.056 sec)- 退出 sys 用户 OBClient 客户端。
obclient [SYS]> \q Bye用户 user_view 可以正常查询视图。
使用 user 用户登录到集群的 oracle 租户。
[root@xxx admin]# obclient -uuser_view@oracle -p'root' -P 2883 -h 127.1 -cA
输出结果如下。
Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 35 Server version: OceanBase 3.2.3.0 (r20220429172811-141f0018b07e9f8d269bb5f6dbd020cd419eb3fc) (Built Apr 29 2022 17:39:23) Copyright (c) 2000, 2018, OB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.- 查询 sys 用户中的视图 v_t1。
obclient [USER_VIEW]> select * from sys.v_t1;输出结果如下。
+-----+------+ | ID | R1 | +-----+------+ | 967 | 11 | +-----+------+ 1 row in set (0.022 sec)退出 user_view 用户 OBClient 客户端。
obclient [USER_VIEW]> \q Bye
sys 用户重建视图,用户 user_view 再次查询视图报错视图不存在。
使用 sys 用户登录到集群的 oracle 租户。
[root@xxx admin]# obclient -usys@oracle -p'root' -P 2883 -h 127.1 -cA输出结果如下。
Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 36 Server version: OceanBase 3.2.3.0 (r20220429172811-141f0018b07e9f8d269bb5f6dbd020cd419eb3fc) (Built Apr 29 2022 17:39:23) opyright (c) 2000, 2018, OB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.使用 sys 用户登录重建视图。
obclient [SYS]> create or replace view v_t1 as select * from t1; Query OK, 0 rows affected (0.095 sec)退出 sys 用户 OBClient 客户端。
obclient [SYS]> \q Bye使用 user 用户登录到集群的 oracle 租户。
[root@xxx admin]# obclient -uuser_view@oracle -p'root' -P 2883 -h 127.1 -cA输出结果如下。
Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 37 Server version: OceanBase 3.2.3.0 (r20220429172811-141f0018b07e9f8d269bb5f6dbd020cd419eb3fc) (Built Apr 29 2022 17:39:23) Copyright (c) 2000, 2018, OB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.使用 user_view 用户查询 sys 用户中的 v_t1 视图。
obclient [USER_VIEW]> select * from sys.v_t1; ORA-00942: table or view does not exist退出 user_view 用户 OBClient 客户端。
obclient [USER_VIEW]> \q Bye
适用版本
OceanBase 数据库 V2.x 和 V3.x 版本。
解决方法
升级至问题已修复版本。
目前已修复的版本包括 OceanBase 数据库企业版 V2.2.77 (oceanbase-2.2.77-20210508211731) 及之后版本、V3.3.3 BP6 Hotfix1 (oceanbase-3.2.3.3-106010052022120116) 及之后版本。
规避方法
提前把相关对象的权限保留下来或重建对象后重新授予权限。
示例如下。
使用 sys 用户登录到集群的 oracle 租户。
[root@xxx admin]# obclient -usys@oracle -p'root' -P 2883 -h 127.1 -cA输出结果如下。
Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 38 Server version: OceanBase 3.2.3.0 (r20220429172811-141f0018b07e9f8d269bb5f6dbd020cd419eb3fc) (Built Apr 29 2022 17:39:23) Copyright (c) 2000, 2018, OB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.授予 user_view 用户拥有查询 sys 用户中 v_t1 视图的权限。
obclient [SYS]> grant select on sys.v_t1 to user_view; Query OK, 0 rows affected (0.060 sec)退出 sys 用户 OBClient 客户端。
obclient [SYS]> \q Bye使用 user 用户登录到集群的 Oracle 租户。
[root@xxxx admin]# obclient -uuser_view@oracle -p'root' -P 2883 -h 127.1 -cA输出结果如下。
Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 39 Server version: OceanBase 3.2.3.0 (r20220429172811-141f0018b07e9f8d269bb5f6dbd020cd419eb3fc) (Built Apr 29 2022 17:39:23) Copyright (c) 2000, 2018, OB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.使用 user_view 用户查询 sys 用户中的 v_t1 视图。
obclient [USER_VIEW]> select * from sys.v_t1;输出结果如下。
+-----+------+ | ID | R1 | +-----+------+ | 967 | 11 | +-----+------+ 1 row in set (0.028 sec)