Show errors in sql plus - sql

I have a file myFile.sql that contains a list of script to compile :
#"Directory\package1.sql"
#"Directory\package2.sql"
#"Directory\package3.sql"
#"Directory\package4.sql"
I have the following script:
SPOOL Directory\Upgrade.log
#"Directory\myFile.sql"
SPOOL OFF
Some packages in myFile.sql have errors, but in Upgrade.log I do not have the details of the errors, I have the message Warning : Package body created with compilation errors.
How can I add the error detail without adding SHOW ERR after each line in MyFile.sql ?
In upgrade.log I want have this:
Package1 created
Warning Package body created with compilation errors.
**Error detail1**
Package2 created
Warning Package body created with compilation errors.
**Error detail2**
I need a hook in sqlplus to show error automatically after each package creation if there is an error
Thanks for your help.

One method is to query dictionnary view USER_ERRORS, or ALL_ERRORS.
From the documentation:
ALL_ERRORS describes the current errors on the stored objects accessible to the current user.
USER_ERRORS gives the same information for objects owned by the current user.

From Oracle 11.1 onward, you could use the SQLPlus error logging feature. You can read more about SQL*Plus error logging – New feature release 11.1.
SQL*Plus error logging is set OFF by default. So, you need to set errorlogging on to use the SPERRORLOG table.
Demo:
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> desc sperrorlog;
Name Null? Type
----------------------------------------- -------- ----------------------------
USERNAME VARCHAR2(256)
TIMESTAMP TIMESTAMP(6)
SCRIPT VARCHAR2(1024)
IDENTIFIER VARCHAR2(256)
MESSAGE CLOB
STATEMENT CLOB
SQL> truncate table sperrorlog;
Table truncated.
SQL> set errorlogging on;
SQL> selct * from dual;
SP2-0734: unknown command beginning "selct * fr..." - rest of line ignored.
SQL> select timestamp, username, script, statement, message from sperrorlog;
TIMESTAMP USERNAME STATEMENT MESSAGE
----------- -------- ------------------ -------
17-APR-2020 SCOTT selct * from dual; SP2-0734: unknown command beginning "selct * fr..." - rest of line ignored.
Similarly, you can capture PLS errors too. They will start with error code SP.

Related

oracle sql developer first time user

I am new to plsql and trying to use oracle sql developer, I try to run a simple procedure with dbms output line and i get the following error,
ora-00904
, the code is
create or replace PROCEDURE proc_101 IS
v_string_tx VARCHAR2(256) := 'Hello World';
BEGIN
dbms_output.put_line(v_string_tx);
END;
whether i click the run(green colour) or debug(red colour) i get the same error.
You can see from the above code, procedure doesn't access any objects but still i get the same error.
Your procedure is fine. You may not have permissions to be able to Create a Procedure. If this is the case test your procedure/code without actually Creating it in the Database first. For example, when I'm testing code in my Production database my oracle user cannot Create Procedures, Packages, Tables etc... And so I test my Procedures within my Own PL/SQL Blocks. When the code is good to go I can get a database administrator to Create the Procedures and/or Packages for me.
The below screenshot is code that simply tests the Procedure:
The below screenshot is code that does much more and tests the Procedure from within a PL/SQL Block
For more advanced situations this allows you to do so much more as you can create all sorts of Procedures/Functions and/or Cursors and test them immediately without needing to CREATE these objects in your Oracle Database.
I'd say that there's some other code in the worksheet which raises that error, not just the CREATE PROCEDURE you posted. For example, something like this SQL*Plus example (just to show what's going on - you'd get the same result in SQL Developer):
SQL> select pixie from dual;
select pixie from dual
*
ERROR at line 1:
ORA-00904: "PIXIE": invalid identifier
SQL>
SQL> create or replace PROCEDURE proc_101 IS
2 v_string_tx VARCHAR2(256) := 'Hello World';
3 BEGIN
4 dbms_output.put_line(v_string_tx);
5 END;
6 /
Procedure created.
SQL>
See? The first part raised ORA-00904 as there's no PIXIE column in DUAL, while the procedure is created correctly.
So - remove code which fails and everything should be OK.
Check with your DBA to make sure the dbms_output package has been installed on your database, and that you have permissions on it.

How to trace a SQL which causes error

