I wish to redeploy some packages.
Here the simplified code:
vCode CLOB;
SELECT DBMS_METADATA.GET_DDL('PACKAGE_BODY', 'MY_PACKAGE', USER) INTO vCode FROM DUAL t;
EXECUTE IMMEDIATE CONVERT(vCode, 'WE8MSWIN1252', 'US8PC437');
Would it be possible to check if the code would be compiled without errors?
And if so, run the EXECUTE IMMEDIATE command?
Many thanks!
Related
If I execute the following scripts on one and another CLI tool, UTL_FILE would trigger a writing error ? What would you do when you can't find ways to trigger exception errors in unit test?
script1.sql
DECLARE
OUT_HANDLE UTL_FILE.FILE_TYPE;
BEGIN
OUT_HANDLE := UTL_FILE.FOPEN('DIRECTORY','LOGFILE.TXT','R');
DBMS_SESSION.SLEEP(30);
UTL_FILE.FCLOSE(OUT_HANDLE);
END;
script2.sql
DECLARE
OUT_HANDLE UTL_FILE.FILE_TYPE;
BEGIN
OUT_HANDLE := UTL_FILE.FOPEN('DIRECTORY','LOGFILE.TXT','A');
UTL_FILE.PUT_LINE('want to trigger a writing error.');
UTL_FILE.FCLOSE(OUT_HANDLE);
END;
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>
I apologize up-front for this super-lightweight question, but I'm missing something when starting to work with sqlcl as a potential replacement for sqlplus.
sqlcl is compelling, but I'm troubled in that I'm missing how to run anonymous-blocks interactively. The below example works fine when saved as Little-Anonymous-Block.sql and run in sqlcl via #Little-Anonymous-Block.sql, but the raw pl/sql fails with the the below PLS-00103.
Little-Anonymous-Block.sql:
BEGIN
DBMS_OUTPUT.PUT_LINE('This anonymous-block ran in sqlcl!');
END;
/
Running as a Script:
SQL> SET SERVEROUTPUT ON;
SQL> #Little-Anonymous-Block.sql;
This anonymous-block ran in sqlcl!
PL/SQL procedure successfully completed.
But running ad-hoc:
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE('This anonymous-block ran in sqlcl!');
3 END;
4 /
gives:
Error starting at line : 1 in command -
BEGIN
DBMS_OUTPUT.PUT_LINE('This anonymous-block ran in sqlcl!');
END;/
PLS-00103: Encountered the symbol "/" The symbol "/" was ignored.
sqlcl appears to be conjoining the "/" with the block-terminating END;
The same command works fine in sqlplus.
Can you tell me, how do I interactively run anonymous blocks in sqlcl? I've got the early-adopter release from 20160513. java 8.0_77. Apologies for this question if its in the sqlcl manual, I didn't find much to go by on the oracle sqlcl-page.
I've found that you can run an anonymous block with exec but that has its limitations (e.g. all code on one line).
As far as I can tell what you've found is a bug. A workaround would be to end your block with a . then execute the buffer with a / as shown below:
This was indeed a bug. It should be fixed in the latest release on OTN
BARRY#orcl☘ >BEGIN
2 DBMS_OUTPUT.PUT_LINE('This anonymous-block ran in sqlcl!');
3 END;
4 /
PL/SQL procedure successfully completed.
BARRY#orcl☘ >l
1 BEGIN
2 DBMS_OUTPUT.PUT_LINE('This anonymous-block ran in sqlcl!');
3* END;
BARRY#orcl☘ >
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;
/
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;