Oracle BFILE cand Directory: сообщение об ошибке
Я не очень разбираюсь в Oracle и BFILE, поэтому прошу прощения, если ответ на мой вопрос очевиден. Я использую Oracle SQL Developer и Oracle Database 12c Enterprise Edition.
Пытаюсь сохранять изображения извне через BFILE. Для этого я создал каталог и таблицу и вставил BFILE:
DROP DIRECTORY PICTURE;
CREATE OR REPLACE DIRECTORY PICTURE AS 'C:\PICTURE';
DROP TABLE TEST1;
CREATE TABLE TEST1( NR INTEGER, IMAGE BFILE );
INSERT INTO TEST1 VALUES( 1, BFILENAME('PICTURE','IMG.png') );
Код работает без ошибок. Теперь я хочу проверить, правильно ли я вставил код. Для этого я использую следующую функцию.
SELECT DBMS_LOB.GETLENGTH(IMAGE) FROM TEST1;
После выполнения функции я получаю следующее сообщение об ошибке.
ORA-22288: file or LOB Operation GETLENGTH failed
The system could not find the specified path.
ORA-06512: in "SYS.DBMS_LOB", line 850
В чем может быть причина? Может быть, мне не разрешено указывать такой путь? Путь указывает на папку на моем компьютере. Может ли программа получить к нему доступ? Если проблема не в этом, что могло вызвать сообщение об ошибке?
ОБНОВИТЬ:
Когда я запускаю большую команду, чтобы назначить мне права, я получаю следующее сообщение об ошибке
SQL > GRANT READ, WRITE ON DIRECTORY PICTURE TO XYZ;
ORA-01749: you may not GRANT/REVOKE privileges to/from yourself
Я предположил, что это означает, что у меня уже есть права.
Подключить как работает XYZ:
SQL> show user
USER is "XYZ"
SQL> select * from all_directories where directory_name = 'EXT_DIR';
OWNER DIRECTORY_NAME DIRECTORY_PATH
------------------------------ ------------------------------ --------------------
SYS PICTURE c:\PICTURE
SQL>
Для остальной части кода мой вывод совпадает с выводом из ответа Литтлфута. Только с функцией.getlength () я получаю сообщение об ошибке, описанное выше.
Возможно, проблема в том, что мой компьютер не является сервером базы данных. Я использую ПК с Windows 10. Я скачал следующую версию:
https://www.oracle.com/de/tools/downloads/sqldev-v192-downloads.html
И я запускаю приложение каждый раз, используя следующий значок в проводнике:
Затем в SQL Developer я подключился к экземпляру базы данных. В экземпляре базы данных мне доступна схема, с помощью которой я могу настраивать файлы и управлять ими. Папка PICTURE с изображениями, как я уже сказал, находится на моем ПК на диске C: . Я пытаюсь создать каталог, который затем будет обращаться к этой папке. Могу ли я сделать это без специальной настройки моего ПК?
1 ответ
Каталог - это объект Oracle, который указывает на каталог файловой системы, который (обычно, давайте притворимся "всегда") расположен на сервере базы данных. Если ваш компьютер не таковой, он не будет работать.
Поскольку каталог указывает на c:\picture
на сервере базы данных,
- этот каталог действительно должен существовать там
- изображение должно быть в нем
- убедитесь, что вы не пропустили фактическое имя файла
- вы, как пользователь, должны иметь (как минимум)
read
привилегия доступа к нему.вот чего не хватает в опубликованном вами коде. Пользователь (SYS, я полагаю), создавший каталог, должен был запустить, например
grant read, write on directory picture to sql_user;
(или любого другого пользователя, которого вы действительно используете).
Вот вам пример. Я бегу Oracle 11gXE на моем ноутбуке (так это сервер базы данных). Файл находится вc:\temp
каталог, который установлен как Oracle EXT_DIR
каталог.
c:\Temp>dir robco.jpg
Volume in drive C is OSDisk
Volume Serial Number is 7635-F892
Directory of c:\Temp
25.09.2017. 20:27 6.427 robco.jpg
1 File(s) 6.427 bytes
0 Dir(s) 234.166.730.752 bytes free
c:\Temp>
Давайте посмотрим на сторону Oracle: сначала предоставьте доступ пользователю scott
(кто загрузит файл):
SQL> show user
USER is "SYS"
SQL> grant read, write on directory ext_dir to scott;
Grant succeeded.
SQL>
Подключиться как scott
:
SQL> show user
USER is "SCOTT"
SQL> select * from all_directories where directory_name = 'EXT_DIR';
OWNER DIRECTORY_NAME DIRECTORY_PATH
------------------------------ ------------------------------ --------------------
SYS EXT_DIR c:\temp
SQL>
Создайте таблицу, вставьте строку, проверьте содержимое:
SQL> CREATE TABLE TEST1( NR INTEGER, IMAGE BFILE );
Table created.
SQL> INSERT INTO TEST1 VALUES( 1, BFILENAME('EXT_DIR','robco.jpg') );
1 row created.
SQL> SELECT * FROM test1;
NR IMAGE
---------- --------------------------------------------------
1 bfilename('EXT_DIR', 'robco.jpg')
SQL> SELECT DBMS_LOB.GETLENGTH(IMAGE) FROM TEST1;
DBMS_LOB.GETLENGTH(IMAGE)
-------------------------
6427
SQL>
Итак, если все сделано правильно, все работает.