How to fetch mysql cursore value from stored procedure - java

How to fetch mysql cursor values in java program.
This is my mysql stored procedure
delimiter //
CREATE PROCEDURE cursor_student()
BEGIN
DECLARE row_count INT DEFAULT 0;
DECLARE exit_flag INT DEFAULT 0;
DECLARE sid varchar(30);
DECLARE sname varchar(50);
DECLARE rst CURSOR FOR
SELECT sid, sname FROM student WHERE class = '11th';
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET exit_flag=1;
OPEN rst;
fetch_loop: LOOP
FETCH rst INTO sid, sname;
IF exit_flag THEN
LEAVE fetch_loop;
END IF;
SET row_count = row_count +1;
END LOOP;
CLOSE rst;
SELECT 'number of rows fetched =', row_count;
END;
this is my simlpe java program to read above stored procedure
import java.sql.CallableStatement;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class StoredProcedure {
public static void main(String[] args) {
Connection dbConnection = null;
String url = "jdbc:mysql://localhost:3306/";
String db = "test";
String driver = "com.mysql.jdbc.Driver";
ResultSet rs = null;
CallableStatement callableStatement = null;
String getDBUSERCursorSql = "{call cursor_student}";
try {
Class.forName(driver);
dbConnection = DriverManager.getConnection(url + db, "root", "");
try {
callableStatement = dbConnection.prepareCall(getDBUSERCursorSql);
callableStatement.executeUpdate();
rs = callableStatement.getResultSet();
while (rs.next()) {
System.out.println("sid "+rs.getString(1) +" name "+rs.getString(2));
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output of above java program is
sid number of rows fetched = name 6
but i want to display values of sid and sname
+------+-------+
| sid | sname |
+------+-------+
| 1 | asdf |
| 2 | dff |
| 3 | gggg |
| 4 | tttt |
| 5 | mmmm |
| 6 | .uyy |
+------+-------+

I think there is problem with your SP.
Could you please make the changes accourding to this SP Example? I haven't execute but I think so
DROP PROCEDURE IF EXISTS mysql_cursor_example $$
CREATE PROCEDURE mysql_cursor_example ( IN in_name VARCHAR(255) )
BEGIN
-- First we declare all the variables we will need
DECLARE l_name VARCHAR(255);
-- flag which will be set to true, when cursor reaches end of table
DECLARE exit_loop BOOLEAN;
-- Declare the sql for the cursor
DECLARE example_cursor CURSOR FOR
SELECT name status_update
FROM employees
WHERE name = name_in;
-- Let mysql set exit_loop to true, if there are no more rows to iterate
DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
-- open the cursor
OPEN example_cursor;
-- marks the beginning of the loop
example_loop: LOOP
-- read the name from next row into the variable l_name
FETCH example_cursor INTO l_name;
-- check if the exit_loop flag has been set by mysql,
-- if it has been set we close the cursor and exit
-- the loop
IF exit_loop THEN
CLOSE example_cursor;
LEAVE example_loop;
END IF;
END LOOP example_loop;
END $$
DELIMITER ;

Related

JDBC MySql driver returns wrong value after working for a long time

I have a MySQL db and I have an issue with two tables named product and product_older. They have same structure and product table's rows copied into product_older for once in a day. Here is their structure:
+-----------------------+---------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| price | decimal(18,2) | YES | | NULL | |
| price_older | decimal(18,2) | YES | | NULL | |
+-----------------------+---------------+------+-----+-------------------+----------------+
I have problem with only price_older field. My program updates values of product table for over 3 million data. price_older field takes it value from price column of product_older every time.
Here is the method which I take price_older:
private double getOlderPrice(int id) {
double price_older = 0.0d;
try {
String query = tools.getQuery("select price from product_older where id=?")
.replace("?", String.valueOf(id));
com.mysql.jdbc.Connection connection = (Connection) DriverManager.getConnection(db_url, username, password);
preparedStatement = (PreparedStatement) connection.prepareStatement(query);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
price_older = resultSet.getDouble(1);
}
} catch (SQLException e) {
..... // error log
} finally {
.... //close the prepared statement
}
return price_older;
}
And I use that price_older value to create PriceList object for every product then I used that list to update product table. Here is my update code:
(Same connection object used in here with the getOlderPrice method.)
private void dbUpdate() throws SQLException {
String query = "update product set price=?, price_older=? where id=?";
try (com.mysql.jdbc.Statement statement = (Statement) connection.createStatement();
com.mysql.jdbc.PreparedStatement updateStatement = (PreparedStatement) connection.prepareStatement(query)) {
connection.setAutoCommit(false);
int batchIndex = 0;
for (UpdatePrice price : priceList) {
if (price.getPrice() == null) {
updateStatement.setNull(1, Types.DECIMAL);
} else {
updateStatement.setDouble(1, price.getPrice());
}
updateStatement.setDouble(2, price.getOlderPrice());
updateStatement.setInt(3, price.getID());
updateStatement.addBatch();
batchIndex++;
if (batchIndex % limitedBatchSize == 0) {
updateStatement.executeBatch();
connection.commit();
}
}
updateStatement.executeBatch();
connection.commit();
connection.setAutoCommit(true);
priceList.clear();
}
}
Here is the problem; It works fine for most of the time but about once every ~30 days it updates older_price with the wrong value and that wrong value is usually belong to another product in the db and when it updates the column with the wrong value there is no error in the log because it appears OK.
And my connection's rewriteBatchedStatements is set to true.
How could that be? If there is a bug, why it works fine most of the time and how there is no problem with the price column? If there is not why it updates a value in the wrong place?
I have been searched for over a week now but there is no result and also I can not reproduce the bug and it makes less possible to be sure where is the problem actually.

How to use LAST_INSERT_ID() Equivalent of ##IDENTITY in MySql [duplicate]

This question already has answers here:
How to get the insert ID in JDBC?
(14 answers)
Closed 7 years ago.
In MySql, I want to use equivalent of SQL ##IDENTITY and I found this LAST_INSERT_ID(). I found in search that it work fines even if there are different sessions exist. I want to find last ID,in current session. I am using following code.
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = null;
conn = DriverManager.getConnection("jdbc:mysql://localhost/fuel","root", "");
System.out.print("Database is connected !\n");
Statement st = conn.createStatement();
String response = "<food>";
String insertQuery = "INSERT INTO transactions(user_input,fuel_response,execution_time)"+
"VALUES(?,?,?)";
PreparedStatement prepareStatementObj = conn.prepareStatement(insertQuery);
prepareStatementObj.setString(1, "I drank a babyfood juice apple.");
prepareStatementObj.setString(2, response);
prepareStatementObj.setInt(3, 4500);
prepareStatementObj.execute();
String queryForId = "SELECT LAST_INSERT_ID() FROM transactions";
ResultSet rs2 = st.executeQuery(queryForId);
if (!rs2.isBeforeFirst() ) {
System.out.println("No data");
} else {
while ( rs2.next() ) {
int id = rs2.getInt("id");
System.out.println("Last id of this session was..."+id);
}
}
conn.close();
} catch(Exception e) {
System.out.print("Do not connect to DB - Error:"+e);
}
}
Code is working for Insertion but I am not getting last inserted id. It gives following exception.
Column 'id' not found.
I will be thankful to you if you can help.
Modify your select to use alias as id:-
SELECT LAST_INSERT_ID() as id FROM transactions
You're trying to grab a column called id, but there's no such column. When you grab the last inserted ID, you get a column called last_insert_id() instead:
MySQL> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 0 |
+------------------+
1 row in set (0.02 sec)
Easier to grab it by index (use .getInt(int)). This is perfectly safe because you know there will only be one column returned.
You can use below code to get last insert id.
ResultSet rs = prepareStatementObj.getGeneratedKeys();
if(rs.next())
{
last_inserted_id=Integer.toString(rs.getInt(1));
}

MySQL create or alter table

I am using MySQL 5.1 for my database and I'm sending the commands via a Java program (JBDC).
Is there a MySQL command for creating or altering a table?
Let's say I have a following table:
+----------+----------+
| column_a | column_b |
+----------+----------+
| value_a | value_b |
+----------+----------+
Now I want to use a command, that would add a column "column_c" if it didn't exist.
That would result in:
+----------+----------+----------+
| column_a | column_b | column_c |
+----------+----------+----------+
| value_a | value_b | |
+----------+----------+----------+
If the table didn't exist, it would create a new table with specified columns:
+----------+----------+----------+
| column_a | column_b | column_c |
+----------+----------+----------+
And finally, if the table had columns that weren't specified in the command, it would leave them untouched.
here is code in Java to create a table called Coffees:
/*Making the connection*/
try {//if any statements within the try block cause problems, rather than the program failing
//an exception is thrown which will be caught in the catch block
con = DriverManager.getConnection(url, "your username", "your password");
//create a statement object
stmt = con.createStatement();
//supply the statement object with a string to execute
stmt.executeUpdate("create table COFFEES (COF_NAME varchar(32), " +
"SUP_ID int, PRICE double, SALES int, TOTAL int, " +
"primary key(COF_NAME))");
//close the statement and connection
stmt.close();
con.close();
} catch(SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
Explanation:
-In this example the java program interacts with a database that is located on a server, so we have to firstly we set the url of where the server is located and also sign in username and password, you may not be using the same method that I used.
-These need to be declared at the top of your java program:
String url = "jdbc:mysql://www.yoururlexample.co.uk";
Connection con;
Statement stmt
Hopefully this helps, you will then be able to insert data into the database and execute queries.
Edit:
This can be used in the executeUpdate statement if you want a table to be created if none exists with the name "COFFEES":
create table if not exists COFFEES
/*Making the connection*/
try {
//an exception is thrown which will be caught in the catch block
con = DriverManager.getConnection("jdbc:mysql:exaple.com", "username", "pass");
//create a statement object
stmt = con.createStatement();
//supply the statement object with a string to execute
stmt.executeUpdate("ALTER TABLE table_name ADD column_name datatype");
//close the statement and connection
stmt.close();
con.close();
} catch(SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
I think that this is going to work for you.
Something like that might be a solution (this need at least one record in the table to work):
package com.stackoverflow.so20935793;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class App {
// complete this:
private static final String JDBC_URL = ".....";
private static final String JDBC_USER = ".....";
private static final String JDBC_PASS = ".....";
public static void main(final String[] args) {
Connection con = null;
PreparedStatement stm = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASS);
stm = con.prepareStatement("SELECT * FROM your_table LIMIT 1");
rs = stm.executeQuery();
if (rs.next() && rs.getMetaData().getColumnCount() == 2) {
// add your new column
}
} catch (final SQLException ex) {
// handle exception
} finally {
closeQuietly(rs);
closeQuietly(stm);
closeQuietly(con);
}
}
private static void closeQuietly(final AutoCloseable what) {
if (what == null) {
return;
}
try {
what.close();
} catch (final Exception ex) {
// ignore
}
}
}
(not tested)

How to display or print the contents of a database table as is?

I want to fetch a table from a database using Java code. The sample code which I tried gets only two columns. I want the fetched data to be presented exactly like it is in the table.
How do I do that ?
This code only gives me two rows, side by side -
while (rs.next()) {
System.out.println(rs.getString(4) + " " + rs.getString(6));
}
Full example at -
http://msdn.microsoft.com/en-us/library/aa342339.aspx
This is what I tried -
int size = 0;
if(rs != null){
rs.beforeFirst();
rs.last();
size = rs.getRow();
}
System.out.println("cols = " + size);
And got an error - The requested operation is not supported on forward only result sets.
Use this code
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
Source - How to get the number of columns from a JDBC ResultSet?
After using that code, one can display the results like they are displayed by the DBMS as follows -
ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
// Iterate through the data in the result set and display it.
while (rs.next()) {
//Print one row
for(int i = 1 ; i <= columnsNumber; i++){
System.out.print(rs.getString(i) + " "); //Print one element of a row
}
System.out.println();//Move to the next line to print the next row.
}
Column names are not displayed in this example.
I posted this answer to a similar question here, but I believe this one is also relevant, maybe more so. In short, I wrote a simple utility class to print db table rows to standard out (for part fun, part learning). It may be useful to someone (at least I hope so).
Here is the link to the code repo at GitHub: https://github.com/htorun/dbtableprinter
And here is the basic usage:
// Create a connection to the database
Connection conn = DriverManager.getConnection(url, username, password);
// Just pass the connection and the table name to printTable()
DBTablePrinter.printTable(conn, "employees");
It should print something like this:
Printing 10 rows from table(s) EMPLOYEES
+--------+------------+------------+-----------+--------+-------------+
| EMP_NO | BIRTH_DATE | FIRST_NAME | LAST_NAME | GENDER | HIRE_DATE |
+--------+------------+------------+-----------+--------+-------------+
| 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 |
+--------+------------+------------+-----------+--------+-------------+
| 10002 | 1964-06-02 | Bezalel | Simmel | F | 1985-11-21 |
+--------+------------+------------+-----------+--------+-------------+
.
.
It's because your code only get 2 value of the row. Notice that rs.getString(4) meant, get the value on current row at 4th column (using 0 based index) as String.
If you want to print all the column, you should write the rest rs.getXXXX(), where XXXX is column data type such as getString(), getInteger(), getLong(), etc. See this java documentation for reference.
public static void printSqlTable(String selectQuery) {
try {
Statement statement = connection.createStatement();
resultSet = statement.executeQuery(selectQuery);
DBTablePrinter.printResultSet(resultSet);
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

How to connect to local host using JDBC?

I installed MySql on my own machine. I created database, create table, ... using MySql CommandLine Client. When working on a project in school, I connected to school's database using this syntax:
public static Statement connect() {
try {
Class.forName( "com.mysql.jdbc.Driver" ).newInstance();
conn = DriverManager.getConnection( "1", "2", "3" );
stmt = conn.createStatement();
}
catch( Exception e ) {
System.out.println( "Connection Error: " + e );
}
return stmt;
}
In my local machine, I don't have to type in user name, all I did is just login with my password as root user:
Enter password: ****
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.53-community MySQL Community Server (GPL)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use chandb;
Database changed
mysql> show tables;
+------------------+
| Tables_in_chandb |
+------------------+
| another |
| cars |
| employees |
+------------------+
3 rows in set (0.03 sec)
mysql> select * from Another;
+----+-----------+----------+
| Id | GoldValue | Model |
+----+-----------+----------+
| 0 | 100 | Civic DX |
+----+-----------+----------+
1 row in set (0.00 sec)
mysql>
I would like to know how can I connect to my local machine's database? what should I put as parameters within method .getConnection
conn = DriverManager.getConnection(
"1", // ?
"2", // ?
"3" ); // ?
Best regards,
Chan
Simple Connection:
import java.sql.Connection;
import java.sql.DriverManager;
public class Main {
public static void main(String[] argv) throws Exception {
String driverName = "org.gjt.mm.mysql.Driver";
Class.forName(driverName);
String serverName = "localhost";
String mydatabase = "mydatabase";
String url = "jdbc:mysql://" + serverName + "/" + mydatabase;
String username = "username";
String password = "password";
Connection connection = DriverManager.getConnection(url, username, password);
}
}
It looks like you left your username and password in the source you posted.
I don't see why you can't just do
DriverManager.getConnection("jdbc:mysql://localhost/chandb", "user, "pass");

Categories

Resources