not able to insert values in my postgresql database - java

In java code:
CallableStatement cs=null;
int bcode=1;
int dcode=3;
int noftab=3;
String sql2 = "{? = call public.insertdepttables('"+bcode+"','"+dcode+"','"+noftab+"')}";
cs = conn.prepareCall(sql2);
cs.registerOutParameter(1,Types.INTEGER);
rset1=cs.getInt(1);
system.out.println("success="+rest1);
In insertdepttables:(Function in my db-postgresql)
CREATE OR REPLACE FUNCTION public.insertdepttables
(
IN branch_code integer,
IN dept_code integer,
IN no_tables integer
)
RETURNS integer AS
$$
DECLARE
count integer;
begin
IF no_tables>0 THEN
LOOP
insert into t_dept_tables(branch_code,dept_code,table_no)values(branch_code,dept_code,no_tables);
no_tables=no_tables-1;
Count=count+1;
EXIT when no_tables =0;
END LOOP ;
END IF;
RETURN count;
end
$$
actually i need to insert the no_table (i.e.,3) times row in my t_dept_tables in postgresql. So wat i have done is i hav written functions in database. I need to call it from java code. So I used callable stmt there:
My output should be like this in db:
bcode dcode table_no
1 3 1
1 3 2
1 3 3
Now while executing java code,
I'm getting the result as,
console:
success=3
but 3 rows arent inserted in db, but while executing the function in my db, the values get inserted. So no wrong in my db function. please help me to sort this out.

