Grails call stored procedure with output parameter - oracle

how to call an Oracle procedure with paramters in grails, the produre looks like this,
var returntype number; begin IZMST_PKG_SOLO_GENERATE_SQL.pro_get_row_cnt(1,181,:returntype); end;
I have tried to call this procedure but the program encounter an error, you can check the error message as below.
org.apache.commons.dbcp.DelegatingCallableStatement with address:
"oracle.jdbc.driver.OracleCallableStatementWrapper#52d0d407" is
closed.. Stacktrace follows: java.sql.SQLException:
org.apache.commons.dbcp.DelegatingCallableStatement with address:
"oracle.jdbc.driver.OracleCallableStatementWrapper#52d0d407" is
closed. at
org.apache.commons.dbcp.DelegatingStatement.checkOpen(DelegatingStatement.java:137)
at
org.apache.commons.dbcp.DelegatingCallableStatement.getObject(DelegatingCallableStatement.java:144)
at
com.pg.izoom.de.ExtractManagementController$$EO5PWcUR.addExtract(ExtractManagementController.groovy:74)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
pasted a piece of the code
Connection conn = dataSource.getConnection()
Sql sql = new Sql(conn)
//int test = sql.call("",)
sql.call'BEGIN IZMST_PKG_SOLO_GENERATE_SQL.pro_get_row_cnt(?,?,?); END;',[1L,qryId,Sql.resultSet(OracleTypes.NUMBER)],{dwells->
println dwells
}
PS: this problem has been solved, update the description to make this question easier to understand.

If I understood, your return type is number, so your can use directly Sql.NUMERIC.
sql.call '{call IZMST_PKG_SOLO_GENERATE_SQL.pro_get_row_cnt(?,?,?) }',[1L, qryId, Sql.NUMERIC],{ dwells ->
println dwells
}

Related

How to get Oracle exception in SQLcl script when using util.execute?

I try to write a batch file using Oracles SQLcl. In this file, i want to insert a new table row with util.execute. This just returns true / false, which is a boolean return of success/failure.
My question is, how i get the error message of the exception which is thrown, so that i can find out, what the problem is with my insert-statement.
What i do:
First of all, i connect to my database server and start my script:
me#pc:/myproject$ /sqlcl/bin/sql schemaname/pw#server.com:1521/sid
SQLcl: Release 17.3.0 Production [...]
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit [...]
SQL>
SQL> #mybatchscript.js path/image.jpg
My mybatchscript.js looks like this:
script
var tabName = "MY_TABLE_NAME";
var HashMap = Java.type("java.util.HashMap");
var bindmap = new HashMap();
var filePath="&1";
print("\nreading file: "+ filePath);
var blob=conn.createBlob();
var bstream=blob.setBinaryStream(1);
java.nio.file.Files.copy(java.nio.file.FileSystems.getDefault().getPath(filePath),bstream);
bstream.flush();
bindmap.put("content",blob); // has content
bindmap.put("size",blob.length()); // is 341989
// the follow command fails
var doInsert = util.execute("insert into "
+ tabName
+ " (id, main_id, file_name, file_type,"
+ " file_size, file_content, table_name)"
+ " values("
+ " SEQ_MY_TABLE_NAME.nextval, 1,"
+ " 'testname', 'image/jpeg', :size, :content,"
+ " 'my_table_name')"
,bindmap);
sqlcl.setStmt(
"show errors \n"
);
sqlcl.run();
if(!doInsert) {
print("insert failed");
print(doInsert);
exit;
}
/
The console output is like:
reading file: path/image.jpg
insert failed
false
The script is working until the util.execute insert-statement. It returns false, so the insert-statement failed. But it doesn't tell me, why. I have no idea, how i get access to the error message or the exception which is thrown inside the util.execute?
I also tried to turn on SERVEROUTPUT or ERRORLOGGING, but it has the same output as above and the error log table is empty:
SQL> set errorlogging on
SQL> show errorlogging
errorlogging is ON TABLE SPERRORLOG
SQL> set serveroutput on
SQL> show serveroutput
serveroutput ON SIZE UNLIMITED FORMAT WORD_WRAPPED
My knowledge source were these slides where my script is also based on, i didn't find information about the error / exception handling for the util functions in general?
There's basically 2 ways.
1- When using util.execute ( or any util.XYZ functions ) the last error message is retrieved with the following. I also just updated the scripting README with this : https://github.com/oracle/oracle-db-tools/blob/master/sqlcl/README.md
var msg = util.getLastException()
2- When using sqlcl.run()
There's an example I wrote here:
https://github.com/oracle/oracle-db-tools/blob/master/sqlcl/examples/audio.js
The example is a tad silly in that it makes noises on success/failure but you'll see the code that gets the error. Check the ctx.getProperty("sqldev.last.err.message" That will get the last sqlerr message.
if ( ctx.getProperty("sqldev.last.err.message") ) {
//
// FAILED !
//
play("chew_roar.wav");
} else {
//
// Success !!
//
play("R2.wav");
}

