通过在连接字符串中使用不同的用户来切换Oracle模式

时间:2018-03-09 11:47:57

标签: oracle

我通常使用MSSQL,但手上有一个需要解决的Oracle项目。我正在使用的部分环境并非完全由我控制,所以我没有自由的统治。

问题:有一个Oracle服务器,包含两个模式。我们打电话给他们:

  1. Schema_Live
  2. Schema_Test
  3. 两种模式都是相同的,明显不同的是一种用于测试,另一种用于实际应用。

    现在,我获得了一个现有的Web服务,可以生成有关此数据库的报告。到目前为止一切正常,但我们正在使用的现有用户,让我们称他为“oldUser”,如果他应该工作,必须给出模式名称。例如,查询:

    SELECT foo FROM Schema_Live.exampleTable WHERE id = 1 
    

    [执行] - GT; foo ='live' 或

    SELECT foo FROM Schema_Test.exampleTable WHERE id = 1 
    

    [执行] - GT; foo ='test'

    有效,但我们不希望在部署之前一直更改查询,因此在执行查询之前,已经存在的解决方法将通过代码自动切换架构:

    ALTER SESSION SET CURRENT_SCHEMA = Schema_Test
    

    [执行]

    SELECT foo FROM exampleTable WHERE id = 1
    

    [执行] - GT; foo ='test'

    如果没有这样做,我们将收到错误“表或视图不存在”:

    Oracle.DataAccess.Client.OracleException: "ORA-00942: Tabelle oder View nicht vorhanden"
    
    SELECT foo FROM exampleTable WHERE id = 1
    

    [执行] - GT; ORA-00942

    还有一些报告使用自己的连接来获取数据,这是主要问题,因为在这些查询中我们必须包含模式名称,因为之前没有机会执行“ALTER SESSION SET CURRENT_SCHEMA”。部署这些包括查找/替换模式名称,这听起来有点错误。

    我的解决方案:据我了解Oracle哲学(如果我错了请纠正我),我不能简单地在连接字符串中更改数据库名称(= schema name),就像在MSSQL中一样。 Oracle连接字符串中没有“数据库”属性,因为Oracle用户已经硬连线到其架构。

    所以,要解决这个问题,我想为不同的用户创建:

    • User_Live - >硬连线到“Schema_Live”
    • User_Test - >硬连线到“Schema_Test”

    并实现两个不同的连接字符串,这些字符串将提供给我将执行的报告和查询。如果我这样做,查询

    SELECT foo FROM exampleTable WHERE id = 1
    

    会给我 对于User_Test,foo ='test' 和
    用户_活动的foo ='live'

    问题1:这个概念是否合理或是否存在错误?

    问题2:我现在的问题是我获得了两个用户但查询

    SELECT foo FROM exampleTable WHERE id = 1
    

    给了我两个用户的ORA-00942。我认为管理员创造了他们错了,但我缺乏检查并告诉他他做错了什么的所有技术诀窍。

    P.S:

    使用其中一个新用户并执行查询:

    SELECT foo FROM Schema_Test.exampleTable WHERE id = 1 
    

    [执行] - GT; foo ='test'

    Soo我猜你只有一个DefaultTablespace问题而且访问权限没有问题

1 个答案:

答案 0 :(得分:1)

“ALTER SESSION SET CURRENT_SCHEMA = Schema_Test”

将持续会话的持续时间。所以(假设您没有使用连接池),您可以在登录触发器中发出一次,然后您应该在会话期间保持良好状态。

SQL>
SQL> conn / as sysdba
Connected.

SQL> create user demo identified by demo;

User created.

SQL> grant connect to demo;

Grant succeeded.

SQL> grant select on scott.emp to demo;

Grant succeeded.

SQL> conn demo/demo
Connected.

SQL> select count(*) from scott.emp;

  COUNT(*)
----------
        14

1 row selected.

SQL> select count(*) from emp;
select count(*) from emp
                     *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL>
SQL>
SQL> conn / as sysdba
Connected.

SQL> create or replace
  2  trigger demo_login
  3  after logon on demo.schema
  4  begin
  5   execute immediate 'alter session set current_schema = scott';
  6  end;
  7  /

Trigger created.

SQL>
SQL> conn demo/demo
Connected.

SQL> select count(*) from scott.emp;

  COUNT(*)
----------
        14

1 row selected.

SQL> select count(*) from emp;

  COUNT(*)
----------
        14

1 row selected.

SQL>

或使用代理的示例

SQL> create user demo identified by demo;

User created.

SQL> grant create session to demo;

Grant succeeded.

SQL> alter user scott grant connect through demo;

User altered.

SQL> conn demo[scott]/demo
Connected.

SQL> select user from dual;

USER
--------------------------------------------------------------------
SCOTT

1 row selected.

SQL> select count(*) from emp;

  COUNT(*)
----------
        14

1 row selected.