Calling Oracle Stored Procedure from Java Web application - java

I am trying to call several oracle stored procedures from my web application. There are no in or out parameters in any of the procedures. Everything works perfectly when I run my web app locally, but when I deploy the app to our test server the stored procedure calls stop working. I get no error messages and the procedure does not run.
I would think it has something to do with the JDBC driver or connection, but I'm at a loss? Any help would be greatly appreciated!
Here is the code that works perfectly when running locally and debugging:
public boolean deleteFromTempTables(String id)
{
String msg = "";
CallableStatement stmt1 = null;
try
{
conn = DBConnection.getConnection();
DbmsOutput dbmsOutput = new DbmsOutput( conn );
dbmsOutput.enable( 1000000 );
stmt1 = conn.prepareCall("{call delete_from_temp_employee()}");
stmt1.execute();
stmt1.close();
dbmsOutput.show(id);
dbmsOutput.close();
}
catch(Exception e)
{
e.printStackTrace();
return true;
}
finally
{
try
{
stmt1.close();
conn.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
return false;
}
Here is the stored procedure:
create or replace procedure delete_from_temp_employee as
temp_empe_before NUMBER;
temp_empe_after NUMBER;
begin
select count(*) into temp_empe_before from temp_employee;
delete from temp_employee;
select count(*) into temp_empe_after from temp_employee;
DBMS_OUTPUT.PUT_LINE ('Procedure DELETE_FROM_TEMP_EMPLOYEE Employee Before: ' || temp_empe_before);
DBMS_OUTPUT.PUT_LINE ('Procedure DELETE_FROM_TEMP_EMPLOYEE Employee After: ' || temp_empe_after);
end delete_from_temp_employee;
Call in JSP page:
<%
boolean isDeleteError = false;
isDeleteError = memberupload.deleteFromTempTables(userid);
%>

you need to execute:
set serveroutput ON;
this command makes output works.
also after delete statement add commit; command to commit changes if you forget it.
by the way, you can get the affected rows for DML statements like delete statement by using sql%rowcownt as following:
set serveroutput ON;
create or replace procedure delete_from_temp_employee2 as
rows NUMBER;
begin
delete from temp_employee;
rows := SQL%rowcount;
DBMS_OUTPUT.PUT_LINE ('Deleted: ' || rows || ' row(s)');
end delete_from_temp_employee2;

Related

How to check Oracle procedure is created correctly by using java?

Am making a simple tool (using) that executes Oracle script from a text file. it's working fine, but while executing create procedure or trigger if an error occurs by oracle, java not throwing any exception, and in the same scenario, any table creation or execution of select/insert/ delete it throwing the exception with error .so my question is how to catch the error while executing procedure/trigger creating script? thank you.
Example: this function (it may be a procedure, trigger )I need to create Oracle.
create or replace function fn_get_contract_invoice_amt(I_CompanyId varchar2,
I_ContractNo Varchar2, I_Date1 Date, I_Date2 Date)
return number is
V_Amount Number(13,3);
begin
begin
Select sum(nvl(Amount,0)) into v_Amount
From Invmast im
Where Company_id = I_CompanyId
and Contract_No = I_ContractNo
and Tran_Date between I_Date1 and I_Date2
and Deleted = 'N'
and Posted = 'Y';
Exception
When No_Data_Found Then
V_Amount := 0;
End;
Return nvl(V_Amount,0);
end;
Java Code to execute script
private static String runSqlStatement(String script) {
String status = "";
System.out.println(script);
Statement stmt = null;
try {
stmt = conn.createStatement();
stmt.execute(script);
} catch (SQLException ex) {
status = ex.getMessage();
System.err.println("SQLException: " + ex.getMessage());
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
System.err.println("SQLException: " + e.getMessage());
}
}
}
return status;
}
I don't think Oracle treats compilation errors when creating procedures as actual errors per say.
If you test this with sqlplus and put a WHENEVER SQLERROR EXIT FAILURE ROLLBACK then run a failed CREATE OR REPLACE you will see that only errors reported via the standard ORA-nnnnn type message is caught. The create with compliation errors result is not caught as a error.
The reason is because even it it is created with compilation errors it is still created.
The only way for you in your use case to check if the CREATE OR REPLACE succeeded is, perhaps as follows:
Execute the CREATE or REPLACE statement
Check DBA_OBJECTS (or ALL_OBJECTS or USER_OBJECTS as appropriate) :
SELECT STATUS
FROM DBA_OBJECTS
WHERE OBJECT_NAME = 'OBject_name'
AND OBJECT_TYPE = 'PACKAGE|PACKAGE BODY|PROCEDURE...'
AND OWNER = 'the_owner'
If this returns VALID then it worked and compiled cleanly, if INVALID then query DBA_ERRORS :
SELECT *
FROM DBA_ERRORS
WHERE NAME = 'Object_name'
AND TYPE = '....'
AND OWNER = 'the_owner'

