We have a Oracle procedure call done using iBatis. One of the IN parameters to the procedure is a VARCHAR2 datatype in procedure and is java.lang.String in Service/DAO layers.
The procedure fails whenever this input parameter is passed with NULL value. When a value is passed, then the procedure gets called without any errors.
For this procedure parameter (which is nullable) within the parametermap, we set the attribute as jdbctype="java.sql.Types.NULL" and it started working.
Is this the correct solution ?
The database connection is established using connection pool (dbcp) created in Tomcat6 server.
Ibatis for sure have problems with NULL values passed as parameters.
In our insert query we use such wrapper:
insert into table (column1) values (<isNull property="column1">NULL </isNull><isNotNull property="column1">#column1:INT# </isNotNull>)
for those still using the old version of ibatis (2.3 in my case), the above error while passing nullable parameters might be caused by not specifying jdbcType in parameterMap. there is a passage in iBatis 2.3.0 User Guide (p.27, Parameter Maps and Inline Parameters - jdbcType) pointing that out.
Related
I've seem to have run across a limitation with JPA / Hibernate and available SQL Server drivers. (The two drivers I know of are jTDS and Microsoft's driver).
My requirement is call a stored procedure that:
has an out parameter of type varbinary(max) that is set with ~10k bytes AND
has two in parameters with default null value. Only one of the two parameters can have null value when called. I need the second one to have a non-null value.
Here's the procedure signature:
procedure [dbo].[pTest]
#outParam varbinary(max) out
,#optParam1 varchar(max) = null
,#optParam2 varchar(max) = null
-- optParam1 or optParam2 can be null. But both cannot be null.
Ideally, I would like to use Spring Data JPA with jTDS to do this. But jTDS fails 1 b/c it truncates at 8k bytes. It passes 2 b/c I don't have to specify params with default values.
Using Microsoft's driver, 1 passes (AFAIK). 2 fails b/c I have to specify params up to the non-null value. If I don't, then I get index out of range. But if I specify the optParam1, I have to give it a non-null value per Hibernate. If I give it a non-null value, the stored procedure complains b/c it has a rule that optParam1 and optParam2 cannot both have a non-null value.
Is it possible to meet my requirements using Spring Data JPA / JPA? I have to work within these requirements. So if not supported using JPA, are there any alternatives to doing this in Java?
I have a problem with calling a stored procedure from ABAP.
I use standard ABAP class cl_sql_statement and it's methods execute_procedure and set_param. Called procedure, for example, has a single Boolean input parameter.
CREATE OR REPLACE PROCEDURE print_boolean (
p_in_flag BOOLEAN
) IS
ABAP snippet
DATA: ld_e_bool type char5,
ld_o_stat type ref to cl_sql_statement,
ld_r_data type ref to data.
***************************
ld_e_bool = 'FALSE'.
get references of ld_e_bool into ld_r_data.
ld_o_stat->set_param(DATA_REF = ld_r_data).
ld_o_stat->execute_procedure( 'print_boolean' ).
********************************************
After the call I catch an exception which says something like: 'wrong number or types of arguments'. Maybe I need another type than char5... Any help would be appreciated.
Some observation:
The JDBC drivers do not support the passing of BOOLEAN parameters to PL/SQL stored procedures( suggest wrapping the PL/SQL procedure with a second PL/SQL procedure). But i dont want to use the above option becuase there are already lot of packages/SP's are available.
The Oracle documentation is unclear on how PL/SQL boolean values are actually represented. There is also a question that discusses the use of boolean types in Oracle database fields (not really relevant here, but provides some background).
From the PL/SQL documentation:
The BOOLEAN datatype takes no parameters. Only the values TRUE, FALSE, and NULL can be assigned to a BOOLEAN variable.
You cannot insert the values TRUE and FALSE into a database column. You cannot select or fetch column values into a BOOLEAN variable. Functions called from a SQL query cannot take any BOOLEAN parameters. Neither can built-in SQL functions such as TO_CHAR; to represent BOOLEAN values in output, you must use IF-THEN or CASE constructs to translate BOOLEAN values into some other type, such as 0 or 1, 'Y' or 'N', 'true' or 'false', and so on.
In light of that, and I know you don't want to, you may need to change the type of parameter you pass into the stored procedure (e.g., use a single character or integer) and then use logic to treat that as a boolean.
In SAP doc say:
Almost all SQL statements that are valid for the addressed database system can be included between EXEC and ENDEXEC
Maybe if i try put in this section native pl/sql code i get result...
Edit: I put this code snip and it's ok.
EXEC SQL.
BEGIN
print_boolean(TRUE);
END;
ENDEXEC.
But there is one problem. This sql statement have static form only.
I am using IBM message broker, v8.0.0.2. I am trying to call a stored procedure with 45 parameters, in and out. I use the Oracle jdbc driver (oracle.jdbc.OracleDriver). Turns out that I get an 'Invalid column index' SqlException, whenever I try to set the 45th IN or OUT parameter, which is weird. Is there such a limit?
Give Us the Code you've created and the Exception from the Exception list, by the way ,test the stored procedure using SQL Developer or any editor you are using then.. create procedure using ESQL and Call Database Stored Procedure.
CREATE PROCEDURE YourProcedureName(IN PARAM1 TYPE, IN PARAM2 TYPE,...,
OUT PARAM44 TYPE, INOUT PARAM45 TYPE)
LANGUAGE DATABASE DYNAMIC RESULT SETS 1 EXTERNAL NAME "ProcedureNameInDB";
In Main Function
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
--CopyMessageHeaders();
--CopyEntireMessage();
-- DECLARE HERE PARAMETERS FOR THE PROCEUDRE
-- In This Block Declare the 45 parameters for passing them in ESQL Procedure.
-- Then ESQL will pass them to Oracle Stored Procedure.
-- END DECLARE PARAMETERS FOR THE PROCEUDRE
-- Environment.DBRowSetResult: Storing Stored Procedure Output in Environment variable.
CALL YourProcedureName(param1, param2, .... param44,param45, Environment.DBRowSetResult);
END;
I have a PL/SQL function in an Oracle database that I can't change. This function takes a parameter which identifies an entity, creates a copy of that entity and then returns the ID of the copy. This looks something like
FUNCTION copy_entity(id IN NUMBER) RETURN NUMBER
I need to call this function from Hibernate. I tried creating a named SQL query with something similar to
CALL copy_entity(:id)
as the query, but from this I can't seem to get the return value of the function. Hibernate's "return-scalar" and similar options require a column name to return and I don't have a column name. This lead me to
SELECT copy_entity(:id) AS newEntityId
with "return-scalar" using newEntityId as column name, but this also did not work since Oracle then throws an exception that I can't call INSERT (to save the copy) in a SELECT.
Is there any way to get the return value of such a PL/SQL function? The function is actually much more complex and still required in other parts of the app, so re-writing it is not really an option.
I hope/think you can use an anonymous PL/SQL block:
begin
:myresult = copy_entity(:id);
end;
Now you have 'column name' myresult with the result.
I've never used hibernate so I hope it works. I don't know how flexible Hibernate is.
I think you are stuck using straight JDBC. The Hibernate documentation has this in the limitations section for Oracle:
For Oracle the following rules apply:
A function must return a result set.
The first parameter of a procedure
must be an OUT that returns a result
set. This is done by using a
SYS_REFCURSOR type in Oracle 9 or 10.
In Oracle you need to define a REF
CURSOR type. See Oracle literature for
further information.
Since this function accepts a number and returns a number you are out of luck with Hibernate and would probably be better off making a simple JDBC CallableStatement.
I have writtent some Oracle storedprocedures in these there are more then 20 input parameters and from them morethen 10 parameters are required , I want all with some value and do not want to accept null values for that , Is there anything that I can declare in the Procedure defination itself which can restrict null input parameter or Will I have to check for each value and Raise the exception if the required value is null ?
I know this is an old question, but there is another option (described here):
SUBTYPE varchar2_not_null IS VARCHAR2 NOT NULL;
You can define this type (and number_not_null, etc) either in the same package as your stored procedures, or in their own package if you want to use them in lots of places. You can then declare parameters of being these types.
If NULL gets passed as an argument, you'll get a very useful error message:
cannot pass NULL to a NOT NULL constrained formal parameter
In PL/SQL I don't know of a way around checking each one.
If you are calling the stored procedure from an external library, that library might have that functionality. This is probably not likely because frequently NULL input parameters are required.
You could make a helper PL/SQL procedure that, given a value, will raise an exception if it is null to save on redundant code. You could then write a chunk of perl/python/groovy that would slurp up your procedure declaration and crank out these calls to your null check procedure.