Oracle BFILE cand Directory: Error message - sql

I am not very experienced with Oracle and BFILEs, so I apologize if the answer to my question is very obvious.
I am using Oracle SQL Developer and Oracle Database 12c Enterprise Edition.
I try to save images externally via BFILE. For this I created a directory and a table and inserted the BFILEs:
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') );
The code runs without errors. Now I want to check that I have pasted the code correctly. To do this, I use the following function.
SELECT DBMS_LOB.GETLENGTH(IMAGE) FROM TEST1;
After executing the function, I get the following error message.
ORA-22288: file or LOB Operation GETLENGTH failed
The system could not find the specified path.
ORA-06512: in "SYS.DBMS_LOB", line 850
What can be the reason? Could it be that I am not allowed to specify the path like this? The path points to a folder on my PC. Can the program access it? If that's not the problem, what could be causing the error message?
UPDATE:
When I run the Grand command to assign me the rights, I get the following error message
SQL > GRANT READ, WRITE ON DIRECTORY PICTURE TO XYZ;
ORA-01749: you may not GRANT/REVOKE privileges to/from yourself
I assumed that means I already have the rights.
Connect as XYZ works:
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>
For the rest of the code, my output coincides with the output from Littlefoot's answer. Only with the .getlength () function do I get the error message described above.
It could be that the problem is that my PC is not a database server. I use a PC with Windows 10. I have downloaded the following Version:
https://www.oracle.com/de/tools/downloads/sqldev-v192-downloads.html
And I run the application every time using the following icon from the Explorer:
SQL Developer Icon
In the SQL Developer I then connected to a database instance. In the database instance a scheme is available to me with which I can set up and manage files. The PICTURE folder with the pictures is, as I said, on my PC in drive C: . I am trying to create a directory which then accesses this folder. Can I do that without having specially configured my PC?

