вторник, 26 ноября 2013 г.

SQL Developer: ORA-12705: Cannot access NLS data files or invalid environment specified


При попытке подключиться с помощью SQL Developer 4.0.0.13 к БД Oracle, получаю ошибку:
Status : Failure -Test failed: ORA-00604: error occurred at recursive SQL level 1
ORA-12705: Cannot access NLS data files or invalid environment specified
NLS - расшифровывается как National Language Support. Проблема связана с кодировкой. Причем при подключении через SQL*Plus никаких проблем с кодировкой не возникает. Это значит что проблема в самом SQL Developer. Поисказ в инете нашел вот эту заметку. Выполнив приведенные в ней дейвтвия решил пролбему:
  • открыть файл sqldeveloper\ide\bin\ide.conf;
  • в конец добавил строки:
    AddVMOption -Duser.region=us
    AddVMOption -Duser.language=en
    
  • перезапустил SQL Developer.

понедельник, 25 ноября 2013 г.

ORA-12638: Credential retrieval failed

При попытке подключиться к Oracle из под учетной записи пользователя Windows не состоящего в группе ORA_DBA, получаю ошибку:
ORA-12638: Credential retrieval failed

Решение

Вот тут написано, что нужно в файле sqlnet.ora (у меня он находится по пути c:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN\sqlnet.ora) заменить строку:
SQLNET.AUTHENTICATION_SERVICES = (NTS)
на 
SQLNET.AUTHENTICATION_SERVICES = (NONE)

четверг, 21 ноября 2013 г.

Изучаю Oracle: Пользователи и их права

В предыдущем посте в п. 2 я писал как исправить проблемы с некорректно установленным Oracle'ом. Как оказалось, то что я написал не полностью решает проблему, по-этому я его снес и установил заново уже под локальной учетной записью. Теперь все работает как надо и можно продолжить изучение.

При установке Oracle по умолчанию создаются два пользователя/схемы - SYS и SYSTEM. Я написал "пользователя/схемы" потому, что при создании нового пользователя для него создается одноименная схема. Не сразу понятно чем понятие "пользователь" отличается от понятия "схема". Чтобы понять представьте пользователя Windows (Unix). Пользователь имеет имя ИмяПользователя  и принадлежащую ему папку - C:\Users\ИмяПользователя (/home/ИмяПользователя). Так вот пользователь Oracle аналогичен пользователю Windows, а схема - аналогична папке пользователя. Точно так же как у пользователя Windows, у пользователя Oracle есть набор прав. Так же как папка пользователя Windows содержит различные файлы, также и схема Oracle содержит различные объекты - таблицы, последовательности, триггеры и др. Если продолжать аналогию, то пользователей SYS и SYSTEM можно считать Администратором Windows или root-пользователем Unix. Они имеют неограниченные права. И работать под ними не рекомендуется. По-этому сначала нужно создать еще одного пользователя.

1. Создание пользователя и предоставление ему прав


Создадим пользователя, например fiftin:
CREATE USER fiftin IDENTIFIED BY 123456;
Мы создали пользователя fiftin с паролем 123456. Он не имеет абсолютно никаких прав. Вы даже не сможете под ним зайти:
SQL> connect fiftin
Enter password:
ERROR:
ORA-01045: user FIFTIN lacks CREATE SESSION privilege; logon denied
Для наделения пользователя правами существует команда GRANT. Например дадим права пользователю fiftin на вход:
GRANT CREATE SESSION TO fiftin;
Если теперь вы попробуете подключиться как пользователь fiftin у вас это получится. Но это все что разрешено пользователю fiftin. Наделим пользователя правами администратора:
GRANT dba TO fiftin WITH ADMIN OPTION;
Теперь вы можете подцепиться к БД под fiftin'ом как админ:
connect fiftin/fiftin
Создадим таблицу:
CREATE TABLE table1(id INT, column1 INT);
Вставим данные:
INSERT INTO table1(id, column1) VALUES (0, 1)

2. Права на создание таблиц


