Difference between oracle call and execute in context of error throwing - sql

I have some procedure written in Oracle. Unfortunately I can't show its code. Somewhere inside it is select where execution crashed because of absence of required data. It looks like this
select value into l_value
from config
where code = upper(p_code);
So when I call this procedure like this (in SqlDeveloper)
execute some_package.some_procedure('CODE');
it throws
Error report -
ORA-01403: no data found
ORA-06512: at "XXXXXXXXXXXXXXXXXXX", line 111
ORA-06512: at "XXXXXXXXXXXXXXXXXXX", line 111
ORA-06512: at line 1
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
But when I call it like this
call some_package.some_procedure('CODE');
it crashes at the same place (as I can suggest from the result, stored in DB), but it does no throw an exception.
some_package.some_procedure('CODE') succeeded.
What happens? And why there is such difference?

NO_DATA_FOUND exception behavior is special. It is handled by default in SQL context but not in PL/SQL. In SQL no data found is not considered as an error, it happens all the time that there is no data that meets certain condition.
CALL is SQL command whereas EXEC is a shortcut for BEGIN <code> END; which is PL/SQL.

Related

SQL Developer DBMS_OUTPUT without 'PL/SQL procedure successfully completed.'

In SQL Developer, when running some PL/SQL, when the procedure is completed, the message 'PL/SQL procedure successfully completed.' is returned.
The PL/SQL that is run may return error messages to the user if the operation could not be completed for any reason through DBMS_OUTPUT.PUT_LINE, however, the user will also see 'PL/SQL procedure successfully completed.', which could be misleading (especially if the Script Output window is small enough that the DBMS_OUTPUT is not visible).
Is there any way to have the DBMS_OUTPUT return what it should whilst also having the script not return 'PL/SQL procedure successfully completed.'?
If not, are there any alternatives in SQL Developer that I may be unaware of to provide instant personalised feedback to the user?
declare
testex exception;
begin
if 1=1 then
raise testex;
end if;
exception when testex then
dbms_output.put_line('Error msg');
end;
Below code works in my end. Did you try to run your code like below?
Copied text from a website to explain the SET FEEDBACK OFF command.
Source link: https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12040.htm
SET FEED[BACK] {6 | n | ON | OFF} -
Displays the number of records returned by a script when a script selects at least n records.
ON or OFF turns this display on or off. Turning feedback ON sets n to 1. Setting feedback to zero is equivalent to turning it OFF.
SET FEEDBACK OFF also turns off the statement confirmation messages such as 'Table created' and 'PL/SQL procedure successfully completed' that are displayed after successful SQL or PL/SQL statements.
Add a RAISE statement in the error handler to re-raise the exception so that any outer handler can deal with it:
declare
testex exception;
begin
if 1=1 then
raise testex;
end if;
exception when testex then
dbms_output.put_line('Error msg');
RAISE; -- re-raise the exception to an outer handler
end;
Best of luck.
You have coded it explicitly to complete successfully in the event of a testex exception. The code says: if this happens, then print a message and end. If you want it to actually fail then it needs to raise an exception.
I would just use something like this:
begin
if 1=1 then
raise_application_error(-20000, 'Bananas are not available on a Tuesday');
end if;
end;
/
begin
*
ERROR at line 1:
ORA-20000: Bananas are not available on a Tuesday
ORA-06512: at line 3
This will cause an actual error, rather than just printing out a message that happens to talk about an error, allowing you to control deployments and build scripts etc.
It will also roll back any uncommitted transactions within the block, which your current approach does not, and it will show the actual line number.

ORA-04088: error during execution of trigger - additional errors

I have a blank table for which I've set up a trigger:
CREATE OR REPLACE TRIGGER authors_bir
BEFORE INSERT ON authors
FOR EACH ROW
begin
if upper(:new.name) = 'TEST' then
raise_application_error(-20001, 'Sorry, that value is not allowed.');
end if;
end;
After executing:
insert into AUTHORS
VALUES (1, 'test', '1-Jan-1989', 'M');
Why am I getting ORA-06512 and ORA-04088 error messages in addition to the expected ORA-20001 error prompt?
ErrorMessage
Error starting at line : 5 in command -
insert into AUTHORS
VALUES (1, 'test', '1-Jan-1989', 'M')
Error report -
ORA-20001: Sorry, that value is not allowed.
ORA-06512: at "RPS.AUTHORS_BIR", line 3
ORA-04088: error during execution of trigger 'RPS.AUTHORS_BIR'
Your trigger works perfectly and ORA-06512 is part of debugging mode and tells you what line of code raised that ORA-20001 that you coded. While ORA-04088 is saying that an error has occurred in the trigger. Both error codes are GENERIC part of oracle troubleshooting report.
According to documentation:
ORA-06512: at stringline string
Cause: Backtrace message as the stack is unwound by unhandled exceptions.
Basically, this error is part of the error stack telling at which line the actual error occurred.
And documentation:
ORA-04088: error during execution of trigger 'string.string'
Cause: A runtime error occurred during execution of a trigger.
And this error is a part of the error stack telling you that error actually occurred in a trigger.
When an unhandled error occurs, error stack is always displayed. If you want to display just the error message, you could use an exception handling part so body of the trigger would look something like this:
begin
if upper(:new.name) = 'TEST' then
raise_application_error(-20001, 'Sorry, that value is not allowed.');
end if;
exception
when others then
dbms_output.put_line(sqlcode|' '|sqlerrm);
end;