My database has many kinds of clients and sometimes they use a wrong SQL string. but those clients were written in different languages such as C++, C, Java, .Net it's not possible that I learn all of them.
When a error happened ORA-00942 for example, how can I know what the SQL text is by just using Oracle or some Oracle utils if I don't know how to print the SQL text in client?
AFAIK the "only" option is to trace the whole server. You have to create a special type of the trigger AFTER SERVERERROR ON DATABASE.
See: http://www.red-database-security.com/scripts/oracle_error_trigger.html
There are probably other ways of doing that, but they are too low-level.
Like: OCI tracing, JDBC tracing or some alter system set events ...
Summary: a session trace will NOT contain a statement which failed parsing.
More advanced topics:
JDBC driver support standard logging
OCI drivers support "interceptor" library. You have to set some environment variable and let it point onto our own .dll library. OCI driver will load this library and will call callbacks from this lib on various events. It is described in OCI Programming reference and also AFAIK you can find some sample interceptor library on SF
.Net tracing is documented here
Yes it is very much possible. It is a new feature in SQL*Plus. Read SQL*Plus error logging – New feature release 11.1 to know more about the feature in depth.
NOTE : SQL*Plus error logging is set OFF by default. So, you need to “set errorlogging on” to use the SPERRORLOG table.
The SPERRORLOG table looks like this:
SQL> desc sperrorlog;
Name Null? Type
----------------------------------------- -------- ----------------------------
USERNAME VARCHAR2(256)
TIMESTAMP TIMESTAMP(6)
SCRIPT VARCHAR2(1024)
IDENTIFIER VARCHAR2(256)
MESSAGE CLOB
STATEMENT CLOB
For example,
SQL> set errorlogging on
SQL>
SQL> SELECT * FROM dula;
SELECT * FROM dula
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL>
SQL> SELECT USERNAME, TIMESTAMP, MESSAGE, STATEMENT FROM sperrorlog;
USERNAME TIMESTAMP MESSAGE STATEMENT
---------- ------------------------------ -------------------------------------------------- ------------------
LALIT 10-MAR-15 04.08.13.000000 PM ORA-00942: table or view does not exist SELECT * FROM dula
SQL>
So, the statement which had an error is now logged in the SPERRORLOG table.
EDIT
My database has many kinds of clients and sometimes they use a wrong SQL string. but those clients were written in different languages such as C++, C, Java, .Net
The above mentioned solution is only applicable for the scripts executed via SQL*Plus. If the queries are executed through the application client, then to find the complete information you could trace the entire session that the application is using to interact with the database.
You could have a look at this article for an example on how to generate a trace file.

Oracle PL/SQL: How to find unused variables in a long package?

Please suppose you have an Oracle PL/SQL package of about 200,000 rows of code.
Is there any fast way to detect variables declared, but not used in the package?
Thank you in advance for your kind help.
EDIT (April 7th, 2014): I am using Oracle 10G.
EDIT: I am looking for a pure PL/SQL solution.
The following only applies to 11g R2. It looks like PL/Scope has become available in 11g R1.
You won't get information about unused variables with PLSQL_WARNINGS='ENABLE:ALL':
SQL> !cat test.sql
set serveroutput on
alter session set plsql_warnings = 'ENABLE:ALL';
create or replace procedure foo is
v_a number;
v_b varchar2(10);
begin
dbms_output.put_line('hello world!');
end;
/
show errors
exec foo
SQL> #test
Session altered.
SP2-0804: Procedure created with compilation warnings
Errors for PROCEDURE FOO:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1 PLW-05018: unit FOO omitted optional AUTHID clause; default
value DEFINER used
hello world!
PL/SQL procedure successfully completed.
SQL>
As you can see the only reported warning is not related to the unused variables at all. Instead PL/Scope has to be used.
The following example has bee derived from Oracle 11g – Generating PL/SQL Compiler Warnings (Java style) using PL/Scope:
SQL> alter session set plscope_settings = 'identifiers:all';
Session altered.
SQL> alter procedure foo compile;
SP2-0805: Procedure altered with compilation warnings
SQL> show errors
Errors for PROCEDURE FOO:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1 PLW-05018: unit FOO omitted optional AUTHID clause; default
value DEFINER used
SQL> #plsql-unused-variables.sql
Enter value for name: foo
old 10: where object_name = upper('&name')
new 10: where object_name = upper('foo')
Enter value for type: procedure
old 11: and object_type = upper('&type')
new 11: and object_type = upper('procedure')
COMPILER_WARNING
--------------------------------------------------------------------------------
V_B: variable is declared but never used (line 3)
V_A: variable is declared but never used (line 2)
SQL>
The script plsql-unused-variables.sql is just a cut and paste from the blog post mentioned above. Because I found it useful I have also made the script available in Bitbucket.
Set your session to report all warnings:
ALTER SESSION SET PLSQL_WARNINGS='ENABLE:ALL';
then compile your code. If the compilation indicates that there are errors, as in you get something like the following:
SP2-0804: Procedure created with compilation warnings
display any errors:
SHO ERR
If you have any unreferenced variables they should be mentioned in the list of errors. Alternatively, use a tool like PL/SQL Developer which automatically shows you these errors following a compile.
Share and enjoy.
PL/SQL waits to allocate memory until you assign the variable, then only
allocates as much storage as needed. So no need to worry about consuming memory. (Source)
So finding and fixing unused variables is just a housekeeping exercise and won't improve the performance of the package. In other words, the simplest solution would be to do nothing.
If you're worried about unused variables anyway, you might be able to find them just by parsing the package source with command-line tools such as grep, sort and uniq (especially if they follow a coding standard such as starting all variables with v_).

