Multiple stored procedures with input and output parameters called from java - java

I want to add a new row in a table - NewOrder which has the columns ID, OrderDate, OrderValue using the following stored procedure.
create proc [dbo].[insert_new_order]( #newID int OUTPUT,
#oValue float)
as
begin
insert into NewOrder values (GETDATE(),#oValue)
set #newID = ##IDENTITY
end
The #newID represents one of the input parameters for the following stored procedure which inserts a new row in the table OrderedProduct which has the columns ProductID, OrderID, Price, Quantity
create proc [dbo].[insert_updates_in_ordered_product] ( #newID int,
#productID int,
#price float,
#qty int)
as
begin
insert into OrderedProduct values(#productID,#newID,#qty,#price)
end
I am calling these 2 stored procedures like this:
public static void addNewOrderToDB(ArrayList<Product> list){
Connection connection = null;
CallableStatement statement1 = null;
String q1 = "{? = CALL insert_new_order(?)}";
String q2 = "{CALL insert_updates_in_ordered_product(?,?,?,?)}";
float orderValue = 0;
//calculate orderValue
for(Product p : list){
orderValue = orderValue + (p.getPrice() * p.getQty());
}
System.out.println(orderValue);
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
connection = DriverManager.getConnection(url);
statement1 = connection.prepareCall(q1);
statement1.registerOutParameter(1, Types.INTEGER);
statement1.setFloat(2, orderValue);
ResultSet rs = statement1.executeQuery();
int uniqueID = rs.getInt(1);
System.out.println(uniqueID);
statement1 = connection.prepareCall(q2);
for(Product p : list){
statement1.setInt(1, p.getProductId());
statement1.setInt(2,uniqueID);
statement1.setInt(3, p.getQty());
statement1.setFloat(4, p.getPrice());
}
statement1.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally{
if(statement1 != null){
try {
statement1.close();
} catch (SQLException e) {
System.err.println("SQLException: " + e.getMessage());
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
System.err.println("SQLException: " + e.getMessage());
}
}
}
}
But i get this error:
com.microsoft.sqlserver.jdbc.SQLServerException: Procedure or function 'insert_new_order' expects parameter '#oValue', which was not supplied.
How can i fix this?

Does it work if you change like this?
String q1 = "{CALL insert_new_order(?, ?)}";
That matches your create proc better.

Related

java calling procedure of package no response

I have created an API module of spring boot application to call stored procedure. When it comes to the implementation, stmt.execute cannot be called with no response. Would you please tell me which module or wayout to modify under my java environment is 1.8?
int retVal = -1;
int errCode = -1;
String errText = null;
int outPos;
int pos = 0;
System.out.println("call 2");
String SQL_SELECT = "{call database_sid.test_pkg.get_pc_lue(?,?,?,?,?,?)}";
try (Connection conn = DriverManager.getConnection(DBC_URL, USERNAME, PASSWORD);
CallableStatement preparedStatement = conn.prepareCall(SQL_SELECT);
) {
System.out.println("call db");
preparedStatement.setString(++pos, "OFFER_TYPE");
preparedStatement.setString(++pos, null); // acct srv limit
preparedStatement.registerOutParameter(outPos = ++pos, Types.REF_CURSOR);
preparedStatement.registerOutParameter(++pos, Types.INTEGER);
preparedStatement.registerOutParameter(++pos, Types.INTEGER);
preparedStatement.registerOutParameter(++pos, Types.VARCHAR);
System.out.println("call 10");
ResultSet resultSet = preparedStatement.executeQuery();
System.out.println("call 11");
while (resultSet.next()) {
String value = resultSet.getString("LOOKUP_VALUE");
String type = resultSet.getString("LOOKUP_TYPE");
PcTblBPcLookUp obj = new PcTblBPcLookUp();
obj.setLookUpValue(value);
obj.setLookUpType(type);
result.add(obj);
System.out.println("call 1obecj1");
}
result.forEach(x -> System.out.println(x));
System.out.println("call finish ");
} catch (SQLException e) {
System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());
} catch (Exception e) {
e.printStackTrace();
System.out.println("call error : " + e.getMessage());
}
You need to execute your stored procedure using execute and then you need to fetch your resultset from opsition registered for out parameter
preparedStatement.execute();
ResultSet rs = (ResultSet) preparedStatement.getObject(outPos);

How to get a String from h2 database (Java, DBUtil)

This is the code from DBUtil
public class DBUtil {
static Connection conn = null;
public static Connection getConnected() {
try {
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test", "sa", "");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}//end method
}//end DBUtil
and here is the code from the method I'm trying to use:
private class SearchForEdit implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e) {
String clientNumber = tfieldMiniSearchNumber.getText();
int number;
conn = DBUtil.getConnected();
if(conn == null) return;
String names=null, address=null;
String sql ="select names from clients where client_number = ?;";
String sql2 ="select address from clients where client_number = ?;";
try {
state = conn.prepareStatement(sql);
state.setInt(1, number);
state.execute();
state = conn.prepareStatement(sql2);
state.setInt(1, number);
state.execute();
labelWarning.setForeground(new Color(22, 205, 5));
labelWarning.setText("<html>TEXT SUCCESS</html>");
//names = select names from clients where client_number = number;
//address = select address from clients where client_number = number;
//if(names!=null && address!=null)
//tfieldEditClientNumber to be number
tfieldEditClientNumber.setText(""+number);
//tfieldEditNames to be names, where names = select names from clients where client_number = number;
//tfieldEditAddressда to be address, where address = select address from clients where client_number = number;
} catch (SQLException e1) {
labelWarning.setForeground(Color.RED);
labelWarning.setText("<html>Try again later</html>");
e1.printStackTrace();
}
}
}//end
I want to take the value of column NAME from the database and then put in in the string name. Then the same for address. I know only how to execute statements. Any help is very apreciated!
You need to store the results of the query in a ResultSet, and then iterate over that ResultSet. You can assign the values from the ResultSet into variables as you iterate over them.
Below code is an example of iterating over a ResultSet, as mentioned in my comment below.
while (rs.next()) {
// ResultSet columns: 1 = UserName 2 = FirstName 3 = LastName 4 = Organization
userInfo[0] = rs.getString(1); // assign UserName result to variable
userInfo[1] = rs.getString(2); // assign First_Name result to variable
userInfo[2] = rs.getString(3); // assign Last_Name result to variable
userInfo[3] = rs.getString(4); // assign Organization result to variable
}
The while loop will end when there are no ResultSet rows left to iterate over.

APOSTROPHE issue with java and SQL

I have code, where I have single quote or APOSTROPHE in my search
I have database which is having test table and in name column of value is "my'test"
When running
SELECT * from test WHERE name = 'my''test';
this works fine
If I use the same in a Java program I am not getting any error or any result
But If I give the name with only single quote then it works
SELECT * from test WHERE name = 'my'test';
Could you please help me out to understand.
Java code is
Connection con = null;
PreparedStatement prSt = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.
getConnection("jdbc:oracle:thin:#localhost:1521:orcl"
,"user","pwd");
String query = "SELECT * from "
+ "WHERE name = ? ";
prSt = con.prepareStatement(query);
String value = "my'mobile";
char content[] = new char[value.length()];
value.getChars(0, value.length(), content, 0);
StringBuffer result = new StringBuffer(content.length + 50);
for (int i = 0; i < content.length; i++) {
if (content[i] == '\'')
{
result.append("\'");
result.append("\'");
}
else
{
result.append(content[i]);
}
}
prSt.setObject(1, result.toString());
int count = prSt.executeUpdate();
System.out.println("===============> "+count);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally{
try{
if(prSt != null) prSt.close();
if(con != null) con.close();
} catch(Exception ex){}
}
You don't have to escape anything for the parameter of a PreparedStatement
Just use:
prSt = con.prepareStatement(query);
prSt.setString("my'mobile");
Additionally: if you are using a SELECT statement to retrieve data, you need to use executeQuery() not executeUpdate()
ResultSet rs = prst.executeQuery();
while (rs.next())
{
// process the result here
}
You might want to go through the JDBC tutorial before you continue with your project: http://docs.oracle.com/javase/tutorial/jdbc/index.html

How to get all data with column name in mysql databases

I create this code for get column name in sql databases. But now I ant to modify above code for get all table data with column name. Then get all data and convert to jsonarray and pass. How I modify this code for get all table data with column name.
#Override
public JSONArray getarray(String sheetName) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");
con.setAutoCommit(false);
PreparedStatement pstm = null;
Statement stmt = null;
//-----------------------Drop earliye table -------------------------------------------------------------
try {
String sqldrop = "select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME='" + sheetName.replaceAll(" ", "_") + "'";
System.out.println(sqldrop);
PreparedStatement mypstmt = con.prepareStatement(sqldrop);
ResultSet resultSet = mypstmt.executeQuery();
JSONArray jsonArray = new JSONArray();
while (resultSet.next()) {
int total_rows = resultSet.getMetaData().getColumnCount();
JSONObject obj = new JSONObject();
for (int i = 0; i < total_rows; i++) {
String columnName = resultSet.getMetaData().getColumnLabel(i + 1).toLowerCase();
Object columnValue = resultSet.getObject(i + 1).toString().replaceAll("_", " ");
// if value in DB is null, then we set it to default value
if (columnValue == null) {
columnValue = "null";
}
/*
Next if block is a hack. In case when in db we have values like price and price1 there's a bug in jdbc -
both this names are getting stored as price in ResulSet. Therefore when we store second column value,
we overwrite original value of price. To avoid that, i simply add 1 to be consistent with DB.
*/
if (obj.has(columnName)) {
columnName += "1";
}
obj.put(columnName, columnValue);
}
jsonArray.put(obj);
}
mypstmt.close();
con.commit();
return jsonArray;
} catch (Exception e) {
System.out.println("There is no exist earlyer databases table!..... :( :( :( **************** " + sheetName.replaceAll(" ", "_"));
}
//----------------------------------------------------------------------------
} catch (ClassNotFoundException e) {
System.out.println(e);
} catch (SQLException ex) {
Logger.getLogger(PassArrayDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("%%%%%%%%%%");
return null;
}
My target is get all data with column name and above data pass html page as a json. So if you have any method for get all data with column name is suitable for me.
// code starts here
// This method retrieves all data from a mysql table...
public void retrieveAllData( String host, String user, String pass, String query) {
JTextArea textArea = new JTextArea();
try(
Connection connection = DriverManager.getConnection( host, user, pass )
Statement statement = connection.createStatement()
ResultSet resultSet = statement.executeQuery(query)) {
ResultSetMetaData metaData = resultSet.getMetaData();
int totalColumns = metaData.getColumnCount();
for( int i = 1; i <= totalColumns; i++ ) {
textArea.append( String.format( "%-8s\t", metaData.getColumnName(i) ) );
}
textArea.append( "\n" );
while( resultSet.next() ) {
for( int i = 1; i <= totalColumns; i++ ) {
Object object = resultSet.getObject(i).toString();
textArea.append( String.format("%-8s\t", object) );
}
textArea.append( "\n" );
}
}
}

Getting empty resultSet for simple query

gurus,
I am new to Java SQL, and need some help.
I'm trying to get a parameter from MS SQL Server 2008. The data is definitely there - it is a current and valid DB, and I'm trying to use the users records to get cridentials for another application.
I asserted the following query:
String query = "SELECT [USER].qc_number FROM [USER] WHERE "[USER].login_name = '"
+ userNameInput + "' AND [USER].password = '" + passWordInput + "';";
Where userNameInput and passWordInput are received from the user. The URL, query and driver class are definitely correct: I checked the DB schema both from the application and from the server views. Furthermore, I verified all the Exceptions systems by changing parameters one by one, resulting in correct Exceptions messages. However, I get a resultSet with 1 column and 0 rows.
The code is below:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class trOdbc
{// database URL
final String DB_URL = "***";
final String Class_URL = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private Connection connection = null; // manages connection
private Statement statement = null; // query statement
private ResultSet resultSet = null; // manages results
private Boolean connectedToDatabase = false;
// ----------------------------------------------------------
public void createJdbcConnection()
{ // connect to database books and query database
if (connectedToDatabase)
{ return; }
try
{ // connectedToDatabase is false - establish the connection
Class.forName(Class_URL);
connection = DriverManager.getConnection
(DB_URL, "***", "***" );
statement = connection.createStatement
(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
connectedToDatabase = true;
}
catch (SQLException ex)
{ System.out.println ("SQL Exception in connection establishment: " + ex); }
catch (ClassNotFoundException ex)
{ System.out.println ("Class not found exception in query process: " + ex); }
}
// ----------------------------------------------------------
public String [][] processJdbcQuery (String query)
{
createJdbcConnection ();
if (!connectedToDatabase)
{ return null; }// the connection wasn't established
try
{// query database
resultSet = statement.executeQuery(query);
int columns = resultSet.getMetaData().getColumnCount();
int rows = 0;
if (resultSet != null)
{
resultSet.beforeFirst();
resultSet.last();
rows = resultSet.getRow();
}
String [][] tempData = new String[rows][columns];
resultSet.beforeFirst();
rows = 0;
while (resultSet.next())
{
for (int x = 1; x <= columns; x++)
{
tempData [rows][x - 1] = resultSet.getString (x);
}
rows++;
}
CloseJdbcConnection ();
return tempData;
}
catch (SQLException ex)
{
System.out.println ("SQL Exception in query process: " + ex);
CloseJdbcConnection ();
return null;
}
} // end processJdbcQuery
// ----------------------------------------------------------
public void CloseJdbcConnection()
{
if ( connectedToDatabase )
{// close Statement and Connection. resultSet is closed automatically.
try
{
statement.close();
connection.close();
connectedToDatabase = false;
}
catch (SQLException ex)
{ System.out.println ("SQL Exception in connection closure: " + ex); }
} // end if
} // end method CloseJdbcConnection
} // end class trOdbc
Why don't you use Prepared Statement instead ?
Here is a good tutorial for using prepared statement in java
In your case it would be :
String query = "SELECT [USER].qc_number FROM [USER] " +
"WHERE [USER].login_name = ? AND [USER].password = ?;";
And then set it with different values each time you execute it like :
PreparedStatement ps = connection.prepareStatement(query);
ps.setString(1, userNameInput);
ps.setString(2, passWordInput);
resultSet = ps.executeQuery();

Categories