java.sql.SQLException: Missing defines

We have a very simple Java code which executes an Oracle stored procedure using CallableStatement API. An Oracle stored procedure doesn't have an OUTPUT parameter defined, however in the Java Code we are trying to register an OUT parameter and retrieve it :
cs = cnDBCon.prepareCall("{call "+strStoredProcedureName+ "}");
cs.registerOutParameter(1, Types.NUMERIC);
cs.execute();
int isOk = cs.getInt(1);
According to Java API ( https://docs.oracle.com/javase/8/docs/api/java/sql/CallableStatement.html#getInt-int- ) when a return value is SQL NULL, the result is 0.
It worked perfectly fine when we were running on Java7/WebLogic 12.1.3. Since we switched to Java8/WebLogic 12.2.1 we started to get the error :
java.sql.SQLException: Missing defines
at oracle.jdbc.driver.Accessor.isNull(Accessor.java:744)
at oracle.jdbc.driver.NumberCommonAccessor.getInt(NumberCommonAccessor.java:73)
at oracle.jdbc.driver.OracleCallableStatement.getInt(OracleCallableStatement.java:1815)
at oracle.jdbc.driver.OracleCallableStatementWrapper.getInt(OracleCallableStatementWrapper.java:780)
at weblogic.jdbc.wrapper.CallableStatement_oracle_jdbc_driver_OracleCallableStatementWrapper.getInt(Unknown Source)
The obvious choice is to update the stored procedure or java code, but I am wondering about the reason the behavior changed. Is it a more strict JDBC driver?

Error while uploading image to database

When I am trying to upload an Image using below code, I am getting following error : java.sql.SQLException: ORA-01460: unimplemented or unreasonable conversion requested
File image = new File("D:/"+fileName);
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1,"Ayush");
fis = new FileInputStream(image);
preparedStatement.setBinaryStream(2, (InputStream)fis, (int)(image.length()));
int s = preparedStatement.executeUpdate();
if(s>0) {
System.out.println("Uploaded successfully !");
flag = true;
}
else {
System.out.println("unsucessfull to upload image.");
flag = false;
}
Please help me out.
DB Script :
CREATE TABLE ESTMT_SAVE_IMAGE
(
NAME VARCHAR2(50),
IMAGE BLOB
)
Its first cause is incompatible conversion but after seeing your DB script, I assume that you are not doing any conversion in your script.
There are other reported causes of the ORA-01460 as well:
Incompatible character sets can cause an ORA-01460
Using SQL Developer, attempting to pass a string to a bind variable value in excess of 4000 bytes can result in an ORA-01460
With ODP, users moving from the 10.2 client and 10.2 ODP to the 11.1 client and 11.1.0.6.10 ODP reported an ORA-01460 error. This was a bug that should be fixed by patching ODP to the most recent version.
Please see this

Delphi TDBXTransaction 'Invalid transaction Object'