Are you sure you haven't forgot to actually call statement, like:
cs.executeQuery();
...
cs.close();
BTW, your task could be achieved without functions, like (don't use string concatenation, use parameter values):
String stm = "insert into t_dept_tables(branch_code,dept_code,table_no) values(branch_code,dept_code,no_tables); VALUES(?, ?, ?)";
cs = con.prepareStatement(stm);
cs.setInt(1, id);
cs.setInt(3, id);
cs.setInt(3, id);
rs = cs.executeUpdate();

Related

How to get result set from store procedure with parameter in jbdc

i have store procedure with 1 parameter only. I can execute the procedure like this exec proc_name param1 in microsoft SQL server management studio and show result set that i want. But when i try in java with my code like this:
String url = "jdbc:sqlserver://TOSHIBA\\SQLEXPRESS;databaseName=Perpustakaan;integratedSecurity=true";
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection(url);
CallableStatement statement = conn.prepareCall("{call search(?)}");
statement.setString(1,parameter);
ArrayList<Buku> result = new ArrayList<>();
statement.execute();
ResultSet rs = statement.executeQuery();
while (rs.next()) {
int tempId = rs.getInt("id");
String tempJudul = rs.getString("judul");
result.add(new Buku(tempId, tempJudul));
}
return result;
i get an error say 'The statement did not return a result set.' The 'parameter' in statement.setString(1,parameter) is String typed.
this is my store procedure code in case something is wrong
alter proc search
#kata varchar(255)
as
declare #tempResult table
(
kata varchar(255)
)
declare
#idx int,
#katas varchar(255)
set #katas = #kata
set #idx = CHARINDEX(',',#katas,1)
while(#idx != 0)
begin
insert into #tempResult
select
SUBSTRING(#katas,1,#idx-1)
set #katas = SUBSTRING(#katas,#idx+1,100000000)
set #idx = CHARINDEX(',',#katas,1)
end
insert into #tempResult
select
#katas
declare #searchResult table
(
judul varchar(255)
)
insert into #searchResult
select dbo.buku.judul
from dbo.buku cross join #tempResult
where CHARINDEX(kata, dbo.buku.judul) > 0
select
dbo.buku.id, sr.judul
from
#searchResult as sr join dbo.buku
on
sr.judul = dbo.buku.judul
group by
sr.judul, dbo.buku.id
order by
COUNT(sr.judul) desc
exec search 'Games'
In order to call stored procedures with callable statement you need to registerOutParameter for the expected results. Also you don't need to executeQuery after the execute becaues you don't have a query and you have already executed your statement
Try to change your code to:
boolean hasResults=statement.execute();
while (hasResults) {
ResultSet rs = cStmt.getResultSet();
int tempId = rs.getInt("id");
String tempJudul = rs.getString("judul");
result.add(new Buku(tempId, tempJudul));
hasResults= cStmt.getMoreResults();
}
But before that you should add the parameters you expect to the statement. Just the way you do :
statement.setString(1,parameter);
// Add out parameters here
statement.registerOutParameter(1, java.sql.Types.INTEGER);
....
I cannot be bothered to look at the procedure call right now ;) but I guess it works if you can execute it in management studio
so what i do to make the statement return result set is i add SET NOCOUNT ON in the beginning of my store procedure.
set nocount explanation is here.

java get stored procedure response

how do i get the Store procedure response in java ?
when i run this in SQL i get a response
DECLARE
result NUMBER;
begin
result := apps.xx01_cpc_ap_pkg.xx01_create_invoice_f(8309, 4795, 146.00);
dbms_output.put_line(result);
end;
this is my java code
i tried many option - but i keep failing on how to fetch the response
in this part resultSet.getInt(4))
CallableStatement stmt = null;
String spCallRequest = "{? = call apps.xx01_cpc_ap_pkg.xx01_create_invoice_f(?, ?, ? )}";
stmt = oraAppUtils.connection.prepareCall(spCallRequest);
stmt.setString(1,paymentRequest.healthFacilityCode);
stmt.setString(2,paymentRequest.batchId);
stmt.setDouble(3,Double.parseDouble(paymentRequest.tariffAmount));
stmt.registerOutParameter(4, java.sql.Types.INTEGER);
resultSet = stmt.executeQuery();
System.out.println ("invoice id ="+resultSet.getInt(4));
ok - just for documentation in case some else needs it... this is the SP it has a function
CREATE OR REPLACE PACKAGE APPS.XX01_CPC_AP_PKG
AS
PROCEDURE XX01_CREATE_INVOICE (P_HF_CODE IN VARCHAR2,
P_BATCH_ID IN VARCHAR2,
P_AMOUNT IN NUMBER,
x_invoice_id OUT NUMBER/*,
x_error_code OUT VARCHAR2,
x_error_msg OUT VARCHAR2,
x_err_comments OUT VARCHAR2,
x_code OUT NUMBER,
x_source OUT VARCHAR2*/);
FUNCTION XX01_CREATE_INVOICE_F (P_HF_CODE IN VARCHAR2,
P_BATCH_ID IN VARCHAR2,
P_AMOUNT IN NUMBER) RETURN NUMBER;
so originaly i called the function - it didn't work - i change the code to the following code and it works
String spCallRequest = "BEGIN apps.xx01_cpc_ap_pkg.xx01_create_invoice(?, ?, ?,? ); END ; ";
stmt = oraAppUtils.connection.prepareCall(spCallRequest);
stmt.setString(1,paymentRequest.healthFacilityCode);
stmt.setString(2,paymentRequest.batchId);
stmt.setDouble(3,Double.parseDouble(paymentRequest.tariffAmount));
stmt.registerOutParameter(4, java.sql.Types.INTEGER);
stmt.execute();
System.out.println ("invoice id ="+stmt.getInt(4));
TL;DR
You did not call ResultSet#next()
Reason
From linked docs:
A ResultSet cursor is initially positioned before the first row; the
first call to the method next makes the first row the current row; the
second call makes the second row the current row, and so on.
Fix
Your code should look like this:
stmt.registerOutParameter(4, java.sql.Types.INTEGER);
resultSet = stmt.executeQuery();
if(resultSet.next()) {
System.out.println ("invoice id ="+resultSet.getInt(4));
} else {
//this should not happen
}
Your question didn't explicitly mention JDBC as the API that you must use, so perhaps, you're open to third party utilities that work on top of JDBC? For example, jOOQ's code generator can be used to generate stubs for all of your stored procedures. In your case, you could simply call the stub like this:
int result = Xx01CpcApPkg.xx01CreateInvoiceF(
configuration, // This object contains your JDBC Connection
paymentRequest.healthFacilityCode,
paymentRequest.batchId,
Double.parseDouble(paymentRequest.tariffAmount)
);
These objects are generated by jOOQ:
Xx01CpcApPkg: A class representing your PL/SQL package
xx01CreateInvoiceF(): A method representing your stored function
Behind the scenes, this does exactly what the accepted answer does, but:
You don't have to work with strings
You don't have to remember data types and parameter order
When you change the procedure in your database, and regenerate the code, then your client code stops compiling, so you'll notice the problem early on
Disclaimer: I work for the company behind jOOQ.

ResultSet is not null still resultset.next() returning false

I'm trying to access a procedure which returns a cursor, my resultset is not null still resultset.next() is returning false and that's why control is not entering into while, please see below mention my procedure and my java code and help me on this.
this is my procedure:
PROCEDURE get_app_biz_summary (p_application_name_i IN VARCHAR2,
p_summary_o OUT SYS_REFCURSOR) IS BEGIN IF p_application_name_i = 'ALL' THEN
OPEN p_summary_o FOR
SELECT application_name,
creation_date,
SUM (success_count) success,
SUM (error_count) "error",
SUM (warning_count) warning
FROM xxcss_sfm_app_biz_summary
WHERE 1 = 1 AND creation_date >= SYSDATE - 4
GROUP BY application_name, creation_date; ELSE
OPEN p_summary_o FOR
SELECT application_name,
biz_process_name,
creation_date,
SUM (success_count) success,
SUM (error_count) "error",
SUM (warning_count) warning
FROM xxcss_sfm_app_biz_summary
WHERE application_name =
NVL (p_application_name_i, application_name)
AND creation_date >= SYSDATE - 4
GROUP BY application_name, biz_process_name, creation_date; END IF; END get_app_biz_summary;
END XXCSS_ORDER_STATUS_PKG;
/
and this is my java code:
try {
OracleCallableStatement cs = (OracleCallableStatement)jdbcTemplate
// CallableStatement cs=jdbcTemplate
.getDataSource()
.getConnection()
.prepareCall(
"{call APPS.XXCSS_ORDER_STATUS_PKG.GET_APP_BIZ_SUMMARY(?,?)}");
cs.setString(1, appName);
cs.registerOutParameter(2, OracleTypes.CURSOR);
cs.execute();
resultSet= (OracleResultSet)cs.getCursor(2);
if(resultSet==null )
System.out.println("resultset null...."); // resultset is not null
System.out.println(resultSet.next()); // its returning false
while(resultSet.next()){
System.out.println("in while");
IBSave ibSave=new IBSave();
ibSave.setApplicationName(resultSet.getString("APPLICATION_NAME"));
Dont call resultSet.next() unnecessarily because as per documentation :-
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/sql/ResultSet.java#ResultSet.next%28%29.
If you call
System.out.println(resultSet.next()); // its returning false
it will move cursor to next row.
and again calling
while(resultSet.next()){
is actually pointed to your second row. So you have only one record returned in resultset.
1.Can you make sure your database is returning data
2.Can you check with resultSet= (OracleResultSet)cs.getCursor(2);
Maybe remove this particular line??
Hope this helps!!

java code make a stored procedure return a resultset in DAO layer

I have a Stored Procedure that runs on MS SQL Server. It takes one parameter as input. Basically, it returns multiple rows.
I am calling the SP from my java application by using CallableStatement.
I would like to know if it possible to get the rows returned by the stored procedure in the form of ResultSet in my DAO layer?[like how we get a resultset when we do select * from EmployeeTable] . If yes, how do we do that?
P.S: I don’t have privilege to modify the stored procedure.
SQL Server knows two types of procedures returning results:
Batches
The procedure looks something like this:
CREATE PROCEDURE p_results(
#p_result_sets INT
)
AS
BEGIN
IF #p_result_sets = 1 BEGIN
SELECT 1 a;
END
ELSE IF #p_result_sets = 2 BEGIN
SELECT 1 a;
SELECT 1 b UNION SELECT 2 b;
END
END;
In this case, you don't know in advance what the result sets will look like, and how many of them you'll get. You will have to run the procedure using Statement.execute() as follows:
try (CallableStatement stmt = con.prepareCall("...")) {
boolean results = stmt.execute();
for (;;) {
if (results)
try (ResultSet rs = stmt.getResultSet()) {
// ... Fetch your results here
}
else if (stmt.getUpdateCount() != -1) {}
else
break;
results = stmt.getMoreResults();
}
// After all results are fetched, you can also retrieve OUT parameters, if applicable
}
Table-valued functions
The function looks something like this:
CREATE FUNCTION f_tables1 ()
RETURNS #out_table TABLE (
column_value INTEGER
)
AS
BEGIN
INSERT #out_table
VALUES (1)
RETURN
END
In this case, you don't really need a CallableStatement. An ordinary SELECT statement will do:
try (PreparedStatement stmt = con.prepareStatement("SELECT * FROM f_tables1()");
ResultSet rs = stmt.executeQuery()) {
// ... Fetch your results here
}

Call pl/sql function in java?

So I've got a function that checks how many cancellations are in my booking table:
CREATE OR REPLACE FUNCTION total_cancellations
RETURN number IS
t_canc number := 0;
BEGIN
SELECT count(*) into t_canc
FROM booking where status = 'CANCELLED';
RETURN t_canc;
END;
/
To execute his in sql I use:
set serveroutput on
DECLARE
c number;
BEGIN
c := total_cancellations();
dbms_output.put_line('Total no. of Cancellations: ' || c);
END;
/
My result is:
anonymous block completed
Total no. of Cancellations: 1
My question is can someone help me call the function in JAVA, I have tried but with no luck.
Java provides CallableStatements for such purposes .
CallableStatement cstmt = conn.prepareCall("{? = CALL total_cancellations()}");
cstmt.registerOutParameter(1, Types.INTEGER);
cstmt.setInt(2, acctNo);
cstmt.executeUpdate();
int cancel= cstmt.getInt(1);
System.out.print("Cancellation is "+cancel);
will print the same as you do in the pl/sql. As per docs Connection#prepareCall(),
Creates a CallableStatement object for calling database stored procedures. The CallableStatement object provides methods for setting up its IN and OUT parameters, and methods for executing the call to a stored procedure.
You can also pass parameters for the function . for ex ,
conn.prepareCall("{? = CALL total_cancellations(?)}");
cstmt.setInt(2, value);
will pass the values to the function as input parameter.
Hope this helps !
Prepare a Callable Statement
There are two formats available, the
familiar block syntax used by Oracle and the ANSI 92 standard syntax.
In the case of our sample program, the block syntax has the form:
CallableStatement vStatement =
vDatabaseConnection.prepareCall( "begin ? := javatest( ?, ? ); end;" );
The ANSI 92 syntax has the form:
CallableStatement vStatement =
vDatabaseConnection.prepareCall( "{ ? = call javatest( ?, ? )}");
source
If you receive the below error, you might want to use the first format.
total_cancellations is not a procedure or is undefined error.
Sample code.
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:#xx.xxx.xx.xxx:1521:xxx", "user","pass");
CallableStatement cstmt = conn.prepareCall("begin ? := TEST_FUNC(?,?); end;");
cstmt.registerOutParameter(1, Types.INTEGER);
cstmt.setString(2, "Test");
cstmt.setInt(3, 1001);
cstmt.execute();
int result = cstmt.getInt(1);
System.out.print("Result: " + result);
cstmt.close();
conn.close();

Categories

Resources