Вопрос:
Я обычно работаю с MSSQL, но у меня есть проект Oracle, который нуждается в решении. Части среды, с которыми я работаю, не полностью контролируются, поэтому я не имею свободного правления.
Проблема. Существует один сервер Oracle, содержащий две схемы. Позвольте называть их:
- Schema_Live
- Schema_Test
Обе схемы идентичны, с очевидной разницей, что одна для тестирования, а другая для реального приложения.
Теперь мне был предоставлен уже существующий веб-сервис, который генерирует отчеты в этой базе данных. Пока все работает нормально, но существующий пользователь, с которым мы работаем, позвонил ему “oldUser”, ему должны быть присвоены имена схем, если он должен работать. Так, например, запрос:
SELECT foo FROM Schema_Live.exampleTable WHERE id = 1
[выполнено] → foo = ‘live’ или
SELECT foo FROM Schema_Test.exampleTable WHERE id = 1
[выполнено] → foo = ‘test’
работает, но мы не хотим постоянно менять наши запросы до развертывания, так как уже существующее обходное решение схема автоматически переключается по коду перед выполнением запроса:
ALTER SESSION SET CURRENT_SCHEMA = Schema_Test
[Выполняется]
SELECT foo FROM exampleTable WHERE id = 1
[выполнено] → foo = ‘test’
Если это не будет сделано, мы получим ошибку “Таблица или представление не существует”:
Oracle.DataAccess.Client.OracleException: «ORA-00942: Tabelle oder View nicht vorhanden» SELECT foo FROM exampleTable WHERE id = 1
[выполнен] → ORA-00942
Существуют также существующие отчеты, которые используют свои собственные подключения для получения своих данных, что является основной проблемой, поскольку в этих запросах мы должны включать имена схем из-за отсутствия возможности выполнить “ALTER SESSION SET CURRENT_SCHEMA” раньше. Развертывание их включает поиск/замену имен схем, которые так же ошибочны, как кажется.
Мое решение: Насколько я понял философию Oracle (и, пожалуйста, поправьте меня, если я ошибаюсь), я не могу просто изменить имя базы данных (= имя схемы) в строке подключения, как это было бы в MSSQL. В строке соединения Oracle нет свойств “базы данных”, поскольку пользователи Oracle уже привязаны к своей схеме.
Итак, чтобы решить эту проблему, я хочу создать для разных пользователей:
- User_Live → hardwired to “Schema_Live”
- User_Test → hardwired to “Schema_Test”
и реализовать две разные строки соединений, которые предоставляются отчетам и запросам, которые я буду выполнять. Если я это сделаю, запрос
SELECT foo FROM exampleTable WHERE id = 1
даст мне
foo = ‘test’ для User_Test и
foo = ‘live’ для User_Live
Вопрос 1: Звучит эта концепция или есть ошибка?
Вопрос 2: Моя проблема в том, что мне дали двух пользователей, но запрос
SELECT foo FROM exampleTable WHERE id = 1
дает мне ORA-00942 для обоих пользователей. Я думаю, что администратор создал их неправильно, но мне не хватает всего ноу-хау, чтобы проверить и сказать ему, что он сделал не так.
PS:
Используя одного из новых пользователей и выполните запрос:
SELECT foo FROM Schema_Test.exampleTable WHERE id = 1
[выполнено] → foo = ‘test’
Су, я догадываюсь, что существует только проблема DefaultTablespace, а не проблема с правами доступа
Ответ №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.