PL/SQL ORA-01031 Insufficient Privilege In conditional statement - oracle

I've got pl/sql script which can be run in two modes: 1) on test database where I've got full access 2) on prod database where I've got limited access
part of the script:
<code>
IF mode = 'test' then
DELETE FROM TABLE1;
END IF;
</code>
In test database I've got full access to TABLE1 and I haven't got access in prod database so I don't want to execute delete staement. I want run the script on both databses just changing the mode parameter. But the compiler gives ORA-01031 Insufficient Privilege. Are there any methods to overcome the situation?

Use EXECUTE IMMEDIATE:
<code>
IF mode = 'test' then
EXECUTE IMMEDIATE 'DELETE FROM TABLE1';
END IF;
</code>

Related

Oracle kill sessions procedure

I want to create procedure which will kill all session. After I run the statement i get error:
[Warning] ORA-24344: success with compilation error 10/13 PL/SQL:
ORA-00942: table or view does not exist 6/6 PL/SQL: SQL Statement
ignored 15/31 PLS-00364: loop index variable 'V_KILL' use is invalid
15/9 PL/SQL: Statement ignored (1: 0): Warning: compiled but with
compilation errors
CREATE OR REPLACE PROCEDURE KILL_ORACLE_SESSIONS
IS
BEGIN
FOR v_kill IN
(SELECT
'alter system kill session '''
||sid||','||serial#||',#1'|| ''' immediate;' as statement
FROM
v$session
WHERE
sql_id='sql_id_here'
)
LOOP
dbms_output.put_line (v_kill.statement);
END LOOP;
END;
/
Where is the catch ?
Thanks
Most likely you don't have permissions to select view v$session because your user received this privilege by a ROLE. Privileges inside a PL/SQL block must be granted directly to the user (i.e. GRANT SELECT ON V$SESSION TO {username};). A role (for example DBA ROLE) does not apply inside PL/SQL.

I want to run this code on oracle 10g but it gives me an error

When I run this it gives me the error
ORA-00911: invalid character
CREATE OR REPLACE DIRECTORY CDATA AS 'D:\';
GRANT READ ON DIRECTORY CDATA TO PUBLIC;
DECLARE
MYFILE UTL_FILE.FILE_TYPE;
type array IS VARRAY(10) OF INTEGER;
arr array;
temp number;
curr number;
prev number;
n number;
BEGIN
MYFILE := UTL_FILE.FOPEN('CDATA','FILING.txt','W');
arr := array(98, 97, 78, 87, 92, 33, 12, 45, 45, 66);
n:= arr.count;
UTL_FILE.PUT(MYFILE, 'ORGANIZED DATA: ');
for i in 2..arr.count loop
curr:=i;
prev:=i-1;
while arr(prev) > arr(curr) loop
temp:= arr(curr);
arr(curr):= arr(prev);
arr(prev):= temp;
curr:= curr-1;
prev:= prev-1;
IF curr=1 THEN
EXIT;
END IF;
end loop;
end loop;
for i in 1.. arr.count loop
UTL_FILE.PUT_LINE(MYFILE, arr(i));
dbms_output.put_line(arr(i));
end loop;
UTL_FILE.FCLOSE(MYFILE);
END; //ORA-00911: invalid character
// File is not writting
Unable to write sorted data into file from insertion algorithm
I ran your query as a normal (public) user. There was no error as ORA-00911: invalid character. There was another error, which is expected as per the code you are running. When I ran your script as a dba user, there was no error at all.
First Approach: As a public user, you would get first error as
"insufficient privileges"
when the create directory line executes. Then you would get
"directory does not exist"
when the plsql script executes.
This is because, the directory creation and grant script have to run with dba privilege (it is a privilege that user account like 'sys' possess). The rest of the script i.e. that plsql block can run from a public user. As normal user does not have directory creation and grant privilege, hence the error.
Now, if you move directory creation to grant lines to run with a dba user, they will run fine, the above 2 errors would be gone. Then when you run the plsql block with a public user, there will be a third error
"directory access denied"
. This is because, in your grant script you have given read access on the directory object to public, while in your plsql block you are actually writing to it. To handle that, modify grant script to -
GRANT READ,WRITE ON DIRECTORY CDATA TO PUBLIC;
Second Approach
You can run the whole script including the plsql block using a dba user, where your script would encounter no errors at all.
I would suggest the best approach would be to run directory creation and grant script from a dba user and then run the plsql block from a normal nondba user, with the grant script modified as above.

Execute Oracle stored procedure in operation manager configuration

I have a stored procedure with 3 parameters. I want to execute this from configuration in operation manager. I used like this :
begin
saman_test.CONVERTHISTORY('$Config/JobType$','$Config/HostFQDN$','$Config/Environment$'); end;
but it does not work without any error.
And I used this code:
exec
saman_test.CONVERTHISTORY('$Config/JobType$','$Config/HostFQDN$','$Config/Environment$')
but I get this error :
ORA-00900: invalid SQL statement
How do I execute my procedure?
I find the keyword for execute my procedure.
call
saman_test.CONVERTHISTORY('$Config/JobType$','$Config/HostFQDN$','$Config/Environment$')