Создадим еще одного пользователя - test:
CREATE USER test IDENTIFIED BY 123;
Дадим ему права:
GRANT create session, create table TO test;
Теперь пользователь test может подключаться и создавать таблицы. Попробуем создать таблицу (не забудьте зайти под test'ом):
CREATE TABLE tbl_test(id int, column1 INT);
Получаем ошибку:
ORA-01950: no privileges on tablespace 'SYSTEM'
Почему так? Оказывается для того чтобы обычный пользователь (не админ) мог что-либо создать в БД, ему нужно выделить для этого место. Зайдем снова под fiftin'ом и выполним команду:
ALTER USER test QUOTA 50m ON system;
Этой командой мы выделяем пользователю test 50Мб под его нужды. Попробуйте теперь зайти под пользователем test и создать таблицу и у вас получится.

3. Права на доступ к таблицам из другой схемы


Теперь предположим что пользователь test должен брать данные из таблицы table1t. По-идее для этого нужно вызвать команду:
SELECT * FROM table1;
Но это не работает. Все потому, что таблица table1 находится в схеме fiftin и пользователь test её не видит (test видит таблицы только в своей схеме). Чтобы test увидел таблицу table1 нужно явно указать что она находится в схеме test - fiftin.table1. Но если вы сейчас попробуете обратиться к таблице fiftin.table1 вы её все равно не увидите. Потому что у пользователя test нет прав на доступ к данным из другой схемы (так же как пользователь Windows не может увидеть файлы другого пользователя, если у него нет на это прав).
Чтобы дать пользователю test права на чтение данных из таблицы fiftin.table1 нужно вызвать команду:
GRANT SELECT ON fiftin.table1 TO test
Теперь повторим попытку чтения из fiftin.table1 под пользователем test. Ура, получилось!

4. Синонимы


Чтобы не писать каждый раз "fiftin.table1" Oracle предоставляет возможность создавать синонимы. Мы можем создать синоним таблицы table1 в схеме test и обращаться к ней по короткому имени.
Для начала дадим права пользователю test на создание синонимов:
GRANT CREATE SYNONYM TO test
А теперь создадим сам синоним:
CREATE SYNONYM table1 FOR fiftin.table1;
Все.

среда, 20 ноября 2013 г.

Изучаю Oracle: Начало

Oracle предоставляет бесплатную (express) версию своей СУБД, которую можно скачать на официальном сайте (потребуется зарегистрироваться).

Если ваш компьютер/сервер находится в домене, то чтобы корректно установить oracle потребуется зайти под локальной учетной записью с правами администратора. СУБД установится и под доменной учетной записью, но при этом сам экземпляр БД (instance) будет создана некорректно и его придется пересоздавать и перенастраивать. Как это сделать будет написано дальше.

Что такое "экземпляр БД"? Это отдельная БД со своим именем, пользователями, таблицами, настройками, правами. В Oracle могут быть созданы и работать несколько экземпляров БД. Экземпляр можно остановить, создать, удалить и это никак не будет влиять на другие экземпляры. По умолчанию создается только один экземпляр.

1. Проверка работы БД


Для управления БД в комплекте идет консольное приложение SQL*Plus, с помощью которой можно как настраивать БД, так и получать доступ к данных хранящимся в ней. Запустив её вы увидите:
SQL*Plus: Release 11.2.0.2.0 Production on ******************
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
SQL>
На данный момент вы просто запустили её. Но к БД доступа, на данный момент, вы не имеете. Чтобы получить доступ к БД нужно к ней подключиться. Для этого существует команда CONNECT. Чтобы с помощью неё подключиться к БД с правами администратора без логина и пароля, необходимо чтобы учетная запись пользователя под которой запущен SQL*Plus была в группах Администраторы и ORA_DBA. В этом случае команда для подключения выгладит так:
CONNECT / AS SYSDBA
Теперь проверим запущен ли экземпляр БД командой:
STARTUP
Эта команда запускает экземпляр БД. Если экземпляр уже запущен, то вы увидите:
ORA-01081: cannot start already-running ORACLE - shut it down first
Если не был запущен, но успешно запустился:
ORACLE instance started.
Total System Global Area  ********* bytes
Fixed Size                  ******* bytes
Variable Size             ********* bytes
Database Buffers          ********* bytes
Redo Buffers                ******* bytes
Database mounted.
Database opened.
Если же не был запущен и при попытке запустить возникла ошибка, вы увидите сообщение об ошибке:
ORA-01078: failure in processing system parameters
ORA-01565: error in identifying file 'C:\oraclexe\app\oracle\product\11.2.0\serv
er\dbs\spfileXE.ora'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) ?? ??????? ????? ????????? ????.
Если у вас на данном этапе не возникло проблем, то теперь вы можете делать с БД все что захотите: останавливать, запускать, создавать таблицы, добавлять данные и пункт 2 вы можете пока не читать.

2. Что делать если вы устанавливали СУБД Oracle из под доменной учетной записи и теперь не можете запустить БД


* Ниже будет использоваться абсолютный путь расположения директории Oracle, у меня это C:\ORACLEXE. Название экземпляра БД - XE.

Начнем с того, что восстановил главный настоечный файл БД - spfile. Он должен располагаться здесь - C:\ORACLEXE\APP\ORACLE\product\11.2.0\server\dbs\ и иметь имя - spfile<имя_экземпляра_БД>.ora, в нашем случае spfileXE.ora. Но его там нет. Но зато есть файл init.ora. С помощью него мы получим spfile.
Откроем init.ora:
# Change '<ORACLE_BASE>' to point to the oracle base (the one you specify at
# install time)
db_name='ORCL'
memory_target=1G
processes = 150
audit_file_dest='<ORACLE_BASE>/admin/orcl/adump'
audit_trail ='db'
db_block_size=8192
db_domain=''
db_recovery_file_dest='<ORACLE_BASE>/flash_recovery_area'
db_recovery_file_dest_size=2G
diagnostic_dest='<ORACLE_BASE>'
dispatchers='(PROTOCOL=TCP) (SERVICE=ORCLXDB)'
open_cursors=300 
remote_login_passwordfile='EXCLUSIVE'
#undo_tablespace='UNDOTBS1'
# You may want to ensure that control files are created on separate physical
# devices
control_files = (ora_control1, ora_control2)
compatible ='11.2.0'

В нем везде заменим (перед этим можно сделать резервную копию) <ORACLE_BASE> на c:\oraclexe\app\oracle и сохраняем.
Далее в SQL*Plus вызываем команду:
CREATE SPFILE='C:\ORACLEXE\APP\ORACLE\product\11.2.0\server\dbs\spfileXE.ora' FROM PFILE='C:\ORACLEXE\APP\ORACLE\product\11.2.0\server\dbs\init.ora'
Теперь мы имеем рабочий spfile и можем повторить попытку запустить экземпляр БД командой STARTUP в SQL*Plus. Теперь она должна пройти но при этом выдать ошибку:
ORACLE instance started.
Total System Global Area  644468736 bytes
Fixed Size                  1385488 bytes
Variable Size             192941040 bytes
Database Buffers          444596224 bytes
Redo Buffers                5545984 bytes
ORA-00205: error in identifying control file, check alert log for more info
Связано это с тем, что на самом деле запуск экземпляра состоит из нескольких этапов:
1) Запуск экземпляра.
2) Монтирование (mount).
3) Открытие доступа (open).
Мы смогли запустить экземпляр, но смонтировать данные не смогли. Это потому, что нам нечего монтировать - файлов содержащих данные нету. Если вы загляните в директорию C:\oraclexe\app\oracle\oradata\XE, то увидите что она пуста. Так быть не должно. Чтобы это исправить нужно вызвать команду CREATE DATABASE <имя_экземпляра_БД>, которая создаст необходимые для работы БД файлы. Синтаксис вызова такой:
CREATE DATABASE xe
   USER SYS IDENTIFIED BY 123456
   USER SYSTEM IDENTIFIED BY 123456
   LOGFILE GROUP 1 ('c:\oraclexe\app\oracle\oradata\xe\redo01.log') SIZE 100M,
           GROUP 2 ('c:\oraclexe\app\oracle\oradata\xe\redo02.log') SIZE 100M,
           GROUP 3 ('c:\oraclexe\app\oracle\oradata\xe\redo03.log') SIZE 100M
   MAXLOGFILES 5
   MAXLOGMEMBERS 5
   MAXLOGHISTORY 1
   MAXDATAFILES 100
   MAXINSTANCES 1
   CHARACTER SET US7ASCII
   NATIONAL CHARACTER SET AL16UTF16
   DATAFILE 'c:\oraclexe\app\oracle\oradata\xe\system01.dbf' SIZE 325M REUSE
   EXTENT MANAGEMENT LOCAL
   SYSAUX DATAFILE 'c:\oraclexe\app\oracle\oradata\xe\sysaux01.dbf' SIZE 325M REUSE
   DEFAULT TEMPORARY TABLESPACE tempts1
      TEMPFILE 'c:\oraclexe\app\oracle\oradata\xe\temp01.dbf' 
      SIZE 20M REUSE
   UNDO TABLESPACE UNDOTBS1
      DATAFILE 'c:\oraclexe\app\oracle\oradata\xe\undotbs01.dbf'
      SIZE 200M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
В конце выполнения команда должна выдать "Database created."
Если теперь вы заглянете в папку C:\oraclexe\app\oracle\oradata\XE, то должны увидеть следующие файлы:
REDO01.LOG
REDO02.LOG
REDO03.LOG
SYSAUX01.DBF
SYSTEM01.DBF
TEMP01.DBF
UNDOTBS01.DBF

Все. Теперь вы можете попробовать создать таблицу:
CREATE TABLE tbl_test1(id int, col1 int);
Вставить в нее данные:
INSERT INTO tbl_test1 VALUES(1, 1);
INSERT INTO tbl_test1 VALUES(2, 2);
INSERT INTO tbl_test1 VALUES(3, 3);
и считать их:
SELECT * FROM tbl_test1;