Proper use of Stored Procedure using Select

I created a Stored Procedure where I can select the column that I address in my Stored Procedure via Callable Statement. I tried to use SELECT SECTION NAME FROM allsections_list WHERE SECTION_NAME = ? Similar to syntax of Prepared Statement but I think its not compatible using this syntax. I'm just new learning this mysql.
Stored Procedure
CREATE STORED PROCEDURE getSECTION_NAME(OUT SECTION_NAME VARCHAR)
SELECT SECTION_NAME FROM allsections_list
Code
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
String searchSection = Section_SearchSection_Textfield.getText();
String searchSection_Name = Section_SectionName_TextField.getText();
if (searchSection.isEmpty())
{
JOptionPane.showMessageDialog(null, "Please fill up this fields");
}
else
try (Connection myConn = DBUtil.connect();
CallableStatement myCs = myConn.prepareCall("{call getSECTION_NAME(?)}"))
{
myCs.setString(1, searchSection_Name);
try (ResultSet myRs = myCs.executeQuery())
{
int resultsCounter = 0;
while (myRs.next())
{
String getSection_Name = myRs.getString(1);
Section_SectionName_TextField.setText(getSection_Name);
resultsCounter++;
}
}
}
catch (SQLException e)
{
DBUtil.processException(e);
}
When I search a records. If the records exist it the value will print out to the textfields. But it doesn't print out. And it throws me a error getSECTION_NAME does not exist. What if I want select multiple values? Because I'm having a project where I'm making a Enrollment System. I choose this Stored Procedure specially than Batch Statement based on what I read. Any help will appreciate. Thanks!
I don't use MySql, but here's a similar example in Oracle (I think this Works in MySql as well).
CREATE PROCEDURE get_section_name(OUT secName VARCHAR(100))
BEGIN
SELECT SECTION_NAME INTO secName FROM allsections_list WHERE some_condition = 100; //your procedure does not use any input arguments if you want to return just one record then you'll probably need to specify a where clause
END
/ //when executing a stored procedure in a DB client you will need to specify a terminator character (in this case slash /)
Note that there's no return statement because we're using OUT parameters.
The getOutValueForStoredProcedure method calls the stored procedure and retrieves the out value.
public String getOutValueForStoredProcedure(String procedureName, int sqlType) throws EasyORMException{
String out=null;
CallableStatement stmt=null;
try{
//out parameters must me marked with question marks just as input parameters
sqlQuery = "{call " + procedureName +"(?)}";
stmt=conn.prepareCall(sqlQuery);//I assume that a Connection has been created
stmt.registerOutParameter(1, sqlType);
stmt.execute();
out = stmt.getString(1);//you get the out variable through the Statement, not the ResultSet
}catch(Exception e){
//log exception
}finally{
//close stmt
}
return out;
}
To call this stored procedure, you can use
String out = getOutValueForStoredProcedure("get_section_name", java.sql.Types.VARCHAR);
For creating stored procedures in MySql , check this link http://code.tutsplus.com/articles/an-introduction-to-stored-procedures-in-mysql-5--net-17843
For a more elaborate example, check this http://www.mkyong.com/jdbc/jdbc-callablestatement-stored-procedure-out-parameter-example/

Unable to figure out JDBC ClassNotFoundException (JTDS driver)