Ignoring User Exists Error in Oracle

I have created a script that creates Oracle users and grants them roles. I am unable to find a way to ignore the "user exists" error:
ORA-01920: user name '' conflicts with another user or role name.
I understand that when the script is ran, it is possible that the user already exists, but I want to ignore any returned errors. Is this possible?
My Oracle code:
CREATE USER "John" PROFILE "DEFAULT" IDENTIFIED BY "temppassword" ACCOUNT UNLOCK;
Edit:
This question is not asking how to create a user if it doesn't exist. This question is asking how to ignore "the user exists" error. According to a previously asked question, the top answer stated
In general, Oracle scripts simply execute the CREATE statement, and if
the object already exist, you'll get an error indicating that, which
you can ignore. This is whaat all the standard Oracle deployment
scripts do.
It isn't clear how you're running your script, but assuming its via SQL*Plus you can modify the behaviour when an error is encountered with the whenever sqlerror command.
If your script is setting that to exit at the moment, or you're picking that up from a startup script (login.sql, glogin.sql) you can change it back, or modify it temporarily:
...
-- do not stop on error
WHENEVER SQLERROR CONTINUE;
CREATE USER "John" PROFILE "DEFAULT" IDENTIFIED BY "temppassword" ACCOUNT UNLOCK;
-- to stop when later errors are encountered
WHENEVER SQLERROR EXIT FAILURE;
ALTER USER ...
You'll still see the ORA-01920 in the output but it will continue on to execute the next statement. This pattern is also useful for a protective drop of a schema object before attempting to create it.
Why can't you find if the user exists first?
SELECT COUNT(*)
INTO V_count
from ALL_USERS
where username = 'YourUserName'
IF v_count = 0 THEN
--create the user
--execute the grants
ELSE
---log that the user already exists
END IF;
SET SERVEROUTPUT ON;
DECLARE
TYPE t_list IS TABLE OF VARCHAR2 (30);
l_list t_list := t_list ('X0', 'X1', 'X2');
e_user_already_exists EXCEPTION;
PRAGMA EXCEPTION_INIT (e_user_already_exists, -1920);
BEGIN
FOR l_iterator IN 1 .. l_list.COUNT LOOP
DBMS_OUTPUT.PUT_LINE ('Creating user ' || l_list (l_iterator));
BEGIN
EXECUTE IMMEDIATE 'CREATE USER "' || l_list (l_iterator) || '" PROFILE DEFAULT IDENTIFIED BY "WELCOME" ACCOUNT UNLOCK';
EXECUTE IMMEDIATE 'GRANT SOME_APPLICATION_ROLE TO ' || l_list (l_iterator);
EXCEPTION
WHEN e_user_already_exists THEN
DBMS_OUTPUT.PUT_LINE ('User exists, ignored');
WHEN OTHERS THEN
RAISE;
END;
END LOOP;
END;
/

Execute copy from command from plsq

How to execute copy from command inside a plsql block?
E.g. I have copy from test/test#test insert emp using select * from emp;
How can I call this in a plsql block? I have tried with
execute immediate 'copy from test/test#test insert emp using select * from emp';
However when I execute my script which has plsql block gives me
ORA-00900: invalid SQL statement
How can I resolve this issue
COPY is a SQL*Plus command. So it only works in the SQL*Plus client. Find out more.
EXECUTE IMMEDIATE is a PL/SQL command to run dynamic calls, and it only recognises SQL and PL/SQL.
"I am executing sqlscript from sqlplus"
Yes, but you are calling COPY in an anonymous block, so that's with a PL/SQL scope; which means PL/SQL and SQL only.
The way to do this is with a shell script. These are operating system dependent, but something like this would work on a Linux environment.
#!/bin/bash
echo Please enter local Username:
read USERNAME
echo "Please enter local Password:"
read -s PASS
SID=${ORACLE_SID}
if [ "${ORACLE_SID}" != 'TEST' ]
then
sqlplus -s -l $USERNAME/$PASS#$SID << EOF
copy from test/test#test insert emp using select * from emp
exit
EOF
else
echo "Can't copy from TEST to TEST"
fi
Obviously this is just a wild guess at what your program actually does, but I hope you can understand the principle.
In a plsql code if we directly use the command as follows shall serve the similar output
begin
insert into emp1 select * from emp;
end;
emp1 is target table
emp is source table
There are similar ask where one wants to create blank structure or structure with data for backup kindly of activity.Refer link https://oracle-concepts-learning.blogspot.com/2019/09/copy-table-structure-or-data.html
1) Creating blank structure from existing table
--Execute on sql prompt
begin
execute immediate 'create table emp1 as select * from emp where 1=2';
end;
--Execute on sql prompt
select count(1) from emp1;
2) Creating structure from existing table with data
--Execute on sql prompt
begin
execute immediate 'create table emp1 as select * from emp';
end;
--Execute on sql prompt
select count(1) from emp1;

Resources