ora-00942以及oracle中schema理解

来源:互联网 发布:js正则表达式 i 编辑:程序博客网 时间:2024/05/23 19:18

最近刚刚接触oracle,遇到很多自认为稀奇古怪的问题,请各位高手不吝赐教:

 1.用system登陆的PLSql,创建了表tbTest,查询的时候 SELECT * FROM�0�2 SYSTEM.TBTEST 可以顺利执行
  但SELECT * FROM�0�2 TBTEST 却报错“表或视图不存在”。为什么会这样?

 2.还是上面刚建的那个表TBTEST ,我在C#中连接oracle,用的system登陆,查询语句 不管查SYSTEM.TBTEST 还是TBTEST 又都ok了,不会报错,这里连接与上方连接PLSQL有何不同之处,为什么这里两种情况又都可以了?

 3.用system登陆的PLSql,新建了个用户yucca, 角色是dba,为何不能查询TBTEST 表?
 grant select any table to yucca 之后yucca才有权限查询表 。那我以后每次需要一个新用户都需要这样grant一次吗?这样太麻烦了。

 4.用yucca登陆plSQL,creat 了表 tbYucca,在plSQL内查询select * from tbYucca 没问题,但在C#内使用yucca登陆Oracle,执行刚刚的查询语句也会报“表或视图不存在”,这是怎么回事?

 5.在plSQL内看tbYucca的属性,owner居然是sys,这又是为什么?

 6.后来在C#内查询 select count(*) from sys.tbYucca 还是会报错“表或视图不存在 ”

 我快绝望了。



1.用system登陆的PLSql,创建了表tbTest,查询的时候 SELECT * FROM  SYSTEM.TBTEST 可以顺利执行 
但SELECT * FROM  TBTEST 却报错“表或视图不存在”。为什么会这样? 

可以用show user命令,看看当前用户的schema,如果你SYSTEM.TBTEST可以访问,但是TBTEST不能访问是shcmea不同的问题

2.还是上面刚建的那个表TBTEST ,我在C#中连接oracle,用的system登陆,查询语句 不管查SYSTEM.TBTEST 还是TBTEST 又都ok了,不会报错,这里连接与上方连接PLSQL有何不同之处,为什么这里两种情况又都可以了?

你用C#连接的时候,是用的system做用户名的,所以scheam是SYSTEM,所以都可以连接

3.用system登陆的PLSql,新建了个用户yucca, 角色是dba,为何不能查询TBTEST 表? 
grant select any table to yucca 之后yucca才有权限查询表 。那我以后每次需要一个新用户都需要这样grant一次吗?这样太麻烦了。 

不需要,dba的权限过大,要查询表,可以用select any table的系统权限,或者针对于当个对象的对象权限比如select on SYSTEM.TBTEST, 一般的用户,我们都指定connect, resource这两个角色权限,比如grant connect, resource to newuser;



4.用yucca登陆plSQL,creat 了表 tbYucca,在plSQL内查询select * from tbYucca 没问题,但在C#内使用yucca登陆Oracle,执行刚刚的查询语句也会报“表或视图不存在”,这是怎么回事? 

还是schema的问题


5.在plSQL内看tbYucca的属性,owner居然是sys,这又是为什么? 
你的tbYucca登录的时候,用的是as sysdba的方式,这种方式的schema是 SYS,既是用户SYS

6.后来在C#内查询 select count(*) from sys.tbYucca 还是会报错“表或视图不存在 ” 
sys的用户需要单独由SYS附对象权限才行。

问题总结

主要是schema的问题,要不通过shcmea.TBTEST这样的形式反问表,必须是scheam和当前schema一致的情况下,

可以通过show user查看当前schema

 

 

自己又捣鼓了捣鼓,总算明白一点了
总结了以下几点
1.使用自己创建的用户登录时,需要登陆模式为"标准"(nomal),这样创建的表的拥有者就是他自己了。
2.不管哪个用户只要是使用dba方式登录PL/sQL创建的表的拥有者都是sys
3.一般报错“表或视图不存在”,除非这个表或视图真不存在,问题一般是权限的问题。把用户的权限之类的理吧清楚了,就不会有这种问题了。

 