1st off I am new to Delphi so this may be a "mundane detail" that's being over looked. [sorry in advance]
I am getting an 'Invalid Transaction Object' error when I attempt to run a transaction through a datasnap server connected to an Oracle 11g DB.
Due to the system details and the companies business plan we have elected not to use ClientDataSets to handle our transactions. Instead we are attempting to make the Snap server very generic and only handle data access by receiving queries and returning native types.
With that being said here is some sample code that is giving me fits:
function TSnapMethods.TransUpdate: boolean;
var
dbx: TDBXTransaction;
params:TParams;
begin
SqlCon.Open;
dbx := SQLCon.DBXConnection.BeginTransaction(TDBXIsolations.ReadCommitted);
try
params:= TParams.Create(self);
with Params.AddParameter do
begin
name:= 'param';
DataType:= ftWideString;
ParamType:= ptInput;
asString:= 'Bugsville';
end;
with Params.AddParameter do
begin
name:= 'var';
DataType:= ftWideString;
ParamType:= ptInput;
asString:= 'ZZZTOP';
end;
sqlcon.Execute('Update Name set City=:param Where Abrv=:var',params);
SQLcon.CommitFreeAndNil(dbx);//Breaks here...
result:= true;
except
Sqlcon.RollbackFreeAndNil(dbx);//Breaks here also...
result:= false;
end;
end;
By calling SQLCon.DBXConnection.BeginTransaction(), you're bypassing the setting up of internal TTransactionItem which is checked when the transaction is committed when you call SQLcon.CommitFreeAndNil() on the SQLConnection object. Notice that you're starting the transaction on the DBXConnection object but not committing it likewise.
Replace
SQLCon.DBXConnection.BeginTransaction()
with
SQLCon.BeginTransaction()
From another source I got this helpful information:
http://codeverge.com/embarcadero.delphi.ide/record-not-found-or-changed-by-another/1061559
For start transaction:
transaction:=Datamodule.SqlConection.BeginTransaction(TDBXIsolations.ReadCommitted);
For commit:
DataModule1.SqlConection.CommitFreeAndNil(Transacao);
To rollback:
DataModule1.SqlConection.RollbackIncompleteFreeAndNil(Transacao)
And use
RollbackIncompleteFreeAndNil
instead
RollbackIncompleteFreeAndNil
like referenced by:
http://docwiki.embarcadero.com/Libraries/Tokyo/en/Data.SqlExpr.TSQLConnection.RollbackIncompleteFreeAndNil
Please try this and report the results.

Incorrect Input/Doc URL Error

I have the following code which connects to a oracle database via soap, creates an XML Blob and returns it to the screen.
I am receiving the following error, and cannot figure out why.
array(3) {
["faultcode"]=>
string(11) "soap:Client"
["faultstring"]=>
string(22) "Error processing input"
["detail"]=>
array(1) {
["OracleErrors"]=>
string(39) "
Incorrect Input Doc/URL
"
}
}
I am using the following function to call a stored procedure.
function getUsersData(){
$xmlfunc = 'GETUSERS';
$pkg = 'JSON_EXPORTS';
$inparam = array("SESSIONHASH-VARCHAR2-IN" => $_SESSION['sessionhash']);
$outparam = array("USERSDATA-XMLTYPE-OUT");
$oradb = oradb::getconnection();
$oradb->newxml($xmlfunc,$pkg,$inparam,$outparam);
$result = $oradb->getxml(false,false,false,true);
print_r($result);
}
This is the stored procedure I am calling:
CREATE OR REPLACE PACKAGE BODY vivouser.json_exports IS
-- #Oracle bexV2
PROCEDURE getusers(sessionhash IN VARCHAR2,
usersdata OUT XMLTYPE)
IS
p_companyid number;
p_storegroupid number;
p_userid number;
BEGIN
bexcore.checksessionid(sessionhash, p_companyid, p_storegroupid, p_userid);
usersdata := bexcore.CreateXMLData(
'select userid,
tbu.companyid,
tbu.firstname,
tbu.middlename,
tbu.lastname,
tbu.gender,
tbu.payrollnumber,
tbu.ismanager,
tpt.description,
tpt.wagerate
from tbuser tbu
left join tbposition tbp using (USERID)
left join tbpositiontype tpt using (POSITIONTYPEID);'
);
END getusers;
END json_exports;
Also, please note: $_SESSION['sessionhash'] is proven to be a logical hash value. All other soap calls using this format function as expected. Bexcore.checksessionid is also proven to be valid, and not the cause of this error, as is bexcore.createXmlData (they are each used in thousands of other cases in the same way and run as expected.)
The problem I was having, was that the user accessing the database did not have permissions set to allow calling the requested packages.
use
grant all on <packagename> to <user>;
to solve this problem.

Resources