Lets say I have a table called "person" and it has 4 columns (name, last_name, city, pincode). Two of those columns (name, last_name) are unique columns. I want to get these two columns from the JDBC driver. How can I get this information from a JDBC driver?
You can find information about unique columns (defined as constraints or unique indexes), using DatabaseMetaData.getIndexInfo, passing true for the fourth parameter (unique).
For example
DatabaseMetaData md = connection.getMetaData();
// NOTE: You may need to use "PERSON"
try (ResultSet rs = md.getIndexInfo(null, null, "person", true, true)) {
while (rs.next()) {
String indexName = rs.getString("INDEX_NAME");
String columnName = rs.getString("COLUMN_NAME");
if (indexName == null || columnName == null) {
continue;
}
System.out.printf("%s: %s%n", indexName, columnName);
}
}
Here you have a simple example based on MySql:
public class Test {
static final String DB_URL = "jdbc:mysql://localhost:3306/yourDatabase";
static final String USER = "----";
static final String PASS = "somePass";
static final String QUERY = "SHOW KEYS FROM YOUR_TABLE WHERE Key_name = 'PRIMARY'\n";
public static void main(String[] args) {
// Open a connection
final ArrayList<String> primaryKeyColumns = new ArrayList<>();
try(Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(QUERY);) {
while (rs.next()) {
primaryKeyColumns.add(rs.getString(5));
}
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println(primaryKeyColumns);
}
}
Look at the used query in this way you can fetch more specific information.
Related
Two tables are present in the database, one is Student table with columns roll_no(PK), name, grade and DOB, another table StudentLeft with columns roll_no, name, grade and leaving_date.
I want to delete the record of the student from Student table whose roll no is entered by the user, and add the roll no, name, grade and leaving_date (the date when the record is deleted and added to the table) to StudentLeft table.
This is my method.
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null, preparedStatement1 = null, preparedStatement2 = null;
ResultSet resultSet = null;
String selectQuery = "", updateQuery = "", deleteQuery = "";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
connection = dataSource.getConnection();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
int rollNo = Integer.parseInt(args[0]);
try {
selectQuery = "SELECT name, grade FROM Student WHERE roll_no = ?";
updateQuery = "INSERT INTO StudentLog values WHERE roll_no = ?, name = ?, standard = ?";
deleteQuery = "DELETE Student WHERE roll_no = ?";
connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement(selectQuery);
preparedStatement.setInt(1, rollNo);
resultSet = preparedStatement.executeQuery();
preparedStatement1 = connection.prepareStatement(updateQuery);
preparedStatement1.setInt(1, rollNo);
while (resultSet.next()) {
String name = resultSet.getString("name");
String grade = resultSet.getString("grade");
preparedStatement1.setString(2, name);
preparedStatement1.setString(3, grade);
preparedStatement1.addBatch();
}
preparedStatement1.executeBatch();
preparedStatement2 = connection.prepareStatement(deleteQuery);
preparedStatement.setInt(1, rollNo);
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
}
try {
if (!preparedStatement.isClosed() || !preparedStatement1.isClosed() || !preparedStatement2.isClosed()) {
preparedStatement.close();
preparedStatement1.close();
preparedStatement2.close();
}
if (!connection.isClosed())
connection.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
These are the errors.
java.sql.BatchUpdateException: ORA-00936: missing expression
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10500)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230)
at Q3.main(Q3.java:48)
Exception in thread "main" java.lang.NullPointerException
at Q3.main(Q3.java:62)
I am using oracle 11g express database.
The code you've written can be simplified quite a bit:
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
int rollNo = Integer.parseInt(args[0]);
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
String transferStatement = "INSERT INTO StudentLog (roll_no, name, standard, leaving_date) " +
"SELECT roll_no, name, standard, SYSDATE FROM Student WHERE roll_no = ?";
try (PreparedStatement stmt = connection.prepareStatement(transferStatement)) {
stmt.setInt(1, rollNo);
stmt.executeUpdate();
}
String deleteStatement = "DELETE FROM Student WHERE roll_no = ?";
try (PreparedStatement stmt = connection.prepareStatement(deleteStatement)) {
stmt.setInt(1, rollNo);
stmt.executeUpdate();
}
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
}
}
I've used try-with-resources statements, which simplifies the clean-up of connections and prepared statements: the connection and statements will get closed when the code inside the try (...) block finishes executing.
Transferring data from the Student table to the StudentLog table can be done in one go with an INSERT INTO ... SELECT statement. This statement doesn't return any result set: there's nothing to iterate through, we just execute it and the row gets inserted.
The DELETE statement is similar: it too returns no result set. I've added the keyword FROM to it out of convention more than anything else: as pointed out on another answer, FROM is optional.
I've also moved the catch (SQLException e) block to the end: that will handle all SQLExceptions generated when connecting to the database or executing either of the prepared statements.
I've kept the code that attempts to load the Oracle database driver class, but added a return statement in the catch block: if there's an exception, the driver isn't on the classpath and connecting to the database is guaranteed to fail so we may as well stop. However, for recent versions of the Oracle driver you don't need this check. Experiment with it: see if the code works without this check and if so, remove it.
Shouldn't your query be
DELETE FROM Student WHERE roll_no = ?
instead of
DELETE Student WHERE roll_no = ?
Your DELETE code used the wrong prepared statement, missing an execute.
It is advisable to use try-with-resources as below, for the automatic closing,
even on return or exception. (It also takes care of variable scopes.)
public static void main(String[] args) throws SQLException {
int rollNo = Integer.parseInt(args[0]);
// Better statements possible.
final String selectQuery = "SELECT name, grade FROM Student WHERE roll_no = ?";
final String updateQuery =
"INSERT INTO StudentLog VALUES WHERE roll_no = ?, name = ?, standard = ?";
final String deleteQuery = "DELETE FROM Student WHERE roll_no = ?";
try { // Check whether you need this. It is for the old discovery mechanism.
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
throw new IllegalStateException("Database driver not provided", e);
}
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
try (PreparedStatement preparedStatement =
connection.prepareStatement(selectQuery)) {
preparedStatement.setInt(1, rollNo);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
try (PreparedStatement preparedStatement1 =
connection.prepareStatement(updateQuery)) {
preparedStatement1.setInt(1, rollNo);
while (resultSet.next()) {
String name = resultSet.getString("name");
String grade = resultSet.getString("grade");
preparedStatement1.setString(2, name);
preparedStatement1.setString(3, grade);
preparedStatement1.addBatch();
}
preparedStatement1.executeBatch();
}
}
}
try (PreparedStatement preparedStatement2 =
connection.prepareStatement(deleteQuery)) {
preparedStatement2.setInt(1, rollNo); // NOT preparedStatement
preparedStatement2.executeUpdate();
}
connection.commit();
}
}
Then one should SELECT+INSERT to the database, using one statement (INSERT SELECT).
The SQL of the StudentLog is a bit incomprehensible to me, but a nice INSERT would be:
INSERT INTO StudentLog VALUES(roll_no, name, standard)
SELECT roll_no, name, grade
FROM Student
WHERE roll_no = ?
Removing the need java nesting of database accesses.
I have a database called 'airplane' inside which there is a table named booking.
The booking table has the columns phone(int type) ,name(text type),address(text type),city(text type) destination(text type),date(text type). I want to fetch only the rows whose phone column has value or data equal to phone number entered by the user . I wrote the following code for it . For context , I am using java using JDBC
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/airplane";
static final String USER = "root";
static final String PASS = "";
Connection conn = null;
try
{
System.out.println("enter cell no");
int cell=sc.nextInt();
conn = DriverManager.getConnection(DB_URL, USER, PASS);
System.out.println("Connected database successfully...");
// My SQL SELECT query.
String query = "SELECT * FROM `booking` where phone=cell";
// creating the java statement
Statement st = conn.createStatement();
/** executing the query, and getting a java resultset of all rows whose phone
column has the value equal to one entered by user and stored by me in
int variable cell**/
ResultSet rs = st.executeQuery(query);
//iterate through the java resultset
while (rs.next())
{
int Phone = rs.getInt("phone");
String Name = rs.getString("name");
String Address = rs.getString("address");
String City = rs.getString("city");
String Destination = rs.getString("destination");
String Date = rs.getString("date");
// print the results
System.out.format("%d, %s, %s, %s, %s, %s\n", Phone, Name, Address, City, Destination, Date);
}
st.close();
}
catch (Exception e)
{
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
I am getting the error:
Got an exception!
Unknown column 'cell' in 'where clause'
What am I doing wrong?
Try this:
String query = "SELECT * FROM `booking` where phone=" + cell;
A better way to handle this is to use PreparedStatement
This case, the query would look like:
String query = "SELECT * FROM `booking` where phone=?"
and
statement.setInt(1, cell);
you will see it's gonna run
String query = "SELECT * FROM booking where phone="+"\"%s\"";
query=String.format(query,cell);
I would like to check the database for duplicates before inserting into the database. It is only considered a duplicate when plateNo, driverID and resDate match.
Here is how I get the data that will be inserted to the database
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String client = (String) clientCmb.getSelectedItem();
String[] cparts = client.split("-");
String cpart = cparts[0];
String driver = (String) driverCmb.getSelectedItem();
String[] dparts = driver.split("-");
String dpart = dparts[0];
String van = (String) vanCmb.getSelectedItem();
java.util.Date oDate = jXDatePicker2.getDate();
DateFormat oDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String date = oDateFormat.format(oDate);
model2.addRow(cpart, dpart, van, date);
}
And here's the code for my addRow method
public void addRow(String client, String driver, String van, String res){
try {
String sqlRes = "Select * from reservation";
rs = st.executeQuery(sqlRes);
rs.moveToInsertRow();
rs.updateString("clientID", client);
rs.updateString("plateNo", van);
rs.updateString("driverID", driver);
rs.updateString("resDate", res);
rs.insertRow();
rs.moveToCurrentRow();
rs = st.executeQuery(sqlRes);
this.fireTableDataChanged();
} catch (SQLException ex) {
Logger.getLogger(MyModel2.class.getName()).log(Level.SEVERE, null, ex);
}
Let the database do the work for you. Define a unique index/constraint specifying that those three values are unique in the table:
create unique index unq_reservation_3 on reservation(plateNo, driverID, resDate);
If you attempt to insert a duplicate -- or do an update that results in a duplicate -- then the database will return an error. You simply need to catch the error.
Use MERGE statement: T-SQL or ORACLE, or for MySQL:
PreparedStatement p = con.prepareStatement("
INSERT INTO reservation tgt (clientID, plateNo, driverID, resDate)
SELECT (? As clientID, ? As plateNo, ? As driverID, ? As resDate)
FROM DUAL ins
LEFT JOIN reservation ref
ON ref.resDate = ins.resDate
AND (ref.plateNo = ins.plateNo OR ref.driverID = ins.driverID)
WHERE ref.clientID IS NULL;
");
p.setString(1, client);
p.setString(2, van);
p.setString(3, driver);
p.setString(4, res);
return p.executeUpdate(); /* 1 - Success | 0 - Ignored Duplicate */
I've connected to a MySQL database, which contains four fields (the first of which being an ID, the latter ones each containing varchar strings).
I am trying to get the last row of the database and retrieve the contents of the fields so that I can set them to variables (an int and three strings) and use them later.
So far, I have the bare minimum to make the connection, where do I go from here? As you can see I have tried to write a SQL statement to get the last row but it's all gone wrong from there and I don't know how to split it into the separate fields.
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/t", "", "");
Statement st = con.createStatement();
String sql = ("SELECT * FROM posts ORDER BY id DESC LIMIT 1;");
st.getResultSet().getRow();
con.close();
Here you go :
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/t", "", "");
Statement st = con.createStatement();
String sql = ("SELECT * FROM posts ORDER BY id DESC LIMIT 1;");
ResultSet rs = st.executeQuery(sql);
if(rs.next()) {
int id = rs.getInt("first_column_name");
String str1 = rs.getString("second_column_name");
}
con.close();
In rs.getInt or rs.getString you can pass column_id starting from 1, but i prefer to pass column_name as its more informative as you don't have to look at database table for which index is what column.
UPDATE : rs.next
boolean next()
throws SQLException
Moves the cursor froward one row from its current position. 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.
When a call to the next method returns false, the cursor is positioned
after the last row. Any invocation of a ResultSet method which
requires a current row will result in a SQLException being thrown. If
the result set type is TYPE_FORWARD_ONLY, it is vendor specified
whether their JDBC driver implementation will return false or throw an
SQLException on a subsequent call to next.
If an input stream is open for the current row, a call to the method
next will implicitly close it. A ResultSet object's warning chain is
cleared when a new row is read.
Returns:
true if the new current row is valid; false if there are no more rows Throws:
SQLException - if a database access error occurs or this method is called on a closed result set
reference
Something like this would do:
public static void main(String[] args) {
Connection con = null;
Statement st = null;
ResultSet rs = null;
String url = "jdbc:mysql://localhost/t";
String user = "";
String password = "";
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(url, user, password);
st = con.createStatement();
rs = st.executeQuery("SELECT * FROM posts ORDER BY id DESC LIMIT 1;");
if (rs.next()) {//get first result
System.out.println(rs.getString(1));//coloumn 1
}
} catch (SQLException ex) {
Logger lgr = Logger.getLogger(Version.class.getName());
lgr.log(Level.SEVERE, ex.getMessage(), ex);
} finally {
try {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
Logger lgr = Logger.getLogger(Version.class.getName());
lgr.log(Level.WARNING, ex.getMessage(), ex);
}
}
}
you can iterate over the results with a while like this:
while(rs.next())
{
System.out.println(rs.getString("Colomn_Name"));//or getString(1) for coloumn 1 etc
}
There are many other great tutorial out there like these to list a few:
http://www.vogella.com/articles/MySQLJava/article.html
http://www.java-samples.com/showtutorial.php?tutorialid=9
As for your use of Class.forName("com.mysql.jdbc.Driver").newInstance(); see JDBC connection- Class.forName vs Class.forName().newInstance? which shows how you can just use Class.forName("com.mysql.jdbc.Driver") as its not necessary to initiate it yourself
References:
http://zetcode.com/databases/mysqljavatutorial/
This should work, I think...
ResultSet results = st.executeQuery(sql);
if(results.next()) { //there is a row
int id = results.getInt(1); //ID if its 1st column
String str1 = results.getString(2);
...
}
Easy Java method to get data from MySQL table:
/*
* CREDIT : WWW.CODENIRVANA.IN
*/
String Data(String query){
String get=null;
try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = (Connection)DriverManager.getConnection
("jdbc:mysql://localhost:3306/mysql","root","password");
Statement stmt = (Statement) con.createStatement();
ResultSet rs=stmt.executeQuery(query);
if (rs.next())
{
get = rs.getString("");
}
}
catch(Exception e){
JOptionPane.showMessageDialog (this, e.getMessage());
}
return get;
}
Here is what I just did right now:
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.javafx.runtime.VersionInfo;
public class ConnectToMySql {
public static ConnectBean dataBean = new ConnectBean();
public static void main(String args[]) {
getData();
}
public static void getData () {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mynewpage",
"root", "root");
// here mynewpage is database name, root is username and password
Statement stmt = con.createStatement();
System.out.println("stmt " + stmt);
ResultSet rs = stmt.executeQuery("select * from carsData");
System.out.println("rs " + rs);
int count = 1;
while (rs.next()) {
String vehicleType = rs.getString("VHCL_TYPE");
System.out.println(count +": " + vehicleType);
count++;
}
con.close();
} catch (Exception e) {
Logger lgr = Logger.getLogger(VersionInfo.class.getName());
lgr.log(Level.SEVERE, e.getMessage(), e);
System.out.println(e.getMessage());
}
}
}
The Above code will get you the first column of the table you have.
This is the table which you might need to create in your MySQL database
CREATE TABLE
carsData
(
VHCL_TYPE CHARACTER(10) NOT NULL,
);
First, Download MySQL connector jar file, This is the latest jar file as of today [mysql-connector-java-8.0.21].
Add the Jar file to your workspace [build path].
Then Create a new Connection object from the DriverManager class, so you could use this Connection object to execute queries.
Define the database name, userName, and Password for your connection.
Use the resultSet to get the data based one the column name from your database table.
Sample code is here:
public class JdbcMySQLExample{
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/YOUR_DB_NAME?useSSL=false";
String user = "root";
String password = "root";
String query = "SELECT * from YOUR_TABLE_NAME";
try (Connection con = DriverManager.getConnection(url, user, password);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(query)) {
if (rs.next()) {
System.out.println(rs.getString(1));
}
} catch (SQLException ex) {
System.out.println(ex);
}
}
i try to understand this part of code:
Properties details= new Properties();
details.load(new FileInputStream("details.properties"));
String userName = details.getProperty("root");
String password = details.getProperty("mysqlpassword");
String url = "jdbc:mysql://localhost/test";
Class.forName ("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection (url, userName, password);
System.out.println ("Database connection established");
PreparedStatement st = conn.prepareStatement("insert into 'Email_list' values(?)");
for(String mail:mails)
i understand that test database is a default database. but if i want to use an existing database, i will just modify test to another database name isn't it?
If yes how do i modify my code if my new database is Test2 with table name Email which contains mail column with varchar(100)
i try to replace test by Test2 Email_list by Email but i don't know where to put the column name mail.
Thank you for help
The INSERT statement you use omits the columns.
INSERT INTO tablename VALUES (1, 2, 3)
can be written if the table has three columns and for all three columns values are provided.
If some columns can be left empty or have default values, you can write
INSERT INTO tablename (column1, column2) VALUES (1, 2)
In this cas the value for column3 is null or the default value.
So in your case the column name is put nowhere.
You are missing PORT number in your connection string...
String url = "jdbc:mysql://localhost/test"; should be String url = "jdbc:mysql://localhost:PORT_NUMBER/test"; like String url = "jdbc:mysql://localhost:3306/test";
Let me know if you have any queries...
Also, Check below how Prepared Statement works
import java.sql.*;
public class TwicePreparedStatement{
public static void main(String[] args) {
System.out.println("Twice use prepared statement example!\n");
Connection con = null;
PreparedStatement prest;
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql:
//localhost:3306/jdbctutorial","root","root");
try{
String sql = "SELECT * FROM movies WHERE year_made = ?";
prest = con.prepareStatement(sql);
prest.setInt(1,2002);
ResultSet rs1 = prest.executeQuery();
System.out.println("List of movies that made in year 2002");
while (rs1.next()){
String mov_name = rs1.getString(1);
int mad_year = rs1.getInt(2);
System.out.println(mov_name + "\t- " + mad_year);
}
prest.setInt(1,2003);
ResultSet rs2 = prest.executeQuery();
System.out.println("List of movies that made in year 2003");
while (rs2.next()){
String mov_name = rs2.getString(1);
int mad_year = rs2.getInt(2);
System.out.println(mov_name + "\t- " + mad_year);
}
}
catch (SQLException s){
System.out.println("SQL statement is not executed!");
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
Good Luck!!!