lz这里的总结和你说的并不矛盾。 
1.使用自己创建的用户登录时,需要登陆模式为"标准"(nomal),这样创建的表的拥有者就是他自己了。

确实,以normal的方式,就可以把表创建到自己的schema里,只要你不指定一个schema的话。sysdba和sysoper
这两个特殊身份,一般是用来管理和维护的。不要用他们来创建表和其他对象。

2. 不管哪个用户只要是使用dba方式登录PL/sQL创建的表的拥有者都是sys
这个也是正确的,不过有错误的是,是使用sysdba,不是dba,dba和sysdba的区别可以看另外一个文章,用sysdba登录的schema就是sys叻,所以拥有者就是sys了。 


3.般报错“表或视图不存在”,除非这个表或视图真不存在,问题一般是权限的问题。把用户的权限之类的理吧清楚了,就不会有这种问题了。
确实别的schema的对象在你的schema里是没有的。 也有可能你加了schema,但是表名写的不对,还是报 不存在的错呀。

看来有的人还是对schema的真正含义不太理解,现在我再次整理了一下,希望对大家有所帮助。

我们先来看一下他们的定义:
A schema is a collection of database objects (used by a user.).
Schema objects are the logical structures that directly refer to the database’s data.
A user is a name defined in the database that can connect to and access objects.
Schemas and users help database administrators manage database security.

从定义中我们可以看出schema为数据库对象的集合,为了区分各个集合,我们需要给这个集合起个名字,这些名字就是我们在企业管理器的方案下看到的许多类似用户名的节点,这些类似用户名的节点其实就是一个schema,schema里面包含了各种对象如tables, views, sequences, stored procedures, synonyms, indexes, clusters, and database links。

一个用户一般对应一个schema,该用户的schema名等于用户名,并作为该用户缺省schema。这也就是我们在企业管理器的方案下看到schema名都为数据库用户名的原因。Oracle数据库中不能新创建一个schema,要想创建一个schema,只能通过创建一个用户的方法解决(Oracle中虽然有create schema语句,但是它并不是用来创建一个schema的),在创建一个用户的同时为这个用户创建一个与用户名同名的schem并作为该用户的缺省shcema。即schema的个数同user的个数相同,而且schema名字同user名字一一 对应并且相同,所有我们可以称schema为user的别名,虽然这样说并不准确,但是更容易理解一些。

一个用户有一个缺省的schema,其schema名就等于用户名,当然一个用户还可以使用其他的schema。如果我们访问一个表时,没有指明该表属于哪一个schema中的,系统就会自动给我们在表上加上缺省的sheman名。比如我们在访问数据库时,访问scott用户下的emp表,通过select * from emp; 其实,这sql语句的完整写法为select * from scott.emp。在数据库中一个对象的完整名称为schema.object,而不属user.object。类似如果我们在创建对象时不指定该对象的schema,在该对象的schema为用户的缺省schema。这就像一个用户有一个缺省的表空间,但是该用户还可以使用其他的表空间,如果我们在创建对象时不指定表空间,则对象存储在缺省表空间中,要想让对象存储在其他表空间中,我们需要在创建对象时指定该对象的表空间。

咳,说了这么多,给大家举个例子,否则,一切枯燥无味!
SQL> Gruant dba to scott

SQL> create table test(name char(10));
Table created.

SQL> create table system.test(name char(10));
Table created.

SQL> insert into test values('scott');
1 row created.

SQL> insert into system.test values('system');
1 row created.

SQL> commit;
Commit complete.

SQL> conn system/manager
Connected.

SQL> select * from test;
NAME
----------
system

SQL> ALTER SESSION SET CURRENT_SCHEMA = scott; --改变用户缺省schema名
Session altered.

SQL> select * from test;
NAME
----------
scott

SQL> select owner ,table_name from dba_tables where table_name=upper('test');
OWNER TABLE_NAME
------------------------------ ------------------------------
SCOTT TEST
SYSTEM TEST
--上面这个查询就是我说将schema作为user的别名的依据。实际上在使用上,shcema与user完全一样,没有什么区别,在出现schema名的地方也可以出现user名。

 

0 0