So a little background on my problem: I am trying to copy over a table on an Microsoft SQL system from an Oracle database. Besides giving password and user access to the table I cannot edit or do anything to the MSSQL database.
I successfully used the Oracle SQL Developer to connect and view the tables I want (using a third party JDBC driver), but I want to set up an automated copy-over into my Oracle database so I am attempting to use the same driver in some stored java code.
I have a java function that all it should do is go and count the number of entries in the table. So far my code looks like:
public static String getCount() {
Statement stmt = null;
Connection conn = null;
int rowCount = 0;
String message = "";
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
}
catch(ClassNotFoundException e) {
System.err.println("Error loading driver: " + e);
message = message + e + " -ER1 \n";
}
try {
conn = DriverManager.getConnection("jdbc:jtds:sqlserver://site.school.edu:2000/ACCESS", "user", "password");
stmt = conn.createStatement();
String strSelect = "select 1 as field;";
ResultSet rset = stmt.executeQuery(strSelect);
while (rset.next()) {
++rowCount;
}
}
catch(SQLException ex) {
ex.printStackTrace();
message = message + ex.getSQLState() + " -ER2";
}
finally {
try {
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch(SQLException ex) {
ex.printStackTrace();
message = message + ex.getSQLState() + "-ER3";
}
}
return message;
}
Which is being calling from a stored function :
CREATE OR REPLACE function Schema.java_testMessage return varchar2
as language java
name 'ConnectAndQuery.getCount() return java.lang.String';
Which I am calling from a script in TOAD:
set serveroutput on;
declare
words varchar2(400);
begin
words := KSL_ADMIN.java_testMessage;
dbms_output.put_line(words);
end;
However the result is that I'm getting:
java.lang.ClassNotFoundException: net/sourceforge/jtds/jdbc/Driver -ER1
08001 -ER2
PL/SQL procedure successfully completed.
I have the jar file within the class path, I can't think of any reason it shouldn't have the nessecary permissions to see the jar, and as far as I can tell I have everything spelled correctly.
Please help me figure out what I am doing wrong. Or if there is perhaps an easier way to go about connecting an Oracle DB to an MSSQL DB without really installing anything. Any knowledge on this is welcome as I am pretty new to a lot of this.
Oracle has its own internal java virtual machine and it does not use the system classpath. If you need external libraries you must “load” them into the internal JVM. You can do this using Oracle's loadjava tool.
See the Oracle's loadjava documentation (http://docs.oracle.com/cd/B28359_01/java.111/b31225/cheleven.htm#JJDEV10060)

Spring jdbc bug?

I'm using MySQL database and have written some procedures. If I try to create these procedures with spring jdbc I get error messages that these procedures already exist. If I connect the old fashion way with DriverManager create a PreparedStatement and execute it everything works just fine.
Does anyone know why this is happening?
here in code what I am doing
...
connection = new JdbcTemplate(dataSource);
...
for(String sql: sqlScript.split( "(;)" ) ){
connection.execute(sql.trim());
}
this results in SQL-Exception that the procedure I give as parameter already exists. But if I exchange the preceding code snippet against this:
for(final String sql: sqlScript.split( "(;/)" ) ) {
if (sql.trim().length() > 0)
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?"
+ "user=root" );
PreparedStatement ps =
conn.prepareCall(sql);
ps.execute();
} catch (SQLException e) {
e.printStackTrace();
}
}
everything works fine...
Would be nice if anyone knows whats wrong here...
at least one of my procedures that already exists... probably even in your database...
create procedure insertUser(
in p_firstname varchar(50),
in p_lastname varchar(50),
in p_username varchar(25)
)
begin
declare l_username varchar(25);
select username into l_username
from movielist.user where username = p_username;
if l_username is null then
insert into movielist.User (firstname, lastname, username) values
(p_firstname, p_lastname, p_username);
end if;
end;/

statement.executeUpdate() always returns 1

I have a problem with the JDBC executeUpdate() method. It always returns 1 whether it updates a row or not. As far as I understand the method it should return 0 is no rows are altered.
Here is a sample of my code:
try {
conn = pool.getConnection();
PreparedStatement ps = conn.prepareStatement("{CALL UPDATE_USER (?,?,?)}");
ps.setString(1, field.toString());
ps.setString(2, change);
ps.setString(3, userID);
int updated = ps.executeUpdate();
System.out.println(updated);
if(updated==0){
throw new NoUserException();
}
ps.close();
} catch (SQLException e) {
log.error("An error occurred while creating the connection");
e.printStackTrace();
} finally {
pool.returnConnection(conn);
}
Could this be because I'm using a prepared statement or a stored procedure?
Here is the stored procedure:
create or replace
PROCEDURE UPDATE_USER
(
updateColumn IN user_tab_columns.column_name%type,
changeStr IN VARCHAR2,
unID IN VARCHAR2
)
IS
BEGIN
EXECUTE IMMEDIATE
'UPDATE
users
SET ' || updateColumn || '= :1
WHERE
uniqueID = :2'
USING changeStr, unID;
END;
It can't get info from stored proc execution. If you want to get row count (or anything else) switch PROCEDURE to FUNCTION, add return clause in this function, and change your call to something like ? = CALL ... Test with sql%rowcount inside function to get impacted row count.
You can use Callable statement a procedure or function. And return the no of rows affected as a return parameter

Categories

Resources