Can't create Oracle Text index with sync (every...)

I'm trying to create an Oracle text index on a CLOB column in a table but whenever I try to specify the sync parameter as 'SYNC (EVERY "(sysdate+30/24/60/60)")' it fails with some errors about having insufficient privileges.
The tables is defined as:
CREATE TABLE MESSAGE
(
MESSAGE_ID NUMBER(19,0),
FROM NUMBER(19,0),
TO NUMBER(19,0),
RECEIVED_AT TIMESTAMP (6),
MESSAGE_TYPE_ID NUMBER(19,0),
MESSAGE_DATA CLOB,
IS_SEARCHABLE CHAR(1 BYTE)
)
So when I try to create the text index on the message_data column as:
BEGIN
CTX_DDL.CREATE_PREFERENCE('msg_data_lexer', 'BASIC_LEXER');
CTX_DDL.SET_ATTRIBUTE('msg_data_lexer', 'skipjoins', '_-');
CTX_DDL.CREATE_PREFERENCE('msg_data_wordlist', 'BASIC_WORDLIST');
CTX_DDL.SET_ATTRIBUTE('msg_data_wordlist', 'SUBSTRING_INDEX', 'YES');
CTX_DDL.SET_ATTRIBUTE('msg_data_wordlist', 'PREFIX_INDEX', 'TRUE');
CTX_DDL.SET_ATTRIBUTE('msg_data_wordlist', 'PREFIX_MIN_LENGTH', '3');
CTX_DDL.SET_ATTRIBUTE('msg_data_wordlist', 'PREFIX_MAX_LENGTH', '6');
END;
/
CREATE INDEX message_msg_data_txt_idx on message(message_data)
INDEXTYPE IS CTXSYS.CONTEXT
FILTER BY message_type_id, from_entity, to_entity, is_searchable
PARAMETERS ('DATASTORE CTXSYS.DEFAULT_DATASTORE
FILTER CTXSYS.NULL_FILTER
LEXER msg_data_lexer
SYNC (EVERY "SYSDATE + (30/24/60/60)")
WORDLIST msg_data_wordlist');
So basically I want to create an index that syncs every 30 seconds because this is a table where lots of new messages will be added all the time (potentially hundreds to thousands of messages per second).
When the create index is run, it outputs:
Error at Command Line:1 Column:13
Error report:
SQL Error: ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-20000: Oracle Text error:
DRG-50857: oracle error in drvddl.IndexCreate
ORA-27486: insufficient privileges
ORA-06512: at "CTXSYS.DRUE", line 160
ORA-06512: at "CTXSYS.TEXTINDEXMETHODS", line 366
29855. 00000 - "error occurred in the execution of ODCIINDEXCREATE routine"
The user has all the necessary privileges as far as I know. If I either remove the 'sync' parameter or change it to 'SYNC (ON COMMIT)', then the index gets created properly.
Why can't I set the sync parameter to 'every'? What am I doing wrong?
The version of Oracle I'm using is:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
After digging through Google, that's what I have finally come across:
EVERY interval-string - Automatically synchronize the index at a regular interval specified by the value of interval-string. interval-string takes the same syntax as that for scheduler jobs. Automatic synchronization using EVERY requires that the index creator have CREATE JOB privileges.
Taken from here: about Oracle Text
I tried to run your code and got the same error as you did. However, after:
GRANT CREATE JOB TO my_user;
I was able to create the index without any errors.

Oracle 10gR2 trigger error

I have Oracle 10gR2. I am trying to create autoincrement trigger.
Here is the sample:
CREATE SEQUENCE TEST_SEQ
INCREMENT BY 1
START WITH 1
NOMAXVALUE
/
CREATE TABLE TESTER (
ID_TESTER INTEGER NOT NULL,
VAL VARCHAR2(20) NOT NULL
)
/
CREATE OR REPLACE TRIGGER TIB_TESTER BEFORE INSERT
ON TESTER FOR EACH ROW
BEGIN
SELECT TEST_SEQ.NEXTVAL
INTO :NEW.ID_TESTER
FROM DUAL;
END;
/
Trigger creation gives warning:
warning : ORA-24344: success with
compilation error
And when I get error value:
select OCI_SUCCESS_WITH_INFO;
/
It gives error:
error : ORA-00923: FROM keyword not
found where expected
What client are you using to issue these commands? ORA-24344 is a perculiar error.
In SQL*PLus we can get more information about compilation errors like this:
SQL> show errors
As for the ORA-00923 error, that is because in Oracle's version of SQL we always have to select from a table. So you should execute
select OCI_SUCCESS_WITH_INFO
from dual
/
I'm not sure how much sense that makes, but at least you won't get the error.
"It was Navicat problem"
That doesn't surprise me, as I ran your code against my database and it built without a hitch.
Maybe it will be useful for somebody:
If you are using Oracle 10g and OCI driver, ORA-24344 shows when trigger have carriage return sign (\r) in code eg. file was created with Windows end of line style.