Directory is an Oracle object which points to a filesystem directory which is (usually; let's pretend "always") located on a database server. If your PC isn't one, then it won't work.
As directory points to c:\picture on the database server,
that directory must really exist there
image must be in it
make sure that you didn't miss the actual file name
you, as user, have to have (at least) read privilege to access it.
that's what is missing in code you posted. User (SYS, I presume), who created the directory, should have ran e.g.
grant read, write on directory picture to sql_user;
(or whichever user you really use).
Here's an example. I'm running Oracle 11gXE on my laptop (so it is a database server). File is located in c:\temp directory which is set to be Oracle EXT_DIR directory.
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>
Let's see the Oracle side: first, grant access to user scott (who will load the file):
SQL> show user
USER is "SYS"
SQL> grant read, write on directory ext_dir to scott;
Grant succeeded.
SQL>
Connect as 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>
Create a table, insert a row, check the contents:
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>
So, if everything is done properly, it works.

Related

Creating schema for oracle sql developer

I have download the oracle sql developer version 21.2.1 and I want to create a new connection. But I do not have any schema created. Can somebody help me or any links would be helpful.
Note: I have searched on youtube and google. All the tutorials that I have seen seems to have already a schema.
Well, SQL Developer you downloaded is just a tool you'd use to access an Oracle database. What you need next is the database itself. Once you download & install it, create user (schema). This is 11g database version example:
Connect as a privileged user (SYS if you don't have any other; and you probably don't) using SQL*Plus (command-line tool):
SQL> connect sys/password_goes_here#xe as sysdba
Connected.
SQL> select tablespace_name from dba_tablespaces;
TABLESPACE_NAME
------------------------------
SYSTEM
SYSAUX
UNDOTBS1
TEMP
USER_DATA
Create user:
SQL> create user will identified by ashoti
2 default tablespace user_data
3 temporary tablespace temp
4 quota unlimited on user_data;
User created.
Grant privileges which will allow that user to actually do something:
SQL> grant create session to will;
Grant succeeded.
SQL> grant create table to will;
Grant succeeded.
That's it; connect as newly created user:
SQL> connect will/ashoti#xe
Connected.
SQL> create table test as select sysdate as datum from dual;
Table created.
SQL> select * from test;
DATUM
----------
06.10.2021
SQL>
It works; moreover, it means that you should now be able to establish connection via SQL Developer as well.

Cannot Create Tablespace

I am using Oracle Database 12c.
I am trying to create a tablespace, but whenever I execute the following command, I run into an error:
create tablespace ts_something
datafile 'C:\test.dbf'
size 32m autoextend on;
The error I get is as follows:
ORA-01119: error in creating database file 'C:\test.dbf'
ORA-27040: file create error, unable to create file
OSD-04002: unable to open file
O/S-Error: (OS 5) Access is denied.
What can I do so that I may successfully create this tablespace?
If you (and apparently, you have) already created a database, locate current database files and specify the same directory. Something like this for my XE:
C:\oraclexe\app\oracle\oradata\XE
You must have the CREATE TABLESPACE system privilege.
i.e. to create a tablespace, you must have the SYSDBA system privilege.
Before you can create a tablespace, you must create a database to contain it, and the database must be open.

Why isn't Oracle DROP USER CASCADE removing all remants of a user from disk?

I need to eliminate all remnants of specific users from an Oracle 11g R2 database. This means not only deleting the users one by one, but also deleting all objects associaated with that user, in addition to all physical remnants on the disk, such as .dbf files.
I read several articles suggesting syntax for this, and settled on the following series of two lines for each user:
DROP USER <username> CASCADE;
DROP TABLESPACE <username> INCLUDING CONTENTS AND DATAFILES;
I then typed SELECT USERNAME, DEFAULT_TABLESPACE FROM DBA_USERS; and confirmed that the USER with the specific username was not included in the results.
But I also have the folder containing the .DBF files open, and I notice that the .DBF files are not deleted even though the Oracle SQL Developer interface tells me that both of the two above commands succeeded.
What specific syntax or other actions do I need to take in order to delete EVERY remnant of the user and its associated schema, etc. from an Oracle 11g R2 database?
ONGOING RESEARCH:
After reading #EliasGarcia's approach, I tried his first command select tablespace_name from dba_data_files where file_name = 'file_including_path' for the same username that was used in the preceding commands in the OP. But this query did not produce any results because the table space was deleted by the two commands shown above in my OP.
Given that I have to delete the user and all objects related to the user also, can someone please show how to combine the OP approach with #EliasGarcia's approach? For example, the OP is asking for something like DROP USER username CASCADE INCLUDING CONTENTS AND DATAFILES;
I hesitate to simply delete the .dbf files after running the above commands.
Datafiles are allocated to tablespaces, not users. Dropping the users will remove the tables etc. from the tablespace, but the underlying storage is not affected.
Don't delete the dbf files from the filesystem directly, you'll get your database into a mess. To remove them, find which tablespace the files belong to using the following statement:
select tablespace_name
from dba_data_files
where file_name = <file name with full path>;
You can then remove the file(s) by dropping the tablespace:
drop tablespace <tablespace_name> including contents and datafiles;
Before doing this you should verify that there aren't any objects still allocated to the tablespace for other users however. You can find this by running:
select * from dba_segments
where tablespace_name = <tablespace to drop>;
If this returns anything, move the objects to another tablespace if you want to keep them before dropping the tablespace.

How to find all users who have say Select grants on a Oracle Table

I am able to find all grants provided to a user but not for all users for a table . like TOAD shows under grants tab in the Table Describe window.
You need to check the below tables:
select * from USER_ROLE_PRIVS;
select * from USER_TAB_PRIVS;
select * from USER_SYS_PRIVS;
Also check this script which finds user who has previleges.
Description : Use this script to find which users have been granted
the privilege passed in. The script checks hierarchically for each
user granted the privileges via a role.
The output can be directed to either the screen via dbms_output or to a file via utl_file. The method is decided at run time by
choosing either 'S' for screen or 'F' for File. If File is chosen then
a filename and output directory are needed. The output directory
needs to be enabled via utl_file_dir prior to 9iR2 and a directory
object after.

PLS-00201: identifier UTIL_FILE must be declared

I'm trying to export data from a query into a csv file from Oracle Enterprise Express installed on a Windows Server 2008 machine.
I've found this solution:
http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:235814350980
which basically writes a function and uses the UTIL_FILE object to create and write to a file and add delimiters.
I receive the follow error when I try and create the function in Oracle SQL Developer:
PLS-00201: identifier UTIL_FILE must be declared.
When I run the following command:
select owner, object_type from all_objects where object_name = 'UTL_FILE'
The result is:
OWNER Object Type
--------- -----------
PUBLIC SYNONYM
EDIT:
Running:
GRANT EXECUTE ON UTL_FILE TO PUBLIC
Gives:
Error starting at line 2 in command:
GRANT EXECUTE ON UTL_FILE TO PUBLIC
Error report:
SQL Error: ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
*Cause:
*Action:
What is the problem?
Seems like lack of privileges to me. Often PUBLIC user has EXECUTE privilege granted on that package, but the privilege may be revoked.
You can check if PUBLIC has that privilege by issuing the following query:
SELECT * FROM all_tab_privs WHERE grantee = 'PUBLIC' AND table_name = 'UTL_FILE';
If there are no rows returned, try granting the execute privilege to either the user you are logged as, or to PUBLIC, as some privileged user, for example SYS:
GRANT EXECUTE ON SYS.utl_file TO user_name;
Edit
You must grant the privilege while being logged as, for example, SYS user.
Users do not have execute permission on UTL_FILE by default. To use UTL_FILE, an ADMIN user or instance administrator must explicitly GRANT EXECUTE permission on it, such as in the following example:
GRANT EXECUTE ON SYS.UTL_FILE TO scott;
Aside from the possible lack of permissions that other answers have covered, your question says the error you get is:
PLS-00201: identifier UTIL_FILE must be declared
That suggests you've referenced UTIL_FILE, rather than the built-in package UTL_FILE, in your function. It might be an error you've introduced writing the question, of course, but you used it in the text too so maybe you have got the package name wrong in your code, if you didn't just copy-and-paste Tom's code.
You'll still need execute privileges on UTL_FILE anyway, if you don't have them already.
As user: h_djebli pointed out in his comment you need to be connected as SYS user in the first place.
To do that, you have to be in your oracle home directory :
cd $ORACLE_HOME
Then execute :
sqlplus / as sysdba
sqlplus will start in your terminal and you'll be connected as the SYS user.
You can finally write the GRANT command in your sqlplus console :
GRANT EXECUTE ON SYS.utl_file TO your_db_username;
We can do this via cmd, with these steps:
Login as sysdba (connect sys as sysdba + enter password as sys_password)
grant execute on utl_file to <user_name>.
now we can check by query :'SELECT * FROM all_tab_privs WHERE grantee = 'PUBLIC' AND table_name = 'UTL_FILE';'