PDO stored procedures with parameters

I'm new with SQL stored procedures. All procedures are encrypted so I cannot see the code itself, but I have manual which contains information about parameters.
This stored procedure is made for inserting data to database. It contains lots of parameters e.g. #orderid and #customerid. While I don't need to use all the parameters, I tried to use following code to insert data with procedure.
$sql = $pdowin->query("EXEC salesorderimport #orderid=:orderid, #customerid=:customerid");
$sql->bindValue(':orderid', 000050);
$sql->bindValue(':customerid', 801040);
$sql->execute();
It gives me following error.
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[07002]: [Microsoft][ODBC Driver 11 for SQL Server]COUNT field incorrect or syntax error' in ...\test.php:14 Stack trace: #0 ...\test.php(14): PDO->query('EXEC salesorder...') #1 {main} thrown in ...\test.php on line 14
Thanks in advance.

Ibatis parameter initialization issue

My application is having an exception about initialization of a parametermap into an sql statement. The error is :
Caused By: com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in /com/***/cusman/cusbilman/postpaid/main/product/data/ibatis/sqlMap/THSSqlMap.xml.
--- The error occurred while applying a parameter map.
--- Check the invoicing.invoice.ths.paymentInfoMap.
--- Check the statement (query failed).
--- Cause: java.sql.SQLException: ORA-00904: : invalid identifier
at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(MappedStatement.java:201)
at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryForList(MappedStatement.java:139)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:567)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:541)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:118)
at org.springframework.orm.ibatis.SqlMapClientTemplate$3.doInSqlMapClient(SqlMapClientTemplate.java:298)
at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:209)
at org.springframework.orm.ibatis.SqlMapClientTemplate.executeWithListResult(SqlMapClientTemplate.java:249)
at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForList(SqlMapClientTemplate.java:296)
The definitions are totally persistent which each other(java side and the xml side I mean).
Any ideas?
I found it. The problem is, oracle has not a stack trace type definition for errors. I was using a function in a select, but my db user had not got the grant to execute it, so Stupid Oracle tried to run it like, the function name is a column name. So it could not find a column name like it. So it hide the real problem...

Cannot stop Oracle Queue - Could not find program unit being called: "SYS.DBMS_ASSERT"

Cannot stop and drop oracle Queue.
Following code
BEGIN
DBMS_AQADM.STOP_QUEUE (
queue_name => 'TEST_QUEUE');
DBMS_AQADM.DROP_QUEUE(
queue_name => 'TEST_QUEUE');
END;
/
produces following errors:
ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04065: not executed, altered or dropped stored procedure "SYS.DBMS_ASSERT"
ORA-06508: PL/SQL: could not find program unit being called: "SYS.DBMS_ASSERT"
ORA-06512: at "SYS.DBMS_AQADM_SYS", line 3365
ORA-06512: at "SYS.DBMS_AQADM", line 167
ORA-06512: at line 5
What can be the root cause of this problem?
UPDATE:
SQL> SELECT * FROM USER_TAB_PRIVS where table_name='DBMS_ASSERT' and GRANTEE='TEST_USER'
...
GRANTEE=TEST_USER
OWNER=SYS
TABLE_NAME=DBMS_ASSERT
GRANTOR=SYS
PRIVILEGE=EXECUTE
GRANTABLE=NO
HIERARCHY=NO
SQL> SELECT * FROM USER_TAB_PRIVS where table_name='DBMS_AQADM' and GRANTEE='TEST_USER'
...
GRANTEE=TEST_USER
OWNER=SYS
TABLE_NAME=DBMS_AQADM
GRANTOR=SYSTEM
PRIVILEGE=EXECUTE
GRANTABLE=NO
HIERARCHY=NO
I’ve checked the table USER_TAB_PRIVS in a few our schemas and I can see that record with table name 'DBMS_ASSERT' exists in schema with in TEST_USER only.
User have EXECUTE privilege.
It looks to me like either the DBMS_ASSERT package doesn't exist (unlikely but I suppose possible), or the user you used to log into the database doesn't have execute rights on it. Typically PUBLIC is granted EXECUTE access to DBMS_ASSERT but perhaps it was changed at your site. Check EXECUTE permission grants on DBMS_ASSERT and DBMS_AQADM.
If you've made this call before without any problems, then the ORA-04068 error makes me think that something in the calling chain has been invalidated. Have you applied any upgrades or patches to the installation recently?
Oracle supplies a script, utlrp in $ORACLE_HOME/rdbms/admin, that will recompile all of the packages and report on any remaining invalid. Have your administrator run